Commit f616135a by taufikyu

penambahan eis, dan rpc

1 parent 0aca380e
import sys
import locale
from pyramid.config import Configurator
......@@ -13,12 +12,13 @@ from pyramid.httpexceptions import (
default_exceptionresponse_view,
HTTPFound, HTTPNotFound
)
from pyramid.renderers import JSON
from types import (
StringType,
UnicodeType,
)
from sqlalchemy import engine_from_config
import datetime, decimal, time
from .security import group_finder, get_user
from .models import (
DBSession,
......@@ -131,6 +131,27 @@ def main(global_config, **settings):
config.add_renderer('csv', '.tools.CSVRenderer')
############################################################################
# Custom JSON
############################################################################
json_renderer = JSON()
json_renderer.add_adapter(datetime.datetime, lambda v, request: dmy(v))
json_renderer.add_adapter(datetime.date, lambda v, request: dmy(v))
json_renderer.add_adapter(decimal.Decimal, lambda v, request: str(v))
config.add_renderer('json', json_renderer)
############################################################################
# JSON RPC
############################################################################
config.include('pyramid_rpc.jsonrpc')
format = '%Y-%m-%dT%H:%M:%S%z'
json_renderer = JSON()
json_renderer.add_adapter(datetime.datetime, lambda v, request: v.isoformat())
json_renderer.add_adapter(datetime.date, lambda v, request: v.isoformat())
json_renderer.add_adapter(decimal.Decimal, lambda v, request: str(v))
config.add_renderer('json_rpc', json_renderer)
config.add_jsonrpc_endpoint('api-webr', '/api/webr', default_renderer="json_rpc")
routes = DBSession.query(Route.kode, Route.path, Route.nama, Route.factory).all()
for route in routes:
if route.factory and route.factory != 'None':
......
......@@ -180,6 +180,7 @@ class UserResourcePermission(UserResourcePermissionMixin, Base):
class User(UserMixin, BaseModel, CommonModel, Base):
api_key = Column(String(256))
last_login_date = Column(DateTime(timezone=True), nullable=True)
registered_date = Column(DateTime(timezone=True),
nullable=False,
......
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(
DBSession,
DefaultModel,
KodeModel,
NamaModel,
Base,
CommonModel
)
from .isipkd import ARInvoice
class DepartemenRoute(KodeModel, Base):
__tablename__ = 'departemen_route'
status = Column(SmallInteger, nullable=False, default=0)
no_skrd = Column(String(64))
tgl_skrd = Column(Date)
ar_invoice_id = Column(Integer, ForeignKey(ARInvoice.id))
arinvoice = relationship(ARInvoice)
__table_args__ = {'extend_existing':True}
\ No newline at end of file
......@@ -228,4 +228,11 @@ id,kode,nama,path,factory,perm_name,disabled,created,updated,create_uid
243,"arinvoicewp-pdf","PDF Reg. Bayar WP","/arinvoicewp/{pdf}/pdf",,"read",0,"2015-03-08 16:45:45",,1
244,"report","Laporan","/report",,"read",0,"2015-03-08 16:45:45",,1
245,"report-sspd","Laporan Penerimaan","/report/sspd",,"read",0,"2015-03-08 16:45:45",,1
246,"sptpd-wapu-posting","Posting SPTPD WAPU","/sptpd/wapu/posting",,"read",0,"2015-03-08 16:45:45",,1
\ No newline at end of file
246,"sptpd-wapu-posting","Posting SPTPD WAPU","/sptpd/wapu/posting",,"read",0,"2015-03-08 16:45:45",,1
247,"anggaran","Anggaran","/anggaran",,"read",0,"2015-03-08 16:45:45",,1
248,"anggaran-act","Baca Anggaran","/anggaran/{act}/act",,"read",0,"2015-03-08 16:45:45",,1
249,"anggaran-add","Tambah Anggaran","/anggaran/add",,"add",0,"2015-03-08 16:45:45",,1
250,"anggaran-edit","Edit Anggaran","/anggaran/{id}/edit",,"edit",0,"2015-03-08 16:45:45",,1
251,"anggaran-delete","Hapus Anggaran","/anggaran/{id}/delete",,"delete",0,"2015-03-08 16:45:45",,1
252,"anggaran-csv","CSV Anggaran","/anggaran/{csv}/csv",,"read",0,"2015-03-08 16:45:45",,1
253,"anggaran-pdf","PDF Anggaran","/anggaran/{pdf}/pdf",,"read",0,"2015-03-08 16:45:45",,1
\ No newline at end of file
This diff could not be displayed because it is too large.
......@@ -19,6 +19,7 @@ from types import (
from datetime import (
datetime,
timedelta,
date
)
from pyramid.threadlocal import get_current_registry
......
import pytz
import transaction
import colander
from datetime import datetime
from datetime import datetime, date
from email.utils import parseaddr
from pyramid.view import view_config
from pyramid.httpexceptions import (HTTPFound, HTTPForbidden, HTTPNotFound)
......@@ -9,6 +9,9 @@ from pyramid.security import (remember, forget, authenticated_userid,)
from deform import (Form, ValidationFailure, widget,)
from ..models import (DBSession, User,)
from ..models.isipkd import(
ARSspd, ARInvoice, Unit
)
from pyramid.view import notfound_view_config
......@@ -38,7 +41,65 @@ from pyramid.view import notfound_view_config
########
@view_config(route_name='home', renderer='templates/home.pt')
def view_home(request):
return dict(project='esipkd')
now = date.today()
dates = dict(
year = now.year,
month = now.month,
week = int(now.strftime('%W')),
day = now,
)
data_dashboard = dict(
tabular = dict(
tahun = dict(q=0,n=0),
bulan = dict(q=0,n=0),
minggu = dict(q=0,n=0),
hari = dict(q=0,n=0),
),
chart = dict(
q = [0,0,0,0,0,0,0,0,0,0,0,0],
n = [0,0,0,0,0,0,0,0,0,0,0,0],
),
opd= [],
sopd= [],
)
payments = DBSession.query(
ARSspd.tgl_bayar.label('tanggal'),
ARSspd.bayar.label('jumlah'),
Unit.kode.label('kode'),
Unit.nama.label('nama'),
).join(ARInvoice, ARInvoice.id == ARSspd.arinvoice_id).\
join(Unit, Unit.kode == ARInvoice.unit_kode).\
filter(ARSspd.tahun_id==dates['year']).order_by(ARInvoice.unit_kode).all()
prev_opd = ''
i = -1
for p in payments:
data_dashboard['tabular']['tahun']['q'] += 1
data_dashboard['tabular']['tahun']['n'] += int(p.jumlah)
if p.tanggal.month == dates['month']:
data_dashboard['tabular']['bulan']['q'] += 1
data_dashboard['tabular']['bulan']['n'] += int(p.jumlah)
if int(p.tanggal.strftime('%W')) == dates['week']:
data_dashboard['tabular']['minggu']['q'] += 1
data_dashboard['tabular']['minggu']['n'] += int(p.jumlah)
if p.tanggal.date() == dates['day']:
data_dashboard['tabular']['hari']['q'] += 1
data_dashboard['tabular']['hari']['n'] += int(p.jumlah)
for x in range(12):
if p.tanggal.month == x+1:
data_dashboard['chart']['q'][x] += int(1)
data_dashboard['chart']['n'][x] += int(p.jumlah)
if prev_opd != p.kode:
i += 1
data_dashboard['opd'].append(dict(kode=p.kode.strip(),unit=p.nama.strip(),jumlah=0))
data_dashboard['opd'][i]['jumlah']+=int(p.jumlah)
prev_opd = p.kode
sort_opd = sorted(data_dashboard['opd'], key = lambda i: (i['jumlah']), reverse=True)
i = 0
for sopd in sort_opd:
if i<10:
data_dashboard['sopd'].append(dict(peringkat=i+1, upd=sopd['unit'], nominal=sopd['jumlah']))
i+=1
return dict(project='esipkd', dates=dates, data = data_dashboard)
#########
......
......@@ -218,10 +218,12 @@ def save(request, values, row=None):
if not row:
row = ARInvoice()
row.create_date = datetime.now()
row.create_uid = request.user.id
if hasattr(request.user,'id'):
row.create_uid = request.user.id
row.from_dict(values)
#row.update_date = datetime.now()
row.update_uid = request.user.id
if hasattr(request.user,'id'):
row.update_uid = request.user.id
row.dasar = re.sub("[^0-9]", "", row.dasar)
row.tarif = re.sub("[^0-9]", "", row.tarif)
row.pokok = re.sub("[^0-9]", "", row.pokok)
......@@ -237,8 +239,8 @@ def save(request, values, row=None):
row.unit_nm = unit.nama
ref = Unit.get_by_id(row.unit_id)
row.unit_kode = ref.kode
row.unit_nama = ref.nama
row.unit_kode = ref.kode.strip()
row.unit_nama = ref.nama.strip()
ref = SubjekPajak.get_by_id(row.subjek_pajak_id)
row.wp_kode = ref.kode
#row.wp_nama = ref.nama
......@@ -284,8 +286,8 @@ def save(request, values, row=None):
str(bulan).rjust(2,'0'),
str(tahun).rjust(2,'0'),
str(row.no_id).rjust(4,'0')])
row.owner_id = request.user.id
if hasattr(request.user,'id'):
row.owner_id = request.user.id
DBSession.add(row)
DBSession.flush()
return row
......
import sys
import json
import requests
import hmac
import hashlib
import base64
from datetime import datetime, time, date
from sqlalchemy import not_, func, between, and_
from pyramid_rpc.jsonrpc import jsonrpc_method
from pyramid_rpc.jsonrpc import JsonRpcError
from ..tools import (date_from_str, dict_to_str, to_str, get_settings)
##MODEL
from ..models.isipkd import (DBSession, ARInvoice, ARSspd, User, Unit,
ObjekPajak, SubjekPajak, Rekening, Wilayah)
from .arinvoice import save as save_invoice
from ..models.rpc import DepartemenRoute
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
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')
###########################################################################
def save_departemen_route(request, values, row=None):
if not row:
row = DepartemenRoute()
if not 'kode' in values or not values['kode']:
return 0
if not 'no_skrd' in values or not values['no_skrd']:
return 0
if not 'tgl_skrd' in values or not values['tgl_skrd']:
return 0
if not 'ar_invoice_id' in values or not values['ar_invoice_id']:
return 0
if not 'status' in values:
values['status'] = 0
row.from_dict(values)
DBSession.add(row)
DBSession.flush()
return row
@jsonrpc_method(method='set_invoice', endpoint='api-webr')
def set_invoice(request, data):
"""
Digunakan untuk menerima data tagihan
:param request:
:param data:
- op_kode
- rek_kode
- dasar
- tarif
- pokok
- denda
- bunga
- jumlah
- periode_1
- periode_2
- jatuh_tempo
- tgl_skrd
:return:
- kd_bayar
"""
auth_from_rpc(request)
param = ['op_kode','rek_kode','dasar','tarif',
'pokok','denda','bunga','jumlah','periode_1',
'periode_2','jatuh_tempo','tgl_tetap']
get_mandatory(data, param)
values = clear_null_value(data)
if 'jatuh_tempo' in values and values['jatuh_tempo']:
values['jatuh_tempo'] = date_from_str(values['jatuh_tempo'])
if 'periode_1' in values and values['periode_1']:
values['periode_1'] = date_from_str(values['periode_1'])
if 'periode_2' in values and values['periode_2']:
values['periode_2'] = date_from_str(values['periode_2'])
if not 'status_bayar' in values or not values['status_bayar']:
values['status_bayar'] = 0
op = ObjekPajak.get_by_kode(values['op_kode'])
if not op:
return custom_error(-1,'Objek Pajak not found')
values['objek_pajak_id'] = op.id
values['op_kode'] = op.kode
values['op_nama'] = op.nama
values['op_alamat_1'] = op.alamat_1
values['op_alamat_2'] = op.alamat_2
values['wilayah_id'] = op.wilayah_id
values['subjek_pajak_id'] = op.subjekpajak_id
values['unit_id'] = op.unit_id
subjek = SubjekPajak.get_by_id(values['subjek_pajak_id'])
if not subjek:
return custom_error(-1,'Subjek Pajak not found, contact admin')
values['wp_kode'] = subjek.kode
values['wp_nama'] = subjek.nama
values['wp_alamat_1'] = subjek.alamat_1
values['wp_alamat_2'] = subjek.alamat_2
unit = Unit.get_by_id(values['unit_id'])
if not unit:
return custom_error(-1,'Unit not found, contact admin')
values['unit_kode'] = unit.id
values['unit_nama'] = unit.nama
rek = Rekening.get_by_kode(values['rek_kode'])
if not rek:
return custom_error(-1,'Rekening not found, contact admin')
values['rekening_id'] = rek.id
values['rek_nama'] = rek.nama
for v in values:
v = v.strip()
row_invoice = DBSession.query(ARInvoice).\
filter(
ARInvoice.tgl_tetap == values['tgl_tetap'],
ARInvoice.op_kode == values['op_kode'],
ARInvoice.rekening_id == values['rekening_id'],
).first()
if row_invoice:
if row_invoice.status_bayar == 1:
raise JsonRpcBillAllreadyPaidError
return custom_error(-1,'Bill already exist')
else:
invoice = save_invoice(request, values)
# Save Departemen_Route
values['kode'] = invoice.kode
values['tgl_skrd'] = invoice.tgl_tetap
values['ar_invoice_id'] = invoice.id
save_departemen_route(request, values)
rdata = dict(kd_bayar=invoice.kode)
if not save_departemen_route:
return dict(code=-32603,
message='Gagal menambahkan Invoice',
data=rdata)
return dict(code=0,
message='Sukses menambahkan Invoice',
data=rdata)
@jsonrpc_method(method='get_payment', endpoint='api-webr')
def get_payment(request, data):
"""
Digunakan untuk informasi pembayaran
:param request:
:param data:
- kd_bayar
:return:
- ntp
- ntb
- pembayaran_ke
- bunga
- bayar
- tgl_bayar
- jatuh_tempo
- bank_id
- channel_id
"""
auth_from_rpc(request)
get_mandatory(data, ['kd_bayar'])
row_invoice = DBSession.query(ARInvoice).filter_by(kode=data['kd_bayar']).first()
if not row_invoice:
raise JsonRpcBillNotFoundError
row_payment = DBSession.query(ARSspd.ntp, ARSspd.pembayaran_ke, ARSspd.bunga,
ARSspd.bayar, ARSspd.tgl_bayar, ARInvoice.jatuh_tempo,
ARSspd.ntb, ARSspd.bank_id, ARSspd.channel_id).\
join(ARInvoice, ARInvoice.id == ARSspd.arinvoice_id).\
filter(ARInvoice.kode==data['kd_bayar']).\
order_by(ARSspd.pembayaran_ke).all()
if not row_payment:
raise JsonRpcPaymentNotFoundError
rdata = []
for k in row_payment:
d = dict(
kd_bayar = data['kd_bayar'],
ntp = k.ntp.strip(),
pembayaran_ke = k.pembayaran_ke,
bunga = k.bunga,
bayar = k.bayar,
tgl_bayar = ymd(k.tgl_bayar),
jatuh_tempo = ymd(k.jatuh_tempo),
ntb = k.ntb.strip(),
bank_id = k.bank_id,
channel_id = k.channel_id,
)
rdata.append(d)
message = ""
return dict(code=0,
message=message,
data=rdata)
@jsonrpc_method(method='send_payment', endpoint='api-webr')
def send_payment(request, data):
"""
Digunakan untuk Scheduler pengiriman data pembayaran
:param request:
:param data:
- url
- token
:return:
-
"""
auth_from_rpc(request)
# get_mandatory(data, ['url','token'])
ws_url = data['url']
token = data['token']
datar = []
row_payment = DBSession.query(
ARSspd.ntp, ARSspd.pembayaran_ke,
ARSspd.bunga, ARSspd.bayar, ARSspd.tgl_bayar,
ARSspd.ntb, ARSspd.bank_id, ARSspd.channel_id,
ARInvoice.kode.label("kd_bayar"), ARInvoice.jatuh_tempo,
DepartemenRoute.id).\
join(DepartemenRoute, DepartemenRoute.ar_invoice_id == ARSspd.arinvoice_id).\
join(ARInvoice, ARInvoice.id == ARSspd.arinvoice_id).\
filter(DepartemenRoute.status==0).\
order_by(ARSspd.pembayaran_ke).all()
if row_payment:
for k in row_payment:
responsetxt = None
d = dict(
kd_bayar = k.kd_bayar,
ntp = k.ntp,
pembayaran_ke = k.pembayaran_ke,
bunga = k.bunga,
bayar = k.bayar,
tgl_bayar = ymd(k.tgl_bayar),
jatuh_tempo = ymd(k.jatuh_tempo),
ntb = k.ntb,
bank_id = k.bank_id,
channel_id = k.channel_id,
token = token
)
# print('>>>>>>>>>>> DEBUG DATA PAYMENT',d)
response = requests.post(ws_url, data=json.dumps(d), verify=False)
if response.status_code != 200:
continue
# try:
# responsetxt = json.loads(response.text)
# if 'result' in responsetxt and responsetxt['result'] != 'success':
# continue
# except:
# continue
# Save Departemen_Route
values = dict(id=k.id,status=1)
row = DepartemenRoute.get_by_id(data['id'])
save_departemen_route(request, values, row)
del d['token']
datar.append(d)
return dict(code=0,
message="Send Payment Success",
data=datar,
)
\ No newline at end of file
<html metal:use-macro="load: base.pt">
<div metal:fill-slot="content">
<style>
h4 {
font-weight:bold;
text-align:center;
color: #15915b;
}
.wraplabel {
border:1px solid #15915b;
border-radius: 5px;
-webkit-border-radius: 5px;
-moz-border-radius: 5px;
padding:10px;
margin-top:10px;
margin-bottom:20px;
}
.labeltab {
color:#264184;
font-weight:bold;
font-size:16px;
}
.textlabel {
display:block;
text-align:right;
color:#005500;
font-weight:bold;
}
.wrapchart {
border:1px solid #c4c4c4;
padding:0px;
margin-top:10px;
margin-bottom:20px;
}
.table {
font-size: 12px;
margin-top: 10px;
margin-bottom: 20px;
}
.table th {
background-color:#ddebf6;
}
.no-padding {
padding:0px;
}
.wrapopd {
border:1px solid #c4c4c4;
min-height:120px;
padding-top:5px;
padding-bottom:5px;
}
.kodeopd {
display:block;
color:#264184;
font-size:120%;
font-weight:bold;
}
.namaopd {
display:block;
color:#264184;
font-weight:500;
}
.jmlopd {
display:block;
font-size:120%;
color:#264184;
font-weight:bold;
text-align:right;
position: absolute;
bottom: 5px;
right: 10px;
}
</style>
<!-- <div class="well"> -->
<!-- <h1>SISTEM PENDAPATAN TERPADU</h1> -->
<!-- <p><img src="/static/img/logo-sipandu-pemda-bjb.png" class="img-float img-thumbnail"/> -->
<!-- Selamat datang di aplikasi SIPANDU -->
<!-- Main component for a primary marketing message or call to action -->
<div class="well">
<h1>SISTEM PENDAPATAN TERPADU</h1>
<!--p><img src="/static/img/logo-pemda-small_old.png" class="img-float img-thumbnail"/-->
<p><img src="/static/img/logo-sipandu-pemda-bjb.png" class="img-float img-thumbnail"/>
Selamat datang di aplikasi SIPANDU
<p>SIPANDU merupakan sub sistem dari aplikasi i-SIPKD yang bertujuan
meningkatkan pelayanan kepada masyarakat seluruh Provinsi Jawa Barat
khususnya dalam melayani registrasi pembayaran Pajak Daerah Provinsi yang
terdiri dari:</p>
<p>
<ul>
<li>Pajak Kendaraan Bermotor</li>
<li>Pajak Bahan Bakar Kendaraan Bermotor </li>
<li>Hibah Masyarakat/Lembaga Swasta</li>
<li>Pendapatan Lainnya</li>
</ul>
</p>
<p>Aplikasi Sistem Pendapatan Terpadu ini terselenggara atas kerjasama:</p>
<ul>
<li>Pemerintah Provinsi Jawa Barat,</li>
<li>PT. Bank Pembangunan Daerah Jawa Barat dan Banten, Tbk (Bank BJB)</li>
<!--li>Kepolisian Daerah Jawa Barat,</li>
<li>PT. Jasa Raharja Persero</li-->
<!-- <p>SIPANDU merupakan sub sistem dari aplikasi i-SIPKD yang bertujuan -->
<!-- meningkatkan pelayanan kepada masyarakat seluruh Provinsi Jawa Barat -->
<!-- khususnya dalam melayani registrasi pembayaran Pajak Daerah Provinsi yang -->
<!-- terdiri dari:</p> -->
<!-- <p> -->
<!-- <ul> -->
<!-- <li>Pajak Kendaraan Bermotor</li> -->
<!-- <li>Pajak Bahan Bakar Kendaraan Bermotor </li> -->
<!-- <li>Hibah Masyarakat/Lembaga Swasta</li> -->
<!-- <li>Pendapatan Lainnya</li> -->
<!-- </ul> -->
<!-- </p> -->
<!-- <p>Aplikasi Sistem Pendapatan Terpadu ini terselenggara atas kerjasama:</p> -->
<!-- <ul> -->
<!-- <li>Pemerintah Provinsi Jawa Barat,</li> -->
<!-- <li>PT. Bank Pembangunan Daerah Jawa Barat dan Banten, Tbk (Bank BJB)</li> -->
</div><!--well-->
<!-- </div> -->
<h4>REALISASI PENDAPATAN DAERAH TAHUN ${dates['year']}</h4>
<div class="col-md-12">
<div class="col-md-3">
<div class="wraplabel">
<font class="labeltab">Tahun ini</font><br>
<font class="textlabel">${'{:n}'.format(data['tabular']['tahun']['q'])}</font>
<font class="textlabel">${'{:n}'.format(data['tabular']['tahun']['n'])}</font>
</div>
</div>
<div class="col-md-3">
<div class="wraplabel">
<font class="labeltab">Bulan ini</font>
<font class="textlabel">${'{:n}'.format(data['tabular']['bulan']['q'])}</font>
<font class="textlabel">${'{:n}'.format(data['tabular']['bulan']['n'])}</font>
</div>
</div>
<div class="col-md-3">
<div class="wraplabel">
<font class="labeltab">Minggu ini</font>
<font class="textlabel">${'{:n}'.format(data['tabular']['minggu']['q'])}</font>
<font class="textlabel">${'{:n}'.format(data['tabular']['minggu']['n'])}</font>
</div>
</div>
<div class="col-md-3">
<div class="wraplabel">
<font class="labeltab">Hari ini</font>
<font class="textlabel">${'{:n}'.format(data['tabular']['hari']['q'])}</font>
<font class="textlabel">${'{:n}'.format(data['tabular']['hari']['n'])}</font>
</div>
</div>
</div>
<div class="col-md-12">
<div class="col-md-7">
<font class="labeltab">Perkembangan Realisasi Pendapatan Daerah tahun ${dates['year']}</font><br>
<div class="clearfix"></div>
<canvas id="chart" class="wrapchart">
</canvas>
</div>
<div class="col-md-5">
<font class="labeltab">10 Penerimaan OPD Tertinggi Periode ${dates['day'].strftime('%d-%m-%Y')}</font><br>
<div class="clearfix"></div>
<table class="table table-bordered">
<thead>
<tr>
<th scope="col">Peringkat</th>
<th scope="col">Upd</th>
<th scope="col">Nominal</th>
</tr>
</thead>
<tbody>
<tal:block tal:repeat="sopd data['sopd']">
<tr>
<td>${sopd['peringkat']}</td>
<td>${sopd['upd']}</td>
<td>${'{:n}'.format(sopd['nominal'])}</td>
</tr>
</tal:block>
</tbody>
</table>
</div>
</div>
<div class="col-md-12">
<tal:block tal:repeat="opd data['opd']">
<div class="col-md-3 wrapopd">
<font class="kodeopd">${opd['kode']}</font>
<font class="namaopd">${opd['unit']}</font>
<font class="jmlopd">${'{:n}'.format(opd['jumlah'])}</font>
</div>
</tal:block>
</div>
<script type="text/javascript" src="/static/js/Chart.min.js"></script>
<script type="text/javascript" src="/static/js/jquery-2.1.1.min.js"></script>
<script>
$(document).ready(function () {
//CHART
Chart.pluginService.register({
beforeRender: function (chart) {
if (chart.config.options.showAllTooltips) {
// create an array of tooltips
// we can't use the chart tooltip because there is only one tooltip per chart
chart.pluginTooltips = [];
chart.config.data.datasets.forEach(function (dataset, i) {
chart.getDatasetMeta(i).data.forEach(function (sector, j) {
chart.pluginTooltips.push(new Chart.Tooltip({
_chart: chart.chart,
_chartInstance: chart,
_data: chart.data,
_options: chart.options.tooltips,
_active: [sector]
}, chart));
});
});
// turn off normal tooltips
chart.options.tooltips.enabled = false;
}
},
afterDraw: function (chart, easing) {
if (chart.config.options.showAllTooltips) {
// we don't want the permanent tooltips to animate, so don't do anything till the animation runs atleast once
if (!chart.allTooltipsOnce) {
if (easing !== 1)
return;
chart.allTooltipsOnce = true;
}
// turn on tooltips
chart.options.tooltips.enabled = true;
Chart.helpers.each(chart.pluginTooltips, function (tooltip) {
tooltip.initialize();
tooltip.update();
// we don't actually need this since we are not animating tooltips
tooltip.pivot();
tooltip.transition(easing).draw();
});
chart.options.tooltips.enabled = false;
}
}
});
//BAR
var config = {
type: 'bar',
data: {
labels: ['Jan','Feb','Mar','Apr','Mei','Jun','Jul','Agt','Sep','Okt','Nov','Des'],
datasets: [{
label: 'Transaksi',
backgroundColor: "#264184",
borderColor: "#264184",
data: ${data['chart']['q']},
},
{
label: 'Nominal',
backgroundColor: "#15915b",
borderColor: "#15915b",
data: ${str(data['chart']['n']).replace('L','')},
}]
},
options: {
responsive: true,
showAllTooltips: false,
tooltips: {
enabled: true,
callbacks: {
title: function(tooltipItem, data) {
return '';
},
label: function(tooltipItem, data) {
var label = data.labels[tooltipItem.index];
var val = data.datasets[tooltipItem.datasetIndex].data[tooltipItem.index];
return val;
},
labelTextColor: function(tooltipItem, data) {
return 'rgba(0,0,0,0.8)';
},
displayColors: false,
borderWidth: 0,
},
backgroundColor: "rgba(0, 0, 0, 0)",
titleFontSize: 11,
mode: 'point'
},
hover: {
mode: 'nearest',
intersect: true
},
scales: {
xAxes: [{
display: true,
scaleLabel: {
display: false,
},
gridLines: {
color: "rgba(0, 0, 0, 0)",
}
}],
yAxes: [{
display: true,
scaleLabel: {
display: false,
labelString: 'Value'
},
}]
},
elements: {
line: {
tension: 0
}
}
}
};
var ctx = document.getElementById('chart').getContext('2d');
BAR = new Chart(ctx, config);
});
</script>
</div>
</html>
......@@ -12,9 +12,10 @@ requires=['pyramid>=1.5a2<=1.6a1',
'transaction',
'pyramid_tm',
'pyramid_debugtoolbar',
'zope.sqlalchemy',
'zope.sqlalchemy==1.0',
'waitress',
'ziggurat-foundations==0.5.6',
'cryptacular==1.4.1'
'colander',
'deform>=2.0a2',
'pyramid_chameleon',
......@@ -25,9 +26,11 @@ requires=['pyramid>=1.5a2<=1.6a1',
'sqlalchemy-datatables==0.1.6',
'recaptcha-client',
'pyJasper',
'informixdb',
'informixdb==2.5',
'z3c.rml',
'xlrd',
'pyramid_rpc',
'requests'
]
if sys.argv[1:] and sys.argv[1] == 'develop-use-pip':
......
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!