Commit 6e056be1 by aagusti

Merge branch 'master' of https://git.opensipkd.com/taufik/esipkd

2 parents 34787f16 958acf40
...@@ -151,6 +151,8 @@ def main(global_config, **settings): ...@@ -151,6 +151,8 @@ def main(global_config, **settings):
json_renderer.add_adapter(decimal.Decimal, lambda v, request: str(v)) json_renderer.add_adapter(decimal.Decimal, lambda v, request: str(v))
config.add_renderer('json_rpc', json_renderer) config.add_renderer('json_rpc', json_renderer)
config.add_jsonrpc_endpoint('api-webr', '/api/webr', default_renderer="json_rpc") config.add_jsonrpc_endpoint('api-webr', '/api/webr', default_renderer="json_rpc")
config.add_jsonrpc_endpoint('bjbva-callback', '/bjbva/callback', default_renderer="json_rpc")
config.add_jsonrpc_endpoint('bjbqris-callback', '/bjbqris/callback', default_renderer="json_rpc")
routes = DBSession.query(Route.kode, Route.path, Route.nama, Route.factory).all() routes = DBSession.query(Route.kode, Route.path, Route.nama, Route.factory).all()
for route in routes: for route in routes:
......
...@@ -41,7 +41,7 @@ from ..tools import as_timezone ...@@ -41,7 +41,7 @@ from ..tools import as_timezone
DBSession = scoped_session(sessionmaker(extension=ZopeTransactionExtension())) DBSession = scoped_session(sessionmaker(extension=ZopeTransactionExtension()))
Base = declarative_base() Base = declarative_base()
TABLE_ARGS = {'extend_existing':True}
############## ##############
# Base model # # Base model #
......
from sqlalchemy import (
Column,
Integer,
Text,
DateTime,
ForeignKey,
UniqueConstraint,
String,
SmallInteger,
BigInteger,
Float,
Date,
)
from sqlalchemy.orm.exc import NoResultFound
from sqlalchemy.orm import (
relationship,
backref
)
from ..models import (NamaModel, Base, DBSession, CommonModel, KodeModel, TABLE_ARGS, User)
import requests
import json
import sys
from .rpc import json_rpc_header, get_jsonrpc
from ..tools import date_from_str, ymd, ymdhms
import logging
log = logging.getLogger('BJBQRIS LOG')
from datetime import datetime, date, timedelta,time
def datetime_from_str(values):
separator = None
values = values.split()
value = values[0] # dd-mm-yyyy HH:MM:SS
tgl = date_from_str(value)
t = [0,0,0]
if len(values) > 1:
t = values[1].split(':')
return datetime(tgl.year, tgl.month, tgl.day, int(t[0]), int(t[1]), int(t[2]))
def cek_parameter(parameter):
if not parameter['bjbqris_url']:
log.error('bjbqris_url parameter belum ada')
return
if not parameter['bjbqris_user']:
log.error('bjbqris_user parameter belum ada')
return
if not parameter['bjbqris_key']:
log.error('bjbqris_key parameter belum ada')
return
return True
class BJBQRIS(KodeModel, Base):
__tablename__ = 'bjb_qris'
id = Column(Integer, primary_key=True)
client_type = Column(SmallInteger)
## 0: VA Offline
## 1: Ecommerce
## 2: Edupay
## 3: Pajak
## 4: Rumah Sakit
invoice_no = Column(String(16))
product_code = Column(String(2))
## 01 = BPHTB
## 02 = PBB
## 05 = SAMSAT
## 10 = PDL
## 30 = WEBR
## 90 = PERIZINAN
description = Column(String(128))
customer_name = Column(String(64))
customer_email = Column(String(128))
customer_phone = Column(String(32))
client_refnum = Column(String(128))
expired_date = Column(DateTime)
amount = Column(BigInteger)
billing_type = Column(String(1))
## o = open payment
## f = fixed payment
va_type = Column(String(1))
va_number = Column(String(32))
currency = Column(String(3))
customer_id = Column(String(32))
status = Column(String(1), server_default='0')
## 0 = belum dibayar
## 1 = dibayar sebagian
## 2 = dibayar penuh
## 3 = kadaluarsa
## 4 = disabled
cin = Column(String(4))
response_code = Column(String(4))
response_message = Column(String(128))
qrcode = Column(Text)
type = Column(String(64))
merchantName = Column(String(128))
transactionDate = Column(DateTime)
transactionStatus = Column(String(64))
transactionAmount = Column(BigInteger)
transactionReference = Column(String(128))
paymentReference = Column(String(64))
merchantBalance = Column(String(255))
merchantMsisdn = Column(String(128))
merchantEmail = Column(String(64))
merchantMpan = Column(String(64))
rrn = Column(String(64))
customerName = Column(String(128))
invoiceNumber = Column(String(128))
created = Column(DateTime, nullable=False, default=datetime.now,server_default='now()')
updated = Column(DateTime)
create_uid = Column(Integer, nullable=False, default=1,server_default='1')
update_uid = Column(Integer),
__table_args__ = TABLE_ARGS
@classmethod
def save(cls, values, row=None, **kwargs):
if not row:
row = cls()
row.from_dict(values)
if 'transaction_date' in values and not isinstance(values['transaction_date'], datetime):
values['transaction_date'] = datetime_from_str(values['transaction_date'])
DBSession.add(row)
DBSession.flush()
return row
@classmethod
def create_va(cls, values, parameter):
cek = cek_parameter(parameter)
if not cek:
return False
data = dict(
client_type = values['client_type'],
invoice_no = str(values['invoice_no']),
product_code = str(values['product_code']),
description = str(values['description']),
customer_name = str(values['customer_name']),
customer_email = str(values['customer_email']),
customer_phone = str(values['customer_phone']),
expired_date = str(values['expired_date']),
amount = str(values['amount'])
)
datava = send_rpc(parameter, 'create', data)
if not datava:
return False
saved = cls.save(datava)
return saved
def send_rpc(parameter, method, data):
headers = json_rpc_header(parameter['bjbqris_user'],parameter['bjbqris_key'])
params = get_jsonrpc(method, dict(data=data))
try:
resp = requests.post(url=parameter['bjbqris_url'],
data=json.dumps(params),
headers=headers)
try:
datava = json.loads(resp.content)
log.error("RESPONSE FROM VA")
log.error(resp.text)
if 'error' in datava:
log.error(resp.content)
return datava['result']['data']
except:
log.error('Response Error')
log.error(resp.content)
return False
return False
except requests.exceptions.RequestException as err:
log.error('Gagal membuat koneksi, silakan coba lagi beberapa saat')
return False
\ No newline at end of file \ No newline at end of file
from sqlalchemy import (
Column,
Integer,
Text,
DateTime,
ForeignKey,
UniqueConstraint,
String,
SmallInteger,
BigInteger,
Float,
Date,
)
from sqlalchemy.orm.exc import NoResultFound
from sqlalchemy.orm import (
relationship,
backref
)
from ..models import (NamaModel, Base, DBSession, CommonModel, KodeModel, TABLE_ARGS, User)
import requests
import json
import sys
from .rpc import json_rpc_header, get_jsonrpc
from ..tools import date_from_str, ymd, ymdhms
import logging
log = logging.getLogger('BJBVA LOG')
from datetime import datetime, date, timedelta,time
def datetime_from_str(values):
separator = None
values = values.split()
value = values[0] # dd-mm-yyyy HH:MM:SS
tgl = date_from_str(value)
t = [0,0,0]
if len(values) > 1:
t = values[1].split(':')
return datetime(tgl.year, tgl.month, tgl.day, int(t[0]), int(t[1]), int(t[2]))
def cek_parameter(parameter):
if not parameter['bjbva_url']:
log.error('bjbva_url parameter belum ada')
return
if not parameter['bjbva_user']:
log.error('bjbva_user parameter belum ada')
return
if not parameter['bjbva_key']:
log.error('bjbva_key parameter belum ada')
return
return True
class BJBVA(KodeModel, Base):
__tablename__ = 'bjb_va'
id = Column(Integer, primary_key=True)
client_type = Column(SmallInteger)
## 0: VA Offline
## 1: Ecommerce
## 2: Edupay
## 3: Pajak
## 4: Rumah Sakit
invoice_no = Column(String(16))
product_code = Column(String(2))
## 01 = BPHTB
## 02 = PBB
## 05 = SAMSAT
## 10 = PDL
## 30 = WEBR
## 90 = PERIZINAN
description = Column(String(128))
customer_name = Column(String(64))
customer_email = Column(String(128))
customer_phone = Column(String(32))
client_refnum = Column(String(128))
expired_date = Column(DateTime)
amount = Column(BigInteger)
billing_type = Column(String(1))
## o = open payment
## f = fixed payment
va_type = Column(String(1))
va_number = Column(String(32))
currency = Column(String(3))
customer_id = Column(String(32))
status = Column(String(1), server_default='0')
## 0 = belum dibayar
## 1 = dibayar sebagian
## 2 = dibayar penuh
## 3 = kadaluarsa
## 4 = disabled
cin = Column(String(4))
response_code = Column(String(4))
response_message = Column(String(128))
transaction_date = Column(DateTime)
transaction_amount = Column(BigInteger)
created = Column(DateTime, nullable=False, default=datetime.now,server_default='now()')
updated = Column(DateTime)
create_uid = Column(Integer, nullable=False, default=1,server_default='1')
update_uid = Column(Integer),
__table_args__ = TABLE_ARGS
@classmethod
def save(cls, values, row=None, **kwargs):
if not row:
row = cls()
row.from_dict(values)
if 'transaction_date' in values and not isinstance(values['transaction_date'], datetime):
values['transaction_date'] = datetime_from_str(values['transaction_date'])
DBSession.add(row)
DBSession.flush()
return row
@classmethod
def create_va(cls, values, parameter):
cek = cek_parameter(parameter)
if not cek:
return False
data = dict(
client_type = values['client_type'],
invoice_no = values['invoice_no'],
product_code = values['product_code'],
description = values['description'],
customer_name = values['customer_name'],
customer_email = values['customer_email'],
customer_phone = values['customer_phone'],
expired_date = values['expired_date'],
amount = str(values['amount'])
)
datava = send_rpc(parameter, 'create', data)
if not datava:
return False
saved = cls.save(datava)
return saved
@classmethod
def update_va(cls, values, row, parameter):
cek = cek_parameter(parameter)
if not cek:
return False
if 'expired_date' in values and isinstance(values['expired_date'], datetime):
values['expired_date'] = ymdhms(values['expired_date'])
data = dict(
va_number = values['va_number'],
invoice_no = values['invoice_no'],
product_code = values['product_code'],
amount = str(values['amount']),
expired_date = str(values['expired_date']),
customer_name = str(values['customer_name']),
customer_email = str(values['customer_email']),
customer_phone = str(values['customer_phone']),
description = str(values['description'])
)
datava = send_rpc(parameter, 'update', data)
if not datava:
return False
saved = cls.save(datava, row)
return saved
@classmethod
def inquiry_va(cls, row, parameter):
cek = cek_parameter(parameter)
if not cek:
return False
data = dict(
va_number = row.va_number,
invoice_no = row.invoice_no,
product_code = row.product_code
)
datava = send_rpc(parameter, 'inquiry', data)
if not datava:
return False
saved = cls.save(datava, row)
return saved
@classmethod
def cancel_va(cls, values, parameter):
cek = cek_parameter(parameter)
if not cek:
return False
row = cls.query().filter_by(va_number=values['va_number']).first()
data = dict(
va_number = row.va_number,
invoice_no = row.invoice_no,
product_code = row.product_code,
amount = str(row.amount),
expired_date = ymdhms(datetime.now()+timedelta(seconds=30)),
customer_name = row.customer_name,
customer_email = row.customer_email,
customer_phone = row.customer_phone,
description = row.description
)
datava = send_rpc(parameter, 'update', data)
if not datava:
return False
datava['status'] = '3'
saved = cls.save(datava, row)
return saved
def send_rpc(parameter, method, data):
headers = json_rpc_header(parameter['bjbva_user'],parameter['bjbva_key'])
params = get_jsonrpc(method, dict(data=data))
try:
resp = requests.post(url=parameter['bjbva_url'],
data=json.dumps(params),
headers=headers)
try:
datava = json.loads(resp.content)
log.error("RESPONSE FROM VA")
log.error(resp.text)
if 'error' in datava:
log.error(resp.content)
return datava['result']['data']
except:
log.error('Response Error')
log.error(resp.content)
return False
return False
except requests.exceptions.RequestException as err:
log.error('Gagal membuat koneksi, silakan coba lagi beberapa saat')
return False
\ No newline at end of file \ No newline at end of file
...@@ -284,6 +284,18 @@ class Anggaran(NamaModel, Base): ...@@ -284,6 +284,18 @@ class Anggaran(NamaModel, Base):
rekenings = relationship("Rekening", backref=backref('anggarans')) rekenings = relationship("Rekening", backref=backref('anggarans'))
UniqueConstraint('rekening_id','tahun', name='anggaran_rekening_tahun') UniqueConstraint('rekening_id','tahun', name='anggaran_rekening_tahun')
class AnggaranOPD(NamaModel, Base):
__tablename__ = 'anggaran_unit'
status = Column(Integer, default=1)
tahun = Column(Integer, nullable=False, default=0)
rekening_id = Column(Integer, ForeignKey("rekenings.id"))
unit_id = Column(Integer, ForeignKey("units.id"))
murni = Column(BigInteger)
perubahan = Column(BigInteger)
rekenings = relationship("Rekening", backref=backref('anggaran_unit'))
units = relationship("Unit", backref=backref('anggaran_unit'))
UniqueConstraint('rekening_id','tahun', name='anggaran_unit_rekening_tahun')
class Wilayah(NamaModel,Base): class Wilayah(NamaModel,Base):
__tablename__ = 'wilayahs' __tablename__ = 'wilayahs'
id = Column(Integer, primary_key=True) id = Column(Integer, primary_key=True)
...@@ -404,6 +416,10 @@ class ARInvoice(CommonModel, Base): ...@@ -404,6 +416,10 @@ class ARInvoice(CommonModel, Base):
units = relationship("Unit", backref=backref('arinvoices')) units = relationship("Unit", backref=backref('arinvoices'))
UniqueConstraint(tahun_id,unit_id,no_id,name='arinvoice_uq') UniqueConstraint(tahun_id,unit_id,no_id,name='arinvoice_uq')
@classmethod
def query(cls):
return DBSession.query(cls)
class ARSspd(CommonModel, Base): class ARSspd(CommonModel, Base):
__tablename__ = 'arsspds' __tablename__ = 'arsspds'
id = Column(Integer, primary_key=True) id = Column(Integer, primary_key=True)
......
...@@ -22,9 +22,14 @@ from ..models import( ...@@ -22,9 +22,14 @@ from ..models import(
KodeModel, KodeModel,
NamaModel, NamaModel,
Base, Base,
CommonModel CommonModel,
User
) )
from .isipkd import ARInvoice from .isipkd import ARInvoice
import base64
import hashlib
import hmac
import sys
class DepartemenRoute(KodeModel, Base): class DepartemenRoute(KodeModel, Base):
__tablename__ = 'departemen_route' __tablename__ = 'departemen_route'
...@@ -34,3 +39,272 @@ class DepartemenRoute(KodeModel, Base): ...@@ -34,3 +39,272 @@ class DepartemenRoute(KodeModel, Base):
ar_invoice_id = Column(Integer, ForeignKey(ARInvoice.id)) ar_invoice_id = Column(Integer, ForeignKey(ARInvoice.id))
arinvoice = relationship(ARInvoice) arinvoice = relationship(ARInvoice)
__table_args__ = {'extend_existing':True} __table_args__ = {'extend_existing':True}
####################### API TOOL #######################################
from ..tools import (date_from_str, dict_to_str, to_str, get_settings)
from datetime import datetime
from pyramid_rpc.jsonrpc import JsonRpcError
now = datetime.now()
datenow = now.date()
lima_menit = 600
def auth_from_rpc(request):
settings = get_settings()
env = request.environ
if not ('HTTP_USERID' in env and 'HTTP_SIGNATURE' in env and
'HTTP_KEY' in env):
raise JsonRpcInvalidLoginError
http_userid = env['HTTP_USERID']
q = DBSession.query(User).filter_by(user_name=http_userid)
user = q.first()
if not user or user.status == 0:
raise JsonRpcInvalidLoginError
# bypass cek authentication for development
if http_userid=='admin' and 'devel' in settings and settings['devel']:
return user
time_stamp = int(env['HTTP_KEY'])
now = get_seconds()
if (not 'devel' in settings or not settings['devel']) and abs(now - time_stamp) > lima_menit:
raise JsonRpcInvalidTimeError
header = json_rpc_header(http_userid, user.api_key, time_stamp)
if header['signature'] != env['HTTP_SIGNATURE']:
raise JsonRpcInvalidLoginError
return user
def json_rpc_header(userid, password, time_stamp=None):
if not time_stamp:
time_stamp = str(get_seconds())
value = '&'.join([str(userid), str(time_stamp)])
password = str(password)
signature = hmac.new(key=str.encode(password), msg=str.encode(value),
digestmod=hashlib.sha256).digest()
if sys.version < '3':
encoded_signature = base64.encodestring(signature).replace('\n', '')
else:
encoded_signature = base64.encodebytes(signature).decode().replace('\n', '')
return dict(userid=userid, signature=encoded_signature, key=time_stamp)
def get_jsonrpc(method, params):
return dict(jsonrpc='2.0', method=method, params=params, id=get_random_number(6))
class JsonRpcNotImplementedError(JsonRpcError):
code = -40000
message = "Method Not Implemented"
class JsonRpcDbUrlNotFoundError(JsonRpcError):
code = -40001
message = "DB URL Connection Not Found"
class JsonRpcDbConnectionError(JsonRpcError):
code = -40002
message = "DB Connection Not Found"
class JsonRpcDataNotFoundError(JsonRpcError):
code = -40003
message = "Error Data Not Found"
class JsonRpcDataFoundError(JsonRpcError):
code = -40004
message = "Error Data Found"
# error terkait authentication dan authorization
class JsonRpcInvalidLoginError(JsonRpcError):
code = -41001
message = "Invalid RPC User/Password"
class JsonRpcInvalidNikError(JsonRpcError):
code = -41002
message = 'NIK Tidak Valid'
class JsonRpcNikFoundError(JsonRpcError):
code = -41003
message = 'NIK Sudah Ada'
class JsonRpcMobileFoundError(JsonRpcError):
code = -41004
message = 'No HP Sudah Digunakan'
class JsonRpcInvalidMobileError(JsonRpcError):
code = -41004
message = 'No HP Tidak Valid'
class JsonRpcInvalidDataError(JsonRpcError):
code = -41005
message = 'Data Tidak Valid'
class JsonRpcEmailFoundError(JsonRpcError):
code = -41006
message = 'e-mail Sudah Digunakan'
class JsonRpcInvalidEmailError(JsonRpcError):
code = -41007
message = 'e-mail Tidak Valid'
class JsonRpcMailError(JsonRpcError):
code = -41008
message = 'Gagal autentikasi mail server'
class JsonRpcUserFoundError(JsonRpcError):
code = -41009
message = 'User sudah digunakan'
class JsonRpcRegisterFailError(JsonRpcError):
code = -41010
message = 'Gagal Registrasi User'
class JsonRpcProfileFailError(JsonRpcError):
code = -41011
message = 'Gagal Update Profile'
class JsonRpcGetPasswordError(JsonRpcError):
code = -41012
message = 'Gagal Request Password'
class JsonRpcUserNotFoundError(JsonRpcError):
code = -41013
message = 'User Tidak Ada'
class JsonRpcInvalidTimeError(JsonRpcError):
code = -41014
message = 'Periksa Date Time Server'
class JsonRpcPermissionError(JsonRpcError):
code = -41015
message = 'Hak Akses dibatasi'
# error terkait transaksi
class JsonRpcInvalidInvoiceError(JsonRpcError):
code = -50001
message = 'Invalid No Bayar'
class JsonRpcBankNotFoundError(JsonRpcError):
code = -51001
message = 'Bank Not Found'
class JsonRpcBillNotFoundError(JsonRpcError):
code = -52001
message = 'Bill Not Found'
class JsonRpcBillAllreadyPaidError(JsonRpcError):
code = -52002
message = 'Bill Allready Paid'
class JsonRpcBillDifferentError(JsonRpcError):
code = -52003
message = 'Bill Amount Different'
class JsonRpcNtbNotFoundError(JsonRpcError):
code = -53001
message = 'NTB Not Found'
class JsonRpcNtbNotValidError(JsonRpcError):
code = -53002
message = 'NTB Not Valid'
# Reversal Message
class JsonRpcPaymentNotFoundError(JsonRpcError):
code = -54001
message = 'Payment Not Found'
class JsonRpcPaymentNotOwnerError(JsonRpcError):
code = -54002
message = 'Not Your Payment'
class JsonRpcPaymentOpenError(JsonRpcError):
code = -54003
message = 'Payment Open'
class JsonRpcReversedError(JsonRpcError):
code = -54004
message = 'Payment Reversed'
class JsonRpcReversalError(JsonRpcError):
code = -54005
message = 'Cannot Reversed'
# Biller Status
class JsonRpcBillerNotFoundError(JsonRpcError):
code = -55001
message = 'Biller Not Found'
class JsonRpcBillerNetworkError(JsonRpcError):
code = -55002
message = 'Biller Network unrecognized'
class JsonRpcProdukNotFoundError(JsonRpcError):
code = -56001
message = 'Produk Not Found'
def custom_error(code, message):
cls = JsonRpcError()
cls.code = code
cls.message = message
cls.message = message
raise cls
def get_mandatory(data, values):
for value in values:
if not value in data or data[value] == '' or data[value] == None:
raise JsonRpcInvalidDataError(message="{} Not Found".format(value))
def get_seconds():
begin_unix_time = datetime(1970, 1, 1)
durasi = datetime.utcnow() - begin_unix_time
return int(durasi.total_seconds())
def get_random_number(width=12):
return ''.join(choice(digits) \
for _ in range(width))
def clear_null_value(values):
# digunakan untuk menghapus dictionary yang value nya null
tobe_del = []
for value in values:
if not values[value]:
tobe_del.append(value)
for value in tobe_del:
del values[value]
return values
def ymd(tgl):
return tgl.strftime('%Y-%m-%d')
\ No newline at end of file \ No newline at end of file
...@@ -80,7 +80,7 @@ def set_sequence(orm): ...@@ -80,7 +80,7 @@ def set_sequence(orm):
seq_name = table_seq(orm.__table__) seq_name = table_seq(orm.__table__)
if not seq_name: if not seq_name:
return return
row = DBSession.query(orm).order_by('id DESC').first() row = DBSession.query(orm).order_by(text('id DESC')).first()
last_id = row and row.id or 1 last_id = row and row.id or 1
sql = "SELECT setval('%s', %d)" % (seq_name, last_id) sql = "SELECT setval('%s', %d)" % (seq_name, last_id)
engine = DBSession.bind engine = DBSession.bind
......
...@@ -243,3 +243,20 @@ id,kode,nama,path,factory,perm_name,disabled,created,updated,create_uid ...@@ -243,3 +243,20 @@ id,kode,nama,path,factory,perm_name,disabled,created,updated,create_uid
258,"ranking-det","Ranking Detail","/ranking/det",,"read",0,"2020-10-13 08:38:45",,1 258,"ranking-det","Ranking Detail","/ranking/det",,"read",0,"2020-10-13 08:38:45",,1
259,"rek-det","Rekening Detail","/rek/det",,"read",0,"2020-10-13 08:38:45",,1 259,"rek-det","Rekening Detail","/rek/det",,"read",0,"2020-10-13 08:38:45",,1
260,"chart-det","Chart Detail","/chart/det",,"read",0,"2020-10-13 08:38:45",,1 260,"chart-det","Chart Detail","/chart/det",,"read",0,"2020-10-13 08:38:45",,1
261,"anggaran-opd","Anggaran OPD","/anggaran/opd",,"read",0,"2015-03-08 16:45:45",,1
262,"anggaran-opd-act","Baca Anggaran OPD","/anggaran/opd/{act}/act",,"read",0,"2015-03-08 16:45:45",,1
263,"anggaran-opd-add","Tambah Anggaran OPD","/anggaran/opd/add",,"add",0,"2015-03-08 16:45:45",,1
264,"anggaran-opd-edit","Edit Anggaran OPD","/anggaran/opd/{id}/edit",,"edit",0,"2015-03-08 16:45:45",,1
265,"anggaran-opd-delete","Hapus Anggaran OPD","/anggaran/opd/{id}/delete",,"delete",0,"2015-03-08 16:45:45",,1
266,"anggaran-opd-csv","CSV Anggaran OPD","/anggaran/opd/{csv}/csv",,"read",0,"2015-03-08 16:45:45",,1
267,"anggaran-opd-pdf","PDF Anggaran OPD","/anggaran/opd/{pdf}/pdf",,"read",0,"2015-03-08 16:45:45",,1
268,"bjbva","BJB VA","/bjbva",,"read",0,"2022-06-24 16:45:45",,1
269,"bjbva-add","BJB VA Add","/bjbva/add",,"read",0,"2022-06-24 16:45:45",,1
270,"bjbva-edt","BJB VA Edit","/bjbva/{id}/edt",,"read",0,"2022-06-24 16:45:45",,1
271,"bjbva-del","BJB VA Hapus","/bjbva/{id}/del",,"read",0,"2022-06-24 16:45:45",,1
272,"bjbva-act","","/bjbva/{act}/act",,"read",0,"2022-06-24 16:45:45",,1
273,"bjbqris","BJB QRIS","/bjbqris",,"read",0,"2022-06-24 16:45:45",,1
274,"bjbqris-add","BJB QRIS Add","/bjbqris/add",,"read",0,"2022-06-24 16:45:45",,1
275,"bjbqris-act","","/bjbqris/{act}/act",,"read",0,"2022-06-24 16:45:45",,1
\ No newline at end of file \ No newline at end of file
...@@ -5,6 +5,7 @@ from sqlalchemy import ( ...@@ -5,6 +5,7 @@ from sqlalchemy import (
engine_from_config, engine_from_config,
select, select,
) )
from sqlalchemy.sql import text
from sqlalchemy.schema import CreateSchema from sqlalchemy.schema import CreateSchema
from pyramid.paster import ( from pyramid.paster import (
get_appsettings, get_appsettings,
...@@ -18,6 +19,10 @@ from ..models import ( ...@@ -18,6 +19,10 @@ from ..models import (
) )
from ..models.isipkd import * from ..models.isipkd import *
from ..models.rpc import *
from ..models.bjb_va import *
from ..models.bjb_qris import *
from sqlalchemy.dialects import oracle
import initial_data import initial_data
from tools import mkdir from tools import mkdir
...@@ -72,9 +77,14 @@ def usage(argv): ...@@ -72,9 +77,14 @@ def usage(argv):
sys.exit(1) sys.exit(1)
def create_schema(engine, schema): def create_schema(engine, schema):
sql = select([('schema_name')]).\ sql = select([text('schema_name')]). \
select_from('information_schema.schemata').\ select_from(text('information_schema.schemata')). \
where("schema_name = '%s'" % schema) where(text("schema_name = '%s'" % schema))
if isinstance(engine.dialect, oracle.dialect):
sql = select([text('owner')]). \
select_from(text('dba_segments')). \
where(text("owner = '%s'" % schema.upper()))
print(sql)
q = engine.execute(sql) q = engine.execute(sql)
if not q.fetchone(): if not q.fetchone():
engine.execute(CreateSchema(schema)) engine.execute(CreateSchema(schema))
......
...@@ -171,8 +171,35 @@ def date_from_str(value): ...@@ -171,8 +171,35 @@ def date_from_str(value):
def dmy(tgl): def dmy(tgl):
return tgl.strftime('%d-%m-%Y') return tgl.strftime('%d-%m-%Y')
def dmyhms(t): def ymd(tgl):
return t.strftime('%d-%m-%Y %H:%M:%S') return tgl.strftime('%Y-%m-%d')
def ymdhms(date):
if isinstance(date, str):
return date
return date.strftime('%Y-%m-%d %H:%M:%S')
def dmyhms(date):
if isinstance(date, str):
return date
return date.strftime('%d-%m-%Y %H:%M:%S')
def datetime_from_str(values):
separator = None
values = values.split()
value = values[0] # dd-mm-yyyy HH:MM:SS
tgl = date_from_str(value)
t = [0,0,0]
if len(values) > 1:
t = values[1].split(':')
return datetime(tgl.year, tgl.month, tgl.day, int(t[0]), int(t[1]), int(t[2]))
def dmy_to_date(tgl):
return datetime.strptime(tgl, '%d-%m-%Y')
def dMy(tgl):
return str(tgl.day) + ' ' + NAMA_BULAN[tgl.month][1] + ' ' + str(tgl.year)
def next_month(year, month): def next_month(year, month):
if month == 12: if month == 12:
...@@ -710,3 +737,11 @@ def round_up(value): ...@@ -710,3 +737,11 @@ def round_up(value):
if isinstance(value, int): if isinstance(value, int):
value = float(value) value = float(value)
return int(round(value+0.4999)) return int(round(value+0.4999))
def get_tmp():
settings = get_settings()
if 'tmp_files' in settings and settings['tmp_files']:
tmpf = settings['tmp_files'].strip('/')
return str(tmpf)+'/'
else:
return str("/tmp/")
\ No newline at end of file \ No newline at end of file
...@@ -9,16 +9,67 @@ from pyramid.security import (remember, forget, authenticated_userid,) ...@@ -9,16 +9,67 @@ from pyramid.security import (remember, forget, authenticated_userid,)
from deform import (Form, ValidationFailure, widget,) from deform import (Form, ValidationFailure, widget,)
from ..tools import dmy, date_from_str, int_to_roman, round_up from ..tools import dmy, date_from_str, int_to_roman, round_up
from sqlalchemy import func, and_, case from sqlalchemy import func, and_, case
from sqlalchemy.sql import text
from collections import namedtuple
from sqlalchemy.orm.properties import RelationshipProperty
from sqlalchemy.sql.expression import asc, desc
# ColumnTuple = namedtuple('ColumnDT', ['column_name', 'mData', 'search_like', 'filter'])
from ..models import (DBSession, User,) from ..models import (DBSession, User,)
from ..models.isipkd import( from ..models.isipkd import(
ARSspd, ARInvoice, Unit, Rekening, Anggaran ARSspd, ARInvoice, Unit, Rekening, Anggaran, AnggaranOPD
) )
from pyramid.view import notfound_view_config from pyramid.view import notfound_view_config
import logging import logging
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
from datatables import DataTables as BaseDataTables, ColumnDT
class DataTables(BaseDataTables):
def sorting(self):
"""Construct the query, by adding sorting(ORDER BY) on the columns needed to be applied on
"""
sorting = []
Order = namedtuple('order', ['name', 'dir'])
if self.request_values.get('iSortCol_0') \
and self.request_values.get('iSortingCols') > 0:
for i in range(int(self.request_values['iSortingCols'])):
sorting.append(Order( self.columns[int(self.request_values['iSortCol_'+str(i)])].column_name,
self.request_values['sSortDir_'+str(i)]))
for sort in sorting:
tmp_sort_name = sort.name.split('.')
obj = getattr(self.sqla_object, tmp_sort_name[0])
if not hasattr(obj, "property"): #hybrid_property or property
sort_name = sort.name
if hasattr(self.sqla_object, "__tablename__"):
tablename = self.sqla_object.__tablename__
else:
tablename = self.sqla_object.__table__.name
elif isinstance(obj.property, RelationshipProperty): # Ex: ForeignKey
# Ex: address.description => description => addresses.description
sort_name = "".join(tmp_sort_name[1:])
if not sort_name:
# Find first primary key
sort_name = obj.property.table.primary_key.columns \
.values()[0].name
tablename = obj.property.table.name
else: #-> ColumnProperty
sort_name = sort.name
if hasattr(self.sqla_object, "__tablename__"):
tablename = self.sqla_object.__tablename__
else:
tablename = self.sqla_object.__table__.name
sort_name = "%s.%s" % (tablename, sort_name)
self.query = self.query.order_by(
asc(text(sort_name)) if sort.dir == 'asc' else desc(text(sort_name)))
############################################################################### ###############################################################################
# Not Found # Not Found
...@@ -192,17 +243,18 @@ def view_home(request): ...@@ -192,17 +243,18 @@ def view_home(request):
# .all() # .all()
invoices = DBSession.query( invoices = DBSession.query(
case([ case([
(Anggaran.perubahan > 0, (AnggaranOPD.perubahan > 0,
func.coalesce(Anggaran.perubahan,0)) func.coalesce(AnggaranOPD.perubahan,0))
], ],
else_= func.coalesce(Anggaran.murni,0)).label('jumlah'), else_= func.coalesce(AnggaranOPD.murni,0)).label('jumlah'),
func.trim(Rekening.kode).label('rek_kode'), func.trim(Rekening.kode).label('rek_kode'),
Anggaran.kode.label('kode'), AnggaranOPD.kode.label('kode'),
Anggaran.nama.label('nama'), AnggaranOPD.nama.label('nama'),
).join(Rekening, Rekening.id == Anggaran.rekening_id).\ ).join(Rekening, Rekening.id == AnggaranOPD.rekening_id).\
filter(Anggaran.tahun==dates['year']).order_by(Anggaran.kode)\ filter(AnggaranOPD.tahun==dates['year']).order_by(AnggaranOPD.kode)\
.all() .all()
for i in invoices: for i in invoices:
# print(">>>>i", i)
## JIKA ADA FILTER DEPARTEMEN DI HEADER ## JIKA ADA FILTER DEPARTEMEN DI HEADER
if 'unit' in request.params and request.params['unit']: if 'unit' in request.params and request.params['unit']:
if i.kode.strip().startswith(request.params['unit'].strip()): if i.kode.strip().startswith(request.params['unit'].strip()):
...@@ -244,6 +296,7 @@ def view_home(request): ...@@ -244,6 +296,7 @@ def view_home(request):
data_dashboard['sopd'] = sorted(data_dashboard['sopd'], key = lambda i: (i['realisasi']), reverse=True) data_dashboard['sopd'] = sorted(data_dashboard['sopd'], key = lambda i: (i['realisasi']), reverse=True)
i=-1 i=-1
for opd in data_dashboard['sopd']: for opd in data_dashboard['sopd']:
# print(">>>>opd", opd)
i+=1 i+=1
if i < 10: if i < 10:
data_dashboard['sopd10'].append(dict( data_dashboard['sopd10'].append(dict(
......
...@@ -255,19 +255,25 @@ def save(request, values, row=None): ...@@ -255,19 +255,25 @@ def save(request, values, row=None):
if not row: if not row:
row = ARSspd() row = ARSspd()
row.create_date = datetime.now(utc) row.create_date = datetime.now(utc)
row.create_uid = request.user.id row.create_uid = hasattr(request.user,'id') and request.user.id or 1
if 'id' not in request.matchdict:
del values['id']
row.from_dict(values) row.from_dict(values)
row.update_date = datetime.now(utc) row.update_date = datetime.now(utc)
row.update_uid = request.user.id row.update_uid = hasattr(request.user,'id') and request.user.id or 1
row.bunga = re.sub("[^0-9]", "", row.bunga) row.bunga = row.bunga and int(re.sub("[^0-9]", "", str(row.bunga))) or 0
row.bayar = re.sub("[^0-9]", "", row.bayar) row.bayar = row.bayar and int(re.sub("[^0-9]", "", str(row.bayar))) or 0
if not row.tahun_id: if not row.tahun_id:
row.tahun_id = datetime.now().strftime('%Y') row.tahun_id = datetime.now().strftime('%Y')
##query invoice 27-06-2022
ref = DBSession.query(ARInvoice).\
filter(ARInvoice.kode==values['invoice_no']).\
first()
if not row.pembayaran_ke: if not row.pembayaran_ke:
invoice_no = DBSession.query(func.count(ARSspd.arinvoice_id)).\ invoice_no = DBSession.query(func.count(ARSspd.arinvoice_id)).\
filter(ARSspd.tahun_id==row.tahun_id, filter(ARSspd.tahun_id==ref.tahun_id,
ARSspd.arinvoice_id==row.arinvoice_id).\ ARSspd.arinvoice_id==ref.id).\
scalar() scalar()
print "--------- Invoice No ---------- ",invoice_no print "--------- Invoice No ---------- ",invoice_no
if not invoice_no: if not invoice_no:
...@@ -276,9 +282,9 @@ def save(request, values, row=None): ...@@ -276,9 +282,9 @@ def save(request, values, row=None):
row.pembayaran_ke = invoice_no+1 row.pembayaran_ke = invoice_no+1
## -------- Update 29 Agustus 2017 ----------------- ## ## -------- Update 29 Agustus 2017 ----------------- ##
ref = DBSession.query(ARInvoice).\ # ref = DBSession.query(ARInvoice).\
filter(ARInvoice.id==row.arinvoice_id).\ # filter(ARInvoice.id==row.arinvoice_id).\
scalar() # scalar()
row.unit_id = ref.unit_id row.unit_id = ref.unit_id
row.unit_kode = ref.unit_kode row.unit_kode = ref.unit_kode
row.unit_nama = ref.unit_nama row.unit_nama = ref.unit_nama
...@@ -291,15 +297,15 @@ def save(request, values, row=None): ...@@ -291,15 +297,15 @@ def save(request, values, row=None):
DBSession.add(row) DBSession.add(row)
DBSession.flush() DBSession.flush()
if int(row.bayar)>0: if int(row.bayar)>0:
row.arinvoices.status_bayar=1 ref.status_bayar=1
row.arinvoices.is_sspd=1 ref.is_sspd=1
else: else:
row.pembayaran_ke = row.pembayaran_ke ref.status_bayar=0
row.arinvoices.status_bayar=0 ref.is_sspd=0
row.arinvoices.is_sspd=0 DBSession.add(ref)
DBSession.add(row)
DBSession.flush() DBSession.flush()
return row setattr(ref, 'status', ref.status_bayar)
return ref
def save_request(values, request, row=None): def save_request(values, request, row=None):
if 'id' in request.matchdict: if 'id' in request.matchdict:
......
...@@ -13,118 +13,10 @@ from ..tools import (date_from_str, dict_to_str, to_str, get_settings) ...@@ -13,118 +13,10 @@ from ..tools import (date_from_str, dict_to_str, to_str, get_settings)
from ..models.isipkd import (DBSession, ARInvoice, ARSspd, User, Unit, from ..models.isipkd import (DBSession, ARInvoice, ARSspd, User, Unit,
ObjekPajak, SubjekPajak, Rekening, Wilayah) ObjekPajak, SubjekPajak, Rekening, Wilayah)
from .arinvoice import save as save_invoice from .arinvoice import save as save_invoice
from ..models.rpc import DepartemenRoute from ..models.rpc import DepartemenRoute, auth_from_rpc
import logging import logging
log = logging.getLogger(__name__) log = logging.getLogger('RPC ESIPKD')
now = datetime.now()
datenow = now.date()
lima_menit = 600
####################### API TOOL #######################################
def auth_from_rpc(request):
settings = get_settings()
env = request.environ
if not ('HTTP_USERID' in env and 'HTTP_SIGNATURE' in env and
'HTTP_KEY' in env):
raise JsonRpcInvalidLoginError
http_userid = env['HTTP_USERID']
q = DBSession.query(User).filter_by(user_name=http_userid)
user = q.first()
if not user or user.status == 0:
raise JsonRpcInvalidLoginError
# bypass cek authentication for development
if http_userid=='admin' and 'devel' in settings and settings['devel']:
return user
time_stamp = int(env['HTTP_KEY'])
now = get_seconds()
if (not 'devel' in settings or not settings['devel']) and abs(now - time_stamp) > lima_menit:
raise JsonRpcInvalidTimeError
header = json_rpc_header(http_userid, user.api_key, time_stamp)
if header['signature'] != env['HTTP_SIGNATURE']:
raise JsonRpcInvalidLoginError
return user
def json_rpc_header(userid, password, time_stamp=None):
if not time_stamp:
time_stamp = str(get_seconds())
value = '&'.join([str(userid), str(time_stamp)])
password = str(password)
signature = hmac.new(key=str.encode(password), msg=str.encode(value),
digestmod=hashlib.sha256).digest()
if sys.version < '3':
encoded_signature = base64.encodestring(signature).replace('\n', '')
else:
encoded_signature = base64.encodebytes(signature).decode().replace('\n', '')
return dict(userid=userid, signature=encoded_signature, key=time_stamp)
def get_jsonrpc(method, params):
return dict(jsonrpc='2.0', method=method, params=params, id=get_random_number(6))
class JsonRpcInvalidTimeError(JsonRpcError):
code = -41014
message = 'Periksa Date Time Server'
class JsonRpcInvalidLoginError(JsonRpcError):
code = -41001
message = "Invalid RPC User/Password"
class JsonRpcInvalidDataError(JsonRpcError):
code = -41005
message = 'Data Tidak Valid'
class JsonRpcBillNotFoundError(JsonRpcError):
code = -52001
message = 'Bill Not Found'
class JsonRpcBillAllreadyPaidError(JsonRpcError):
code = -52002
message = 'Bill Allready Paid'
class JsonRpcPaymentNotFoundError(JsonRpcError):
code = -54001
message = 'Payment Not Found'
def custom_error(code, message):
cls = JsonRpcError()
cls.code = code
cls.message = message
cls.message = message
raise cls
def get_mandatory(data, values):
for value in values:
if not value in data or not data[value]:
raise JsonRpcInvalidDataError(message="{} Not Found".format(value))
def get_seconds():
begin_unix_time = datetime(1970, 1, 1)
durasi = datetime.utcnow() - begin_unix_time
return int(durasi.total_seconds())
def get_random_number(width=12):
return ''.join(choice(digits) \
for _ in range(width))
def clear_null_value(values):
# digunakan untuk menghapus dictionary yang value nya null
tobe_del = []
for value in values:
if not values[value]:
tobe_del.append(value)
for value in tobe_del:
del values[value]
return values
def ymd(tgl):
return tgl.strftime('%Y-%m-%d')
########################################################################### ###########################################################################
......
<html metal:use-macro="load: ../base.pt">
<div metal:fill-slot="content" class="form-550">
<h4>Tambah/Edit Anggaran OPD</h4>
<hr>
<!--div tal:content="structure form"/-->
<form id="deform" method="POST" enctype="multipart/form-data" accept-charset="utf-8"
class="form-horizontal">
<fieldset class="deformFormFieldset">
<input type="hidden" name="_charset_" />
<input type="hidden" name="__formid__" value="deform"/>
<div class="form-group">
<div tal:condition="'id' in form">
<div tal:define="field form['id']">
${structure:field.serialize()}
</div>
</div>
<div tal:define="field form['kode']">
${structure:field.serialize()}
</div>
<div tal:define="field form['nama']">
${structure:field.serialize()}
</div>
<!--rekening_id -->
<div tal:define="field form['rekening_id']">
${structure:field.serialize()}
</div>
<div class="col-md-12">
<!--rekening-->
<div class="form-group" tal:define="field form['rekening_kd']" id="item-${field.oid}">
<label for="${field.oid}" class="control-label col-md-3" id="req-${field.oid}">
${field.title}<span id="error-${field.oid}" class="text text-danger"
tal:condition="field.required">&nbsp*</span></label>
<div class="col-md-9" tal:define="field form['rekening_kd']" >
${structure:field.serialize()}
<p id="error-${field.oid}" class="help-block" tal:condition="field.error"
tal:repeat="error field.error.messages()">
${error}</p>
</div>
</div>
<div class="form-group" tal:define="field form['rekening_nm']" id="item-${field.oid}">
<label for="${field.oid}" class="control-label col-md-3" id="req-${field.oid}">
${field.title}<span id="error-${field.oid}" class="text text-danger"
tal:condition="field.required">&nbsp*</span></label>
<div class="col-md-9" tal:define="field form['rekening_nm']" >
${structure:field.serialize()}
<p id="error-${field.oid}" class="help-block" tal:condition="field.error"
tal:repeat="error field.error.messages()">
${error}</p>
</div>
</div>
<!--opd-->
<div class="form-group" tal:define="field form['unit_id']" id="item-${field.oid}">
<label for="${field.oid}" class="control-label col-md-3" id="req-${field.oid}">
${field.title}<span id="error-${field.oid}" class="text text-danger"
tal:condition="field.required">&nbsp*</span></label>
<div class="col-md-9" tal:define="field form['unit_id']" >
${structure:field.serialize()}
<p id="error-${field.oid}" class="help-block" tal:condition="field.error"
tal:repeat="error field.error.messages()">
${error}</p>
</div>
</div>
<!--murni -->
<div class="form-group" tal:define="field form['murni']" id="item-${field.oid}">
<label for="${field.oid}" class="control-label col-md-3" id="req-${field.oid}">
${field.title}<span id="error-${field.oid}" class="text text-danger"
tal:condition="field.required">&nbsp*</span></label>
<div class="col-md-9">
${structure:field.serialize()}
<p id="error-${field.oid}" class="help-block" tal:condition="field.error"
tal:repeat="error field.error.messages()">
${error}</p>
</div>
</div>
<!--perubahan -->
<div class="form-group" tal:define="field form['perubahan']" id="item-${field.oid}">
<label for="${field.oid}" class="control-label col-md-3" id="req-${field.oid}">
${field.title}<span id="error-${field.oid}" class="text text-danger"
tal:condition="field.required">&nbsp*</span></label>
<div class="col-md-9">
${structure:field.serialize()}
<p id="error-${field.oid}" class="help-block" tal:condition="field.error"
tal:repeat="error field.error.messages()">
${error}</p>
</div>
</div>
<!--tahun -->
<div class="form-group" tal:define="field form['tahun']" id="item-${field.oid}">
<label for="${field.oid}" class="control-label col-md-3" id="req-${field.oid}">
${field.title}<span id="error-${field.oid}" class="text text-danger"
tal:condition="field.required">&nbsp*</span></label>
<div class="col-md-9">
${structure:field.serialize()}
<p id="error-${field.oid}" class="help-block" tal:condition="field.error"
tal:repeat="error field.error.messages()">
${error}</p>
</div>
</div>
<!--status -->
<div class="form-group" tal:define="field form['status']" id="item-${field.oid}">
<label for="${field.oid}" class="control-label col-md-3" id="req-${field.oid}">
${field.title}<span id="error-${field.oid}" class="text text-danger"
tal:condition="field.required">&nbsp*</span></label>
<div class="col-md-9">
${structure:field.serialize()}
<p id="error-${field.oid}" class="help-block" tal:condition="field.error"
tal:repeat="error field.error.messages()">
${error}</p>
</div>
</div>
<!--Button -->
<div class="form-group">
<label class="control-label col-md-3">
</label>
<div class="col-md-9">
<button id="deformsave" name="simpan" type="submit" class="btn btn-primary "
value="simpan">Simpan</button>
<button id="deformcancel" name="cancel" type="submit" class="btn btn-danger "
value="cancel">Batal</button>
</div>
</div>
</div>
</div>
<script>
$('#rekening_kd').typeahead({
"hint" : true,
"highlight": true,
"minLength": 1,
"limit" : 20,
"remote" : "/rekening/hok_anggaran/act?term=%QUERY",
},{
"name" : 'rekening_kd',
"displayKey": 'value',
});
$('#rekening_kd').bind('typeahead:selected', function(obj, datum, name) {
$('#rekening_id').val(datum.id);
$('#rekening_nm').val(datum.nama);
$('#kode').val(datum.value);
$('#nama').val(datum.nama);
});
$('#rekening_nm').typeahead({
"hint" : true,
"highlight": true,
"minLength": 1,
"limit" : 20,
"remote" : "/rekening/hon_anggaran/act?term=%QUERY",
},{
"name" : 'rekening_nm',
"displayKey": 'value',
});
$('#rekening_nm').bind('typeahead:selected', function(obj, datum, name) {
$('#rekening_id').val(datum.id);
$('#rekening_kd').val(datum.kode);
$('#kode').val(datum.kode);
$('#nama').val(datum.value);
});
$('#murni').keyup(function(){
var murni = this.value.length;
});
$('#perubahan').keyup(function(){
var perubahan = this.value.length;
});
</script>
</fieldset>
</form>
</div>
</html>
<html metal:use-macro="load: ../base.pt">
<div metal:fill-slot="content">
<div class="panel panel-danger">
<div class="panel-heading">
<h3 class="panel-title">Warning</h3>
</div>
<div class="panel-body">
Hapus anggaran rekening ${row.kode} ${row.nama} tahun ${row.tahun} ?
</div>
</div>
<div tal:content="structure form"/>
</div>
</html>
<html metal:use-macro="load: ../base.pt">
<div metal:fill-slot="content" class="form-550">
<h4>Edit Tarif</h4>
<hr>
<!--div tal:content="structure form"/-->
<form id="deform" method="POST" enctype="multipart/form-data" accept-charset="utf-8"
class="form-horizontal">
<fieldset class="deformFormFieldset">
<input type="hidden" name="_charset_" />
<input type="hidden" name="__formid__" value="deform"/>
<div class="form-group">
<div tal:condition="'id' in form">
<div tal:define="field form['id']">
${structure:field.serialize()}
</div>
</div>
<div class="col-md-12">
<!--kode -->
<div class="form-group" tal:define="field form['kode']" id="item-${field.oid}">
<label for="${field.oid}" class="control-label col-md-3" id="req-${field.oid}">
${field.title}<span id="error-${field.oid}" class="text text-danger"
tal:condition="field.required">&nbsp*</span></label>
<div class="col-md-9">
${structure:field.serialize()}
<p id="error-${field.oid}" class="help-block" tal:condition="field.error"
tal:repeat="error field.error.messages()">
${error}</p>
</div>
</div>
<!--nama -->
<div class="form-group" tal:define="field form['nama']" id="item-${field.oid}">
<label for="${field.oid}" class="control-label col-md-3" id="req-${field.oid}">
${field.title}<span id="error-${field.oid}" class="text text-danger"
tal:condition="field.required">&nbsp*</span></label>
<div class="col-md-9">
${structure:field.serialize()}
<p id="error-${field.oid}" class="help-block" tal:condition="field.error"
tal:repeat="error field.error.messages()">
${error}</p>
</div>
</div>
<!--rekening_id -->
<div class="form-group" tal:define="field form['rekening_id']" id="item-${field.oid}">
<label for="${field.oid}" class="control-label col-md-3" id="req-${field.oid}">
${field.title}<span id="error-${field.oid}" class="text text-danger"
tal:condition="field.required">&nbsp*</span></label>
<div class="col-md-9" tal:define="field form['rekening_id']" >
${structure:field.serialize()}
<p id="error-${field.oid}" class="help-block" tal:condition="field.error"
tal:repeat="error field.error.messages()">
${error}</p>
</div>
</div>
<!--tahun -->
<div class="form-group" tal:define="field form['tahun']" id="item-${field.oid}">
<label for="${field.oid}" class="control-label col-md-3" id="req-${field.oid}">
${field.title}<span id="error-${field.oid}" class="text text-danger"
tal:condition="field.required">&nbsp*</span></label>
<div class="col-md-9">
${structure:field.serialize()}
<p id="error-${field.oid}" class="help-block" tal:condition="field.error"
tal:repeat="error field.error.messages()">
${error}</p>
</div>
</div>
<!--tarif -->
<div class="form-group" tal:define="field form['tarif']" id="item-${field.oid}">
<label for="${field.oid}" class="control-label col-md-3" id="req-${field.oid}">
${field.title}<span id="error-${field.oid}" class="text text-danger"
tal:condition="field.required">&nbsp*</span></label>
<div class="col-md-9">
${structure:field.serialize()}
<p id="error-${field.oid}" class="help-block" tal:condition="field.error"
tal:repeat="error field.error.messages()">
${error}</p>
</div>
</div>
<!--status -->
<div class="form-group" tal:define="field form['status']" id="item-${field.oid}">
<label for="${field.oid}" class="control-label col-md-3" id="req-${field.oid}">
${field.title}<span id="error-${field.oid}" class="text text-danger"
tal:condition="field.required">&nbsp*</span></label>
<div class="col-md-9">
${structure:field.serialize()}
<p id="error-${field.oid}" class="help-block" tal:condition="field.error"
tal:repeat="error field.error.messages()">
${error}</p>
</div>
</div>
<!--Button -->
<div class="form-group">
<label class="control-label col-md-3">
</label>
<div class="col-md-9">
<button id="deformsave" name="simpan" type="submit" class="btn btn-primary "
value="simpan">Simpan</button>
<button id="deformcancel" name="cancel" type="submit" class="btn btn-danger "
value="cancel">Batal</button>
</div>
</div>
</div>
</div>
</fieldset>
</form>
</div>
</html>
<html metal:use-macro="load: ../base.pt">
<div metal:fill-slot="content">
<link href="/static/datatables/extensions/TableTools/css/dataTables.tableTools.min.css" rel="stylesheet">
<link href="/static/datatables/media/css/dataTables.bootstrap.css" rel="stylesheet">
<h4>Anggaran OPD</h4>
<hr>
<table id="table1" name="table1" class="table table-bordered table-hover table-condensed" >
<thead>
<tr>
<th>ID</th>
<th>Kode Rekening</th>
<th>Uraian Rekening</th>
<th>Unit Kerja/OPD</th>
<th>Murni</th>
<th>Perubahan</th>
<th>Tahun</th>
<th>Status</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
<script src="/static/datatables/media/js/jquery.dataTables.min.js"></script>
<!--script src="/static/datatables/media/js/jquery.jeditable.js')}"></script-->
<script src="/static/datatables/media/js/jquery.dataTables.ext.js"></script>
<script src="/static/datatables/extensions/TableTools/media/js/ZeroClipboard.js"></script>
<script src="/static/datatables/media/js/dataTables.bootstrap.js"></script>
<script>
var mID;
var oTable;
var iPos;
var oFormUrl = "/anggaran/opd/";
var oTableUrl = oFormUrl+"grid/act";
$(document).ready(function () {
oTable = $('#table1').dataTable({
"sAjaxSource" : oTableUrl,
"bStateSave" : true,
"bServerSide" : true,
"bProcessing" : true,
"sDom" : '<"toolbar">lfrtip',
"bScrollCollapse" : true,
"bSort" : true,
"bInfo" : false,
"bFilter" : true,
"bAutoWidth" : false,
"bPaginate" : true,
"sPaginationType" : "full_numbers",
"lengthMenu": [
[10, 25, 50, 100, 150, 200],
[10, 25, 50, 100, 150, 200]
],
"aoColumnDefs": [
{"bSearchable": false,
"bVisible" : false,
"aTargets" : [0]
}
],
"aoColumns": [
null,
{"sWidth": "100px", "sClass": "left"},
{"sWidth": "250px", "sClass": "left"},
{"sWidth": "250px", "sClass": "left"},
{"sWidth": "50px", "sClass": "right"},
{"sWidth": "50px", "sClass": "right"},
{"sWidth": "30px", "sClass": "center"},
{"sWidth": "40px", "sClass": "center"}
],
"language": {
"search" : "Cari: ",
"paginate":{
"first" : "Pertama ",
"last" : "Terakhir ",
"previous": "Sebelumnya ",
"next" : "Selanjutnya ",
},
"lengthMenu" : "Tampil _MENU_ baris "
}
});
var tb_array = [
'<div class="btn-group pull-left">',
' <button id="btn_tambah" class="btn btn btn-primary pull-left" type="button">Tambah</button>',
' <button id="btn_edit" class="btn btn btn-primary pull-left" type="button">Edit</button>',
' <button id="btn_delete" class="btn btn btn-danger pull-left" type="button">Hapus</button>',
//' <button id="btn_print" class="btn btn btn-primary pull-left" type="button">Cetak</button>',
' <button id="btn_pdf" class="btn btn btn-success pull-left" type="button">PDF</button>',
' <button id="btn_csv" class="btn btn btn-info pull-left" type="button">CSV</button>',
' <button id="btn_close" class="btn btn btn-warning" type="button">Tutup</button>',
' &nbsp;',
'</div>',
];
var tb = tb_array.join(' ');
$("div.toolbar").html(tb);
$('#table1 tbody').on('click', 'tr', function () {
if ($(this).hasClass('selected')) {
mID = '';
$(this).removeClass('selected');
} else {
iPos = oTable.fnGetPosition(this);
var aData = oTable.fnGetData(iPos);
mID = aData[0];
oTable.$('tr.selected').removeClass('selected');
$(this).addClass('selected');
}
});
$('#btn_tambah').click(function () {
window.location = oFormUrl+'add';
});
$('#btn_edit').click(function () {
if (mID) {
window.location = oFormUrl+mID+'/edit';
} else {
alert('Silahkan pilih data yang akan diedit');
}
});
$('#btn_print').click(function () {
url = "/reports/act/rAnggaran"
window.open(url);
});
$('#btn_pdf').click(function () {
url = oFormUrl+"reg/pdf";
window.open(url);
});
$('#btn_csv').click(function () {
url = oFormUrl+"reg/csv";
window.open(url);
});
$('#btn_close').click(function () {
window.location = "/"
});
$('#btn_delete').click(function () {
if (mID) {
var hapus = confirm('Hapus data ini?');
if (hapus == true) {
window.location = oFormUrl+mID+'/delete';
};
} else {
alert('Silahkan pilih data yang akan dihapus');
}
});
});
</script>
</div>
</html>
\ No newline at end of file \ No newline at end of file
...@@ -82,6 +82,13 @@ ...@@ -82,6 +82,13 @@
</li> </li>
<!--li tal:attributes="class request.path == '/arsspd' and 'active'"><a href="/arsspd">Penerimaan</a></li--> <!--li tal:attributes="class request.path == '/arsspd' and 'active'"><a href="/arsspd">Penerimaan</a></li-->
<li tal:attributes="class request.path == '/arsts' and 'active'"><a href="/arsts">STS</a></li> <li tal:attributes="class request.path == '/arsts' and 'active'"><a href="/arsts">STS</a></li>
<li class="dropdown" tal:attributes="class request.matched_route.name in ['bjbva','bjbva-add','bjbva-edt','bjbva-del','bjbva-act','bjbva-callback','bjbqris','bjbqris-add','bjbqris-act','bjbqris-callback'] and 'active'">
<a href="#" class="dropdown-toggle" data-toggle="dropdown">BJB<b class="caret"></b></a>
<ul class="dropdown-menu">
<li><a href="/bjbva">BJB VA</a></li>
<li><a href="/bjbqris">BJB QRIS</a></li>
</ul>
</li>
<!--li tal:attributes="class request.path == '/pbbkb' and 'active'"><a href="/pbbkb">PBB-KB</a></li> <!--li tal:attributes="class request.path == '/pbbkb' and 'active'"><a href="/pbbkb">PBB-KB</a></li>
...@@ -106,6 +113,7 @@ ...@@ -106,6 +113,7 @@
<li><a href="/rekening">Kode Rekening</a></li> <li><a href="/rekening">Kode Rekening</a></li>
<li><a href="/pajak">Tarif</a></li> <li><a href="/pajak">Tarif</a></li>
<li><a href="/anggaran">Anggaran</a></li> <li><a href="/anggaran">Anggaran</a></li>
<li><a href="/anggaran/opd">Anggaran-OPD</a></li>
<li><a href="/wilayah">Wilayah</a></li> <li><a href="/wilayah">Wilayah</a></li>
<li><a href="/sptpd/sektor">Sektor PBBKB</a></li> <li><a href="/sptpd/sektor">Sektor PBBKB</a></li>
<li><a href="/sptpd/peruntukan">Peruntukan PBBKB</a></li> <li><a href="/sptpd/peruntukan">Peruntukan PBBKB</a></li>
......
<html metal:use-macro="load: ../base.pt">
<div metal:fill-slot="content">
<link href="https://cdn.jsdelivr.net/npm/select2@4.1.0-rc.0/dist/css/select2.min.css" rel="stylesheet" />
<div class="panel panel-default">
<div class="panel-body">
<form id="cariform" method="POST" enctype="multipart/form-data" accept-charset="utf-8" class="form-horizontal">
<div class="alert alert-danger" tal:condition="form and form.error and True or False">
<div class="error-msg-lbl">Kesalahan Pengisian Form</div>
<p class="error-msg">${form.errormsg}</p>
</div>
<div class="form-group" tal:repeat="f form">
<div id="item-${f.oid}" style="${f.widget.hidden and 'display:none;' or 'display:block;'}">
<label for="${f.oid}" class="control-label col-md-2 ${f.required and 'required' or ''} " id="req-${f.oid}">
${f.title}</label>
<div class="col-md-3">
${structure:f.serialize()}
<p id="error-${f.oid}" class="help-block" tal:condition="f.error"
tal:repeat="error f.error.messages()">
${error}</p>
</div>
</div>
</div>
<div class="col-md-4">
<label class="control-label col-md-3"></label>
<button type="submit" class="btn btn-primary" id="simpan" name="simpan">Simpan</button>
<button type="submit" class="btn btn-warning" id="batal" name="batal">Tutup</button>
</div>
</form>
</div> <!--panel-body-->
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/smalot-bootstrap-datetimepicker/2.4.4/js/bootstrap-datetimepicker.min.js" integrity="sha512-4lTnmq2kNbykTiOPulgEvxRgqegB5/YMhMqaBWvxji/9wRgR9W/TSGF51/mIG1hQ6janxTojpr41y5/gaW9LRA==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/smalot-bootstrap-datetimepicker/2.4.4/css/bootstrap-datetimepicker.min.css" integrity="sha512-m9g5oqvMhf2FsilNZqftBnOR1GW+dJpb1a8RN+R3Aw1dVI2AeDfpSOa9Sm48xMacONC1vJlM2iIadPy4uLEC4Q==" crossorigin="anonymous" referrerpolicy="no-referrer" />
<script src="https://cdn.jsdelivr.net/npm/select2@4.1.0-rc.0/dist/js/select2.min.js"></script>
<script>
$(document).ready(function () {
function formatNumber(toFormat) {
return toFormat.toString().replace(
/\B(?=(\d{3})+(?!\d))/g, "."
);
};
$('.input-date').datetimepicker({
format: "yyyy-mm-dd hh:ii:ss"
});
<tal:block tal:condition="not 'id' in request.matchdict">
$('#invoice_no').select2({
ajax: {
url: '/bjbqris/kodebayar/act',
dataType: 'json',
type: "GET",
quietMillis: 50,
data: function (q) {
return {
'term': q.term
};
},
processResults: function (data) {
return {
results: $.map(data, function (item) {
return {
text: item.nama+' - '+item.kode,
id: item.kode
}
})
};
}
}
});
$('#invoice_no').on("select2:select", function(e) {
$.ajax({
type: 'GET',
url: '/bjbqris/detail/act',
dataType: 'json',
data : {
term : $('#invoice_no').val()
},
success: function(data) {
$('#description').val(data.description);
$('#customer_name').val(data.customer_name);
$('#customer_phone').val(data.customer_phone);
$('#customer_email').val(data.customer_email);
$('#expired_date').val(data.expired_date);
$('#amount').val(data.amount);
}
});
});
</tal:block>
<tal:block tal:condition="'id' in request.matchdict and request.matchdict['id']">
$('#va_number').prop('readonly', true);
$('#invoice_no').prop('readonly', true);
$('#status').prop('readonly', true);
$('#billing_type').prop('readonly', true);
$('#va_type').prop('readonly', true);
$('#currency').prop('readonly', true);
$('#customer_id').prop('readonly', true);
$('#cin').prop('readonly', true);
$('#response_code').prop('readonly', true);
$('#response_message').prop('readonly', true);
</tal:block>
});
</script>
</div> <!-- /metal:content -->
</html>
\ No newline at end of file \ No newline at end of file
<html metal:use-macro="load: ../main.pt">
<div metal:fill-slot="content">
<div class="panel panel-danger">
<div class="panel-heading">
<h3 class="panel-title">Warning</h3>
</div>
<div class="panel-body">
CANCEL No. VA #${row.va_number}?
</div>
</div>
<div tal:content="structure form"/>
</div>
</html>
<html metal:use-macro="load: ../base.pt">
<div metal:fill-slot="content">
<link href="/static/datatables/media/css/dataTables.bootstrap.css" rel="stylesheet">
<h4>Daftar BJB QRIS</h4>
<form id="filter_form" method="POST" enctype="multipart/form-data" accept-charset="utf-8" class="form-inline">
<div class="form-group">
<label for="exampleInputName2">Tahun</label>
<input class="form-control" id="tahun" name="tahun" type="text" value="${request.session['tahun']}"/>
</div>
</form>
<div class="clearfix" style="margin-top:20px"></div>
<div class="clearfix"></div>
<table id="table1" class="table table-bordered table-hover table-condensed">
<thead>
<tr>
<th>ID</th>
<th>ID BILLING</th>
<th>Kode Bayar</th>
<th>Deskripsi</th>
<th>Subjek Nama</th>
<th>Jumlah</th>
<th>Refnum</th>
<th>Expired Date</th>
<th>Tgl Bayar</th>
<th>Status</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
<div id="form_cetak" class="modal fade" tabindex="-1" role="dialog">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
<h3 id="cuDialogLabel">Cetak Daftar Penerimaan Harian</h3>
</div>
<div class="modal-body form-group">
<div class="input-group col-md-12">
<label class="control-label col-md-3">Pejabat</label>
<div class="col-md-7">
<input class="form-control" id="pejabat" type="text" >
<input type="hidden" class="form-control" name="id_pejabat" id="id_pejabat" >
</div>
</div>
<div class="clearfix" style="margin-top:20px"></div>
<div class="clearfix"></div>
</div>
<div class="modal-footer">
<div class="btn-group center-block" role="group">
<button class="btn btn-primary" id="btn_pdf">Cetak</button>
</div>
<button class="btn" data-dismiss="modal" aria-hidden="true" id="batal">Batal</button>
</div>
</div>
</div>
</div>
<script src="/static/datatables/media/js/jquery.dataTables.min.js"></script>
<script src="/static/datatables/media/js/dataTables.bootstrap.js"></script>
<script>
var mID;
var oTable;
var oTableUri = "/bjbqris"
var oTableUrl = oTableUri+"/grid/act";
$(document).ready(function () {
oTable = $('#table1').DataTable({
ajaxSource : oTableUrl,
//"bStateSave" : true,
serverSide : true,
"bProcessing" : true,
"sDom" : '<"toolbar">lfrtip',
"bScrollCollapse": true,
"bSort" : true,
"bSearch" : true,
"bInfo" : false,
"bFilter" : true,
"bAutoWidth" : false,
"bPaginate" : true,
"sPaginationType": "full_numbers",
lengthMenu: [
[10, 25, 50, 100],
[10, 25, 50, 100]
],
columnDefs: [{
searchable: false,
visible: false,
targets: [0]
}],
"language": {
"search" : "Cari: ",
"paginate":{
"first" : "Pertama ",
"last" : "Akhir ",
"previous": false,
"next" : false,
},
"lengthMenu": " _MENU_ baris "
},
});
var tb_array = [
'<div class="btn-group pull-left">',
' <button id="btn_add" class="btn btn btn-success" type="button">Create QRIS</button>',
//' <button id="btn_edit" class="btn btn btn-warning" type="button">Update VA</button>',
//' <button id="btn_update" class="btn btn btn-primary" type="button">Inquiry VA</button>',
//' <button id="btn_delete" class="btn btn btn-danger" type="button">Cancel VA</button>',
' <button id="btn_qrcode" class="btn btn btn-info" type="button">View QRCODE</button>',
' &nbsp;',
'</div>',
];
var tb = tb_array.join(' ');
$("div.toolbar").html(tb);
$("div.toolbar").attr('style', 'display:block; float: left; margin-bottom:6px; line-height:16px;');
$('#table1 tbody').on('click', 'tr', function () {
if ($(this).hasClass('selected')) {
$(this).removeClass('selected');
} else {
var aData = oTable.row( this ).data();
oTable.$('tr.selected').removeClass('selected');
$(this).addClass('selected');
mID = aData[0];
oTable.$('tr.row_selected').removeClass('row_selected');
$(this).addClass('row_selected');
}
});
$('#btn_add').click(function () {
window.location = oTableUri+'/add';
});
$("#btn_close").click(function () {
window.location = '/';
return false;
});
$("#btn_qrcode").click(function () {
if (mID) window.open(oTableUri+"/qrcode/act?id="+mID,"_blank","width=350,height=350");
else
alert("Pilih Baris yang akan di lihat...");
});
});
</script>
</div> <!-- metal:content -->
</html>
\ No newline at end of file \ No newline at end of file
<img src="data:image/png;base64, ${qr}" alt="" width="300px" height="300px">
\ No newline at end of file \ No newline at end of file
<html metal:use-macro="load: ../base.pt">
<div metal:fill-slot="content">
<link href="https://cdn.jsdelivr.net/npm/select2@4.1.0-rc.0/dist/css/select2.min.css" rel="stylesheet" />
<div class="panel panel-default">
<div class="panel-body">
<form id="cariform" method="POST" enctype="multipart/form-data" accept-charset="utf-8" class="form-horizontal">
<div class="alert alert-danger" tal:condition="form and form.error and True or False">
<div class="error-msg-lbl">Kesalahan Pengisian Form</div>
<p class="error-msg">${form.errormsg}</p>
</div>
<div class="form-group" tal:repeat="f form">
<div id="item-${f.oid}" style="${f.widget.hidden and 'display:none;' or 'display:block;'}">
<label for="${f.oid}" class="control-label col-md-2 ${f.required and 'required' or ''} " id="req-${f.oid}">
${f.title}</label>
<div class="col-md-3">
${structure:f.serialize()}
<p id="error-${f.oid}" class="help-block" tal:condition="f.error"
tal:repeat="error f.error.messages()">
${error}</p>
</div>
</div>
</div>
<div class="col-md-4">
<label class="control-label col-md-3"></label>
<button type="submit" class="btn btn-primary" id="simpan" name="simpan">Simpan</button>
<button type="submit" class="btn btn-warning" id="batal" name="batal">Tutup</button>
</div>
</form>
</div> <!--panel-body-->
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/smalot-bootstrap-datetimepicker/2.4.4/js/bootstrap-datetimepicker.min.js" integrity="sha512-4lTnmq2kNbykTiOPulgEvxRgqegB5/YMhMqaBWvxji/9wRgR9W/TSGF51/mIG1hQ6janxTojpr41y5/gaW9LRA==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/smalot-bootstrap-datetimepicker/2.4.4/css/bootstrap-datetimepicker.min.css" integrity="sha512-m9g5oqvMhf2FsilNZqftBnOR1GW+dJpb1a8RN+R3Aw1dVI2AeDfpSOa9Sm48xMacONC1vJlM2iIadPy4uLEC4Q==" crossorigin="anonymous" referrerpolicy="no-referrer" />
<script src="https://cdn.jsdelivr.net/npm/select2@4.1.0-rc.0/dist/js/select2.min.js"></script>
<script>
$(document).ready(function () {
function formatNumber(toFormat) {
return toFormat.toString().replace(
/\B(?=(\d{3})+(?!\d))/g, "."
);
};
$('.input-date').datetimepicker({
format: "yyyy-mm-dd hh:ii:ss"
});
<tal:block tal:condition="not 'id' in request.matchdict">
$('#invoice_no').select2({
ajax: {
url: '/bjbva/kodebayar/act',
dataType: 'json',
type: "GET",
quietMillis: 50,
data: function (q) {
return {
'term': q.term
};
},
processResults: function (data) {
return {
results: $.map(data, function (item) {
return {
text: item.nama+' - '+item.kode,
id: item.kode
}
})
};
}
}
});
$('#invoice_no').on("select2:select", function(e) {
$.ajax({
type: 'GET',
url: '/bjbva/detail/act',
dataType: 'json',
data : {
term : $('#invoice_no').val()
},
success: function(data) {
$('#description').val(data.description);
$('#customer_name').val(data.customer_name);
$('#customer_phone').val(data.customer_phone);
$('#customer_email').val(data.customer_email);
$('#expired_date').val(data.expired_date);
$('#amount').val(data.amount);
}
});
});
</tal:block>
<tal:block tal:condition="'id' in request.matchdict and request.matchdict['id']">
$('#va_number').prop('readonly', true);
$('#invoice_no').prop('readonly', true);
$('#status').prop('readonly', true);
$('#billing_type').prop('readonly', true);
$('#va_type').prop('readonly', true);
$('#currency').prop('readonly', true);
$('#customer_id').prop('readonly', true);
$('#cin').prop('readonly', true);
$('#response_code').prop('readonly', true);
$('#response_message').prop('readonly', true);
</tal:block>
});
</script>
</div> <!-- /metal:script -->
</html>
\ No newline at end of file \ No newline at end of file
<html metal:use-macro="load: ../main.pt">
<div metal:fill-slot="content">
<div class="panel panel-danger">
<div class="panel-heading">
<h3 class="panel-title">Warning</h3>
</div>
<div class="panel-body">
CANCEL No. VA #${row.va_number}?
</div>
</div>
<div tal:content="structure form"/>
</div>
</html>
<html metal:use-macro="load: ../base.pt">
<div metal:fill-slot="content">
<link href="/static/datatables/media/css/dataTables.bootstrap.css" rel="stylesheet">
<h4>Daftar BJB VA</h4>
<div class="dataTables_wrapper form-inline no-footer">
<form id="filter_form" method="POST" enctype="multipart/form-data" accept-charset="utf-8" class="form-inline">
<div class="form-group">
<label for="exampleInputName2">Tahun</label>
<input class="form-control" id="tahun" name="tahun" type="text" value="${request.session['tahun']}"/>
</div>
</form>
<div class="clearfix" style="margin-top:20px"></div>
<div class="clearfix"></div>
<table id="table1" class="table table-bordered table-hover table-condensed">
<thead>
<tr>
<th>ID</th>
<th>No. VA</th>
<th>Kode Bayar</th>
<th>Deskripsi</th>
<th>Subjek Nama</th>
<th>Jumlah</th>
<th>Refnum</th>
<th>Expired Date</th>
<th>Tgl Bayar</th>
<th>Status</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
</div>
<div id="form_cetak" class="modal fade" tabindex="-1" role="dialog">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
<h3 id="cuDialogLabel">Cetak Daftar Penerimaan Harian</h3>
</div>
<div class="modal-body form-group">
<div class="input-group col-md-12">
<label class="control-label col-md-3">Pejabat</label>
<div class="col-md-7">
<input class="form-control" id="pejabat" type="text" >
<input type="hidden" class="form-control" name="id_pejabat" id="id_pejabat" >
</div>
</div>
<div class="clearfix" style="margin-top:20px"></div>
<div class="clearfix"></div>
</div>
<div class="modal-footer">
<div class="btn-group center-block" role="group">
<button class="btn btn-primary" id="btn_pdf">Cetak</button>
</div>
<button class="btn" data-dismiss="modal" aria-hidden="true" id="batal">Batal</button>
</div>
</div>
</div>
</div>
<script src="/static/datatables/media/js/jquery.dataTables.min.js"></script>
<script src="/static/datatables/media/js/dataTables.bootstrap.js"></script>
<script>
var mID;
var oTable;
var oTableUri = "/bjbva"
var oTableUrl = oTableUri+"/grid/act";
$(document).ready(function () {
oTable = $('#table1').DataTable({
ajaxSource : oTableUrl,
//"bStateSave" : true,
serverSide : true,
"bProcessing" : true,
"sDom" : '<"toolbar">lfrtip',
"bScrollCollapse": true,
"bSort" : true,
"bSearch" : true,
"bInfo" : false,
"bFilter" : true,
"bAutoWidth" : false,
"bPaginate" : true,
"sPaginationType": "full_numbers",
lengthMenu: [
[10, 25, 50, 100],
[10, 25, 50, 100]
],
columnDefs: [{
searchable: false,
visible: false,
targets: [0]
}],
"language": {
"search" : "Cari: ",
"paginate":{
"first" : "Pertama ",
"last" : "Akhir ",
"previous": false,
"next" : false,
},
"lengthMenu": " _MENU_ baris "
},
});
var tb_array = [
'<div class="btn-group pull-left">',
' <button id="btn_add" class="btn btn btn-success" type="button">Create VA</button>',
' <button id="btn_edit" class="btn btn btn-warning" type="button">Update VA</button>',
' <button id="btn_update" class="btn btn btn-primary" type="button">Inquiry VA</button>',
' <button id="btn_delete" class="btn btn btn-danger" type="button">Cancel VA</button>',
' &nbsp;',
'</div>',
];
var tb = tb_array.join(' ');
$("div.toolbar").html(tb);
$("div.toolbar").attr('style', 'display:block; float: left; margin-bottom:6px; line-height:16px;');
$('#table1 tbody').on('click', 'tr', function () {
if ($(this).hasClass('selected')) {
$(this).removeClass('selected');
} else {
var aData = oTable.row( this ).data();
oTable.$('tr.selected').removeClass('selected');
$(this).addClass('selected');
mID = aData[0];
oTable.$('tr.row_selected').removeClass('row_selected');
$(this).addClass('row_selected');
}
});
$('#btn_add').click(function () {
window.location = oTableUri+'/add';
});
$('#btn_edit').click(function () {
if (mID) window.location = oTableUri+'/'+mID+'/edt';
else
alert("Pilih Baris yang akan di edit...");
});
$('#btn_delete').click(function () {
if (mID) window.location = oTableUri+'/'+mID+'/del';
else
alert("Pilih Baris yang akan di hapus...");
});
$('#btn_update').click(function () {
if (mID) {
$.ajax({
type: 'GET',
url: oTableUri+'/update/act',
dataType: 'json',
data : {
term : mID
},
success: function(data) {
oTable.ajax.url(oTableUrl).load();
}
});
}
else
alert("Pilih Baris yang akan di inquiry...");
});
$("#btn_close").click(function () {
window.location = '/';
return false;
});
});
</script>
</div>
</html>
\ No newline at end of file \ No newline at end of file
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!