Commit 50c37130 by aagusti

update

1 parent 8518e656
...@@ -11,7 +11,7 @@ debug_notfound = false ...@@ -11,7 +11,7 @@ debug_notfound = false
debug_routematch = false debug_routematch = false
debug_templates = true debug_templates = true
default_locale_name = en default_locale_name = en
sqlalchemy.url = postgresql://aagusti:a@127.0.0.1/esipkd sqlalchemy.url = postgresql://aagusti:a@127.0.0.1/aagusti
pyramid.includes = pyramid.includes =
pyramid_debugtoolbar pyramid_debugtoolbar
pyramid_tm pyramid_tm
...@@ -22,13 +22,15 @@ session.type = ext:database ...@@ -22,13 +22,15 @@ session.type = ext:database
session.secret = s0s3cr3t session.secret = s0s3cr3t
session.cookie_expires = true session.cookie_expires = true
session.key = WhatEver session.key = WhatEver
session.url = postgresql://aagusti:a@127.0.0.1/esipkd session.url = postgresql://aagusti:a@127.0.0.1/aagusti
session.timeout = 3000 session.timeout = 3000
session.lock_dir = %(here)s/tmp session.lock_dir = %(here)s/tmp
timezone = Asia/Jakarta timezone = Asia/Jakarta
localization = id_ID.UTF-8 localization = id_ID.UTF-8
static_files = upload_data
[server:main] [server:main]
use = egg:waitress#main use = egg:waitress#main
host = 0.0.0.0 host = 0.0.0.0
......
import sys
import locale import locale
from pyramid.config import Configurator from pyramid.config import Configurator
from pyramid_beaker import session_factory_from_settings from pyramid_beaker import session_factory_from_settings
...@@ -19,8 +21,10 @@ from .models import ( ...@@ -19,8 +21,10 @@ from .models import (
DBSession, DBSession,
Base, Base,
init_model, init_model,
Route
) )
from .tools import DefaultTimeZone
from .tools import DefaultTimeZone, get_months
# http://stackoverflow.com/questions/9845669/pyramid-inverse-to-add-notfound-viewappend-slash-true # http://stackoverflow.com/questions/9845669/pyramid-inverse-to-add-notfound-viewappend-slash-true
class RemoveSlashNotFoundViewFactory(object): class RemoveSlashNotFoundViewFactory(object):
...@@ -58,105 +62,11 @@ def add_global(event): ...@@ -58,105 +62,11 @@ def add_global(event):
def get_title(request): def get_title(request):
route_name = request.matched_route.name route_name = request.matched_route.name
#return titles[route_name] return titles[route_name]
return None #return None
routes = [
('home', '/', 'Home'),
('login', '/login', 'Login'),
('logout', '/logout', None),
('forbidden', '/forbidden', 'Forbidden'),
('password', '/password', 'Change password'),
('user', '/user', 'Users'),
('user-act', '/user/{act}/act', ''),
('user-add', '/user/add', 'Add user'),
('user-edit', '/user/{id}/edit', 'Edit user'),
('user-delete', '/user/{id}/delete', 'Hapus user'),
('group', '/group', 'Group'),
('group-act', '/group/{act}/act', ''),
('group-add', '/group/add', 'Tambah Group'),
('group-edit', '/group/{id}/edit', 'Edit Group'),
('group-delete', '/group/{id}/delete', 'Hapus Group'),
('pkb', '/pkb', 'Pajak Kendaraan Bermotor'),
('pkb-add', '/pkb/add', 'Pajak Kendaraan Bermotor'),
('pap', '/pap', 'Pajak Air Permukaan'),
('pap-add', '/pap/add', 'Pajak Air Permukaan'),
('pbbkb', '/pbbkb', 'PBB-KB'),
('pbbkb-act', '/pbbkb/{act}/act', ''),
('pbbkb-add', '/pbbkb/add', 'Tambah PBB-KB'),
('pbbkb-edit', '/pbbkb/{id}/edit', 'Edit PBB-KB'),
('pbbkb-delete', '/pbbkb/{id}/delete', 'Hapus PBB-KB'),
('hibah', '/hibah', 'Hibah'),
('hibah-act', '/hibah/{act}/act', ''),
('hibah-add', '/hibah/add', 'Tambah Hibah'),
('hibah-edit', '/hibah/{id}/edit', 'Edit Hibah'),
('hibah-delete', '/hibah/{id}/delete', 'Hapus Hibah'),
('lain', '/lain', 'Lain-lain'),
('lain-add', '/lain/add', 'Tambah Lain-lain'),
('lain-edit', '/lain/{id}/edit', 'Edit Lain-lain'),
('lain-act', '/lain/{act}/act', ''),
('lain-delete', '/lain/{id}/delete', 'Hapus Lain-lain'),
('coa', '/coa', 'COA'),
('coa-act', '/coa/{act}/act', ''),
('coa-add', '/coa/add', 'Tambah COA'),
('coa-edit', '/coa/{id}/edit', 'Edit COA'),
('coa-delete', '/coa/{id}/delete', 'Hapus COA'),
('skpd', '/skpd', 'SKPD/Unit'),
('skpd-act', '/skpd/{act}/act', ''),
('skpd-add', '/skpd/add', 'Tambah SKPD/Unit'),
('skpd-edit', '/skpd/{id}/edit', 'Edit SKPD/Unit'),
('skpd-delete', '/skpd/{id}/delete', 'Hapus SKPD/Unit'),
('jabatan', '/jabatan', 'Jabatan'),
('jabatan-act', '/jabatan/{act}/act', ''),
('jabatan-add', '/jabatan/add', 'Tambah Jabatan'),
('jabatan-edit', '/jabatan/{id}/edit', 'Edit Jabatan'),
('jabatan-delete', '/jabatan/{id}/delete', 'Hapus Jabatan'),
('pegawai', '/pegawai', 'Pegawai'),
('pegawai-act', '/pegawai/{act}/act', ''),
('pegawai-add', '/pegawai/add', 'Tambah Pegawai'),
('pegawai-edit', '/pegawai/{id}/edit', 'Edit Pegawai'),
('pegawai-delete', '/pegawai/{id}/delete', 'Hapus Pegawai'),
('pajak', '/pajak', 'Pajak'),
('pajak-act', '/pajak/{act}/act', ''),
('pajak-add', '/pajak/add', 'Tambah Pajak'),
('pajak-edit', '/pajak/{id}/edit', 'Edit Pajak'),
('pajak-delete', '/pajak/{id}/delete', 'Hapus Pajak'),
('wilayah', '/wilayah', 'Wilayah'),
('wilayah-act', '/wilayah/{act}/act', ''),
('wilayah-add', '/wilayah/add', 'Tambah Wilayah'),
('wilayah-edit', '/wilayah/{id}/edit', 'Edit Wilayah'),
('wilayah-delete', '/wilayah/{id}/delete', 'Hapus Wilayah'),
('wp', '/wp', 'Wajib Pajak'),
('wp-act', '/wp/{act}/act', ''),
('wp-add', '/wp/add', 'Tambah Wajib Pajak'),
('wp-edit', '/wp/{id}/edit', 'Edit Wajib Pajak'),
('wp-delete', '/pegawai/{id}/delete', 'Hapus Wajib Pajak'),
('op', '/op', 'Objek Pajak'),
('op-act', '/op/{act}/act', ''),
('op-add', '/op/add', 'Tambah Objek Pajak'),
('op-edit', '/op/{id}/edit', 'Edit Objek Pajak'),
('op-delete', '/op/{id}/delete', 'Hapus Objek Pajak'),
]
main_title = 'esipkd' main_title = 'esipkd'
titles = {} titles = {}
for name, path, title in routes:
if title:
titles[name] = ' - '.join([main_title, title])
def main(global_config, **settings): def main(global_config, **settings):
...@@ -173,24 +83,40 @@ def main(global_config, **settings): ...@@ -173,24 +83,40 @@ def main(global_config, **settings):
locale.setlocale(locale.LC_ALL, settings['localization']) locale.setlocale(locale.LC_ALL, settings['localization'])
if 'timezone' not in settings: if 'timezone' not in settings:
settings['timezone'] = DefaultTimeZone settings['timezone'] = DefaultTimeZone
config = Configurator(settings=settings, config = Configurator(settings=settings,
root_factory='esipkd.models.RootFactory', root_factory='esipkd.models.RootFactory',
session_factory=session_factory) session_factory=session_factory)
config.include('pyramid_beaker') config.include('pyramid_beaker')
config.include('pyramid_chameleon') config.include('pyramid_chameleon')
authn_policy = AuthTktAuthenticationPolicy('sosecret', authn_policy = AuthTktAuthenticationPolicy('sosecret',
callback=group_finder, hashalg='sha512') callback=group_finder, hashalg='sha512')
authz_policy = ACLAuthorizationPolicy() authz_policy = ACLAuthorizationPolicy()
config.set_authentication_policy(authn_policy) config.set_authentication_policy(authn_policy)
config.set_authorization_policy(authz_policy) config.set_authorization_policy(authz_policy)
config.add_request_method(get_user, 'user', reify=True) config.add_request_method(get_user, 'user', reify=True)
config.add_request_method(get_title, 'title', reify=True) config.add_request_method(get_title, 'title', reify=True)
#config.add_notfound_view(RemoveSlashNotFoundViewFactory()) config.add_request_method(get_months, 'months', reify=True)
config.add_notfound_view(RemoveSlashNotFoundViewFactory())
config.add_static_view('static', 'static', cache_max_age=3600) config.add_static_view('static', 'static', cache_max_age=3600)
config.add_static_view('deform_static', 'deform:static') config.add_static_view('deform_static', 'deform:static')
for name, path, title in routes: config.add_static_view('static_files', 'static_files', cache_max_age=3600)
config.add_route(name, path) config.add_static_view('files', settings['static_files'])
config.add_static_view('js', 'js')
config.add_renderer('csv', '.tools.CSVRenderer')
routes = DBSession.query(Route.kode, Route.path, Route.nama, Route.factory).all()
for route in routes:
if route.factory and route.factory != 'None':
config.add_route(route.kode, route.path, factory= route.factory) #(route.factory).encode("utf8"))
else:
config.add_route(route.kode, route.path)
if route.nama:
titles[route.kode] = route.nama
config.scan() config.scan()
return config.make_wsgi_app() return config.make_wsgi_app()
...@@ -2,15 +2,20 @@ from datetime import datetime ...@@ -2,15 +2,20 @@ from datetime import datetime
from sqlalchemy import ( from sqlalchemy import (
Column, Column,
Integer, Integer,
SmallInteger,
Text, Text,
DateTime, DateTime,
String String,
ForeignKey,
UniqueConstraint
) )
from sqlalchemy.ext.declarative import declarative_base from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm.exc import NoResultFound from sqlalchemy.orm.exc import NoResultFound
from sqlalchemy.orm import ( from sqlalchemy.orm import (
scoped_session, scoped_session,
sessionmaker, sessionmaker,
relationship,
backref
) )
from zope.sqlalchemy import ZopeTransactionExtension from zope.sqlalchemy import ZopeTransactionExtension
import transaction import transaction
...@@ -219,59 +224,51 @@ class ExternalIdentity(ExternalIdentityMixin, Base): ...@@ -219,59 +224,51 @@ class ExternalIdentity(ExternalIdentityMixin, Base):
pass pass
class GroupRoutePermission(Base, CommonModel):
__tablename__ = 'groups_routes_permissions'
__table_args__ = {'extend_existing':True,}
route_id = Column(Integer, ForeignKey("routes.id"),nullable=False, primary_key=True)
group_id = Column(Integer, ForeignKey("groups.id"),nullable=False, primary_key=True)
routes = relationship("Route", backref=backref('routepermission'))
groups = relationship("Group",backref= backref('grouppermission'))
class Route(Base, DefaultModel):
__tablename__ = 'routes'
__table_args__ = {'extend_existing':True}
kode = Column(String(256))
nama = Column(String(256))
path = Column(String(256), nullable=False)
factory = Column(String(256))
perm_name = Column(String(16))
disabled = Column(SmallInteger, nullable=False, default=0,
server_default='0')
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),
UniqueConstraint('kode', 'route_kode_uq')
class RootFactory(object): class RootFactory(object):
def __init__(self, request): def __init__(self, request):
self.__name__ = '' self.__name__ = None
self.__acl__ = [ self.request = request
(Allow, Authenticated, 'delete'), self.__acl__ = [(Allow, 'Admin', ALL_PERMISSIONS),
(Allow, Authenticated, 'view'), (Allow, Authenticated, 'view'),]
(Allow, Authenticated, 'read'), """if self.request.user and self.request.matched_route:
(Allow, Authenticated, 'edit'), rows = DBSession.query(Group.group_name, Route.perm_name).\
(Allow, Authenticated, 'add'), join(UserGroup).join(GroupRoutePermission).join(Route).\
(Allow, Authenticated, 'delete'), filter(UserGroup.user_id==self.request.user.id,
Route.kode==self.request.matched_route.name).all()
(Allow, 'Admin', ALL_PERMISSIONS), if rows:
(Allow, 'Staff', 'view'), for r in rows:
(Allow, Everyone, 'view'), self.__acl__.append((Allow, ''.join(['g:',r.group_name]), r.perm_name))
"""
]
"""
class UserResourceFactory(object):
def __init__(self, request):
self.__acl__ = []
rid = request.matchdict.get("resource_id") or 1
if not rid:
raise HTTPNotFound()
self.resource = Resource.by_resource_id(rid)
if not self.resource:
raise HTTPNotFound()
if self.resource and request.user:
# append basic resource acl that gives all permissions to owner
self.__acl__ = self.resource.__acl__
# append permissions that current user may have for this context resource
for perm_user, perm_name in self.resource.perms_for_user(request.user):
self.__acl__.append((Allow, perm_user, perm_name,))"""
class GroupResourceFactory(object):
def __init__(self, request):
self.__acl__ = [(Allow,'Admin',ALL_PERMISSIONS),
(Allow, Everyone, 'view'),]
rid = request.matchdict.get("resource_id") or 1
if not rid:
raise HTTPNotFound()
self.resource = Resource.by_resource_id(rid)
if not self.resource:
raise HTTPNotFound()
if self.resource and request.user:
#groups = group_finder(request.user)
# append basic resource acl that gives all permissions to owner
self.__acl__ = self.resource.__acl__
# append permissions that current user may have for this context resource
for perm_group, perm_name in self.resource.perms_for_group(request.user):
self.__acl__.append((Allow, 'g:%s' % perm_group, perm_name,))
def init_model(): def init_model():
ziggurat_model_init(User, Group, UserGroup, GroupPermission, UserPermission, ziggurat_model_init(User, Group, UserGroup, GroupPermission, UserPermission,
UserResourcePermission, GroupResourcePermission, Resource, UserResourcePermission, GroupResourcePermission, Resource,
ExternalIdentity, passwordmanager=None) ExternalIdentity, passwordmanager=None)
import os
import sys
import transaction
from sqlalchemy import engine_from_config
from pyramid.paster import (
get_appsettings,
setup_logging,
)
from ..models import (
DBSession,
Route,
)
MAIN_TPL = """RouteData = [
{data}
]
"""
ROW_TPL = """\
dict(
id={id},
kode='{kode}',
nama='{nama}',
path='{path}',
perm_name='{perm_name}',
),"""
def usage(argv):
cmd = os.path.basename(argv[0])
print('usage: %s <config_uri>\n'
'(example: "%s development.ini")' % (cmd, cmd))
sys.exit(1)
def main(argv=sys.argv):
if len(argv) != 2:
usage(argv)
config_uri = argv[1]
setup_logging(config_uri)
settings = get_appsettings(config_uri)
engine = engine_from_config(settings, 'sqlalchemy.')
DBSession.configure(bind=engine)
q = DBSession.query(Route).order_by('id')
data = []
for row in q:
row_s = ROW_TPL.format(id=row.id, kode=row.kode, nama=row.nama,
path=row.path, perm_name=row.perm_name)
data.append(row_s)
data_s = '\n'.join(data)
main_s = MAIN_TPL.format(data=data_s)
print(main_s)
import os
import re import re
import transaction import base64
from ..models import DBSession from sqlalchemy import (
Table,
MetaData,
)
from sqlalchemy.schema import PrimaryKeyConstraint
from sqlalchemy.sql.expression import text
from ..models import (
Base,
BaseModel,
CommonModel,
DBSession,
User,
)
from tools import get_fullpath
SQL_TABLE = """ SQL_TABLE = """
...@@ -28,7 +42,7 @@ SELECT a.attname, ...@@ -28,7 +42,7 @@ SELECT a.attname,
FROM pg_catalog.pg_attrdef d FROM pg_catalog.pg_attrdef d
WHERE d.adrelid = a.attrelid WHERE d.adrelid = a.attrelid
AND d.adnum = a.attnum AND d.adnum = a.attnum
AND a.atthasdef), AND a.atthasdef) AS substring,
a.attnotnull, a.attnum, a.attnotnull, a.attnum,
(SELECT c.collname (SELECT c.collname
FROM pg_catalog.pg_collation c, pg_catalog.pg_type t FROM pg_catalog.pg_collation c, pg_catalog.pg_type t
...@@ -41,16 +55,14 @@ SELECT a.attname, ...@@ -41,16 +55,14 @@ SELECT a.attname,
WHERE a.attrelid = :table_id AND a.attnum > 0 AND NOT a.attisdropped WHERE a.attrelid = :table_id AND a.attnum > 0 AND NOT a.attisdropped
ORDER BY a.attnum""" ORDER BY a.attnum"""
def get_table_seq(table_name): def table_seq(table):
t = table_name.split('.') engine = DBSession.bind
if t[1:]: if table.schema:
schema = t[0]
table_name = t[1]
sql = text(SQL_TABLE_SCHEMA) sql = text(SQL_TABLE_SCHEMA)
q = engine.execute(sql, schema=schema, table_name=table_name) q = engine.execute(sql, schema=table.schema, table_name=table.name)
else: else:
sql = text(SQL_TABLE) sql = text(SQL_TABLE)
q = engine.execute(sql, table_name=table_name) q = engine.execute(sql, table_name=table.name)
r = q.fetchone() r = q.fetchone()
table_id = r.oid table_id = r.oid
sql = text(SQL_FIELDS) sql = text(SQL_FIELDS)
...@@ -64,53 +76,37 @@ def get_table_seq(table_name): ...@@ -64,53 +76,37 @@ def get_table_seq(table_name):
match = regex.search(r.substring) match = regex.search(r.substring)
return match.group(1) return match.group(1)
def set_sequence(orm, seq_name): def set_sequence(orm):
seq_name = table_seq(orm.__table__)
if not seq_name:
return
row = DBSession.query(orm).order_by('id DESC').first() row = DBSession.query(orm).order_by('id DESC').first()
last_id = row.id last_id = row and row.id or 1
seq_name = get_table_seq(orm.__tablename__)
sql = "SELECT setval('%s', %d)" % (seq_name, last_id) sql = "SELECT setval('%s', %d)" % (seq_name, last_id)
engine = DBSession.bind engine = DBSession.bind
engine.execute(sql) engine.execute(sql)
def set_sequences(ORMs): def split_tablename(tablename):
for orm in ORMs: t = tablename.split('.')
set_sequence(orm) if t[1:]:
schema = t[0]
tablename = t[1]
else:
schema = None
return schema, tablename
def get_pkeys(table): def get_pkeys(table):
r = [] r = []
for c in table.constraints: for c in table.constraints:
if c.__class__ is not PrimaryKeyConstraint: if c.__class__ is PrimaryKeyConstraint:
continue
for col in c: for col in c:
r.append(col.name) r.append(col.name)
return r return r
return r
def execute(engine, sql_file):
def insert_(engine, fixtures): sql_file_ = get_fullpath(sql_file)
session_factory = sessionmaker(bind=engine) f = open(sql_file_)
session = session_factory() sql = f.read()
metadata = MetaData(engine) f.close()
sequences = [] engine.execute(sql)
for tablename, data in fixtures:
table = Table(tablename, metadata, autoload=True)
class T(Base, BaseModel):
__table__ = table
keys = get_pkeys(table)
for d in data:
filter_ = {}
for key in keys:
val = d[key]
filter_[key] = val
q = session.query(T).filter_by(**filter_)
if q.first():
continue
u = T()
u.from_dict(d)
m = session.add(u)
seq_name = get_table_seq(tablename)
if seq_name:
sequences.append((T, seq_name))
session.commit()
set_sequences(sequences)
File mode changed
AppsData = [
"""dict(
id=1,
kode='admin',
nama='Administrator',
tahun=2014,
),
dict(
id=2,
kode='gaji',
nama='Gaji Pegawai dan Potongan',
tahun=None,
),
dict(
id=3,
kode='eis',
nama='Eksekutif Summary',
tahun=None,
),
dict(
id=4,
kode='skpd',
nama='Penatausahaan dan Akuntansi SKPD',
tahun=2015,
),
dict(
id=5,
kode='anggaran',
nama='Anggaran',
tahun=2015,
),
dict(
id=6,
kode='tu-skpd',
nama='Penatausahaan SKPD',
tahun=2015,
),
dict(
id=7,
kode='tu-ppkd',
nama='Penatausahaan PPKD',
tahun=2015,
),
dict(
id=8,
kode='ak-ppkd',
nama='Akuntasi PPKD',
tahun=2015,
),
dict(
id=9,
kode='aset',
nama='Aset',
tahun=2015,
),
"""
]
UserData = [
dict(
id=1,
email='admin@local',
user_name='admin',
password='admin',
status=1,
),
dict(
id=2,
email='anonymous@local',
user_name='anonymous',
status=0,
),
]
import re from types import DictType
import sys
from sqlalchemy import ( from sqlalchemy import (
Table, Table,
MetaData, MetaData,
) )
from sqlalchemy.orm import sessionmaker from data.user import UserData
from sqlalchemy.schema import PrimaryKeyConstraint from data.routes import RouteData
from sqlalchemy.sql.expression import text from data.apps import AppsData
import transaction from DbTools import (
get_pkeys,
execute,
set_sequence,
split_tablename,
)
from ..models import ( from ..models import (
Base, Base,
BaseModel, BaseModel,
...@@ -18,122 +22,16 @@ from ..models import ( ...@@ -18,122 +22,16 @@ from ..models import (
fixtures = [ fixtures = [
('users', [ ('users', UserData),
dict( ('routes', RouteData),
id=0, #('admin.apps', AppsData),
email='anonymous@local',
user_name='anonymous',
status=0,
),
dict(
id=1,
email='admin@local',
user_name='admin',
password='admin',
status=1,
),
]),
] ]
SQL_TABLE = """
SELECT c.oid, n.nspname, c.relname
FROM pg_catalog.pg_class c
LEFT JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace
WHERE c.relname = :table_name
AND pg_catalog.pg_table_is_visible(c.oid)
ORDER BY 2, 3
"""
SQL_TABLE_SCHEMA = """
SELECT c.oid, n.nspname, c.relname
FROM pg_catalog.pg_class c
LEFT JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace
WHERE c.relname = :table_name
AND n.nspname = :schema
ORDER BY 2, 3
"""
SQL_FIELDS = """
SELECT a.attname,
pg_catalog.format_type(a.atttypid, a.atttypmod),
(SELECT substring(pg_catalog.pg_get_expr(d.adbin, d.adrelid) for 128)
FROM pg_catalog.pg_attrdef d
WHERE d.adrelid = a.attrelid
AND d.adnum = a.attnum
AND a.atthasdef),
a.attnotnull, a.attnum,
(SELECT c.collname
FROM pg_catalog.pg_collation c, pg_catalog.pg_type t
WHERE c.oid = a.attcollation
AND t.oid = a.atttypid
AND a.attcollation <> t.typcollation) AS attcollation,
NULL AS indexdef,
NULL AS attfdwoptions
FROM pg_catalog.pg_attribute a
WHERE a.attrelid = :table_id AND a.attnum > 0 AND NOT a.attisdropped
ORDER BY a.attnum"""
def table_seq(table_name):
engine = DBSession.bind
t = table_name.split('.')
if t[1:]:
schema = t[0]
table_name = t[1]
sql = text(SQL_TABLE_SCHEMA)
q = engine.execute(sql, schema=schema, table_name=table_name)
else:
sql = text(SQL_TABLE)
q = engine.execute(sql, table_name=table_name)
r = q.fetchone()
table_id = r.oid
sql = text(SQL_FIELDS)
q = engine.execute(sql, table_id=table_id)
regex = re.compile("nextval\('(.*)'\:")
for r in q.fetchall():
print table_name, r
#sys.exit()
if not r.substring:
continue
if r.substring.find('nextval') == -1:
continue
match = regex.search(r.substring)
return match.group(1)
def set_sequence(orm):
row = DBSession.query(orm).order_by('id DESC').first()
last_id = row.id
seq_name = table_seq(orm.__table__.name)
sql = "SELECT setval('%s', %d)" % (seq_name, last_id)
engine = DBSession.bind
engine.execute(sql)
def insert(): def insert():
engine = DBSession.bind insert_(fixtures)
tablenames = insert_(engine, fixtures)
metadata = MetaData(engine)
for item in fixtures:
tablename = item[0]
if tablename not in tablenames:
continue
class T(Base):
__table__ = Table(tablename, metadata, autoload=True)
set_sequence(T)
transaction.commit()
def get_pkeys(table):
r = []
for c in table.constraints:
if c.__class__ is not PrimaryKeyConstraint:
continue
for col in c:
r.append(col.name)
return r
def insert_(engine, fixtures): def insert_(fixtures):
session_factory = sessionmaker(bind=engine) engine = DBSession.bind
session = session_factory()
metadata = MetaData(engine) metadata = MetaData(engine)
tablenames = [] tablenames = []
for tablename, data in fixtures: for tablename, data in fixtures:
...@@ -141,11 +39,17 @@ def insert_(engine, fixtures): ...@@ -141,11 +39,17 @@ def insert_(engine, fixtures):
T = User T = User
table = T.__table__ table = T.__table__
else: else:
table = Table(tablename, metadata, autoload=True) schema, tablename_ = split_tablename(tablename)
table = Table(tablename_, metadata, autoload=True, schema=schema)
class T(Base, BaseModel, CommonModel): class T(Base, BaseModel, CommonModel):
__table__ = table __table__ = table
if type(data) == DictType:
q = session.query(T).limit(1) options = data['options']
data = data['data']
else:
options = []
if 'insert if not exists' not in options:
q = DBSession.query(T).limit(1)
if q.first(): if q.first():
continue continue
tablenames.append(tablename) tablenames.append(tablename)
...@@ -155,13 +59,26 @@ def insert_(engine, fixtures): ...@@ -155,13 +59,26 @@ def insert_(engine, fixtures):
for key in keys: for key in keys:
val = d[key] val = d[key]
filter_[key] = val filter_[key] = val
q = session.query(T).filter_by(**filter_) q = DBSession.query(T).filter_by(**filter_)
if q.first(): if q.first():
continue continue
tbl = T() tbl = T()
tbl.from_dict(d) tbl.from_dict(d)
if tablename == 'users' and 'password' in d: if tablename == 'users' and 'password' in d:
tbl.password = d['password'] tbl.password = d['password']
m = session.add(tbl) DBSession.add(tbl)
session.commit() DBSession.flush()
return tablenames update_sequence(tablenames)
# Perbaharui nilai sequence
def update_sequence(tablenames):
engine = DBSession.bind
metadata = MetaData(engine)
for item in fixtures:
tablename = item[0]
if tablename not in tablenames:
continue
schema, tablename = split_tablename(tablename)
class T(Base):
__table__ = Table(tablename, metadata, autoload=True, schema=schema)
set_sequence(T)
import os import os
import sys import sys
import transaction import transaction
from sqlalchemy import (
from sqlalchemy import engine_from_config engine_from_config,
select,
)
from sqlalchemy.schema import CreateSchema
from pyramid.paster import ( from pyramid.paster import (
get_appsettings, get_appsettings,
setup_logging, setup_logging,
...@@ -18,6 +20,7 @@ from ..models import ( ...@@ -18,6 +20,7 @@ from ..models import (
from ..models.isipkd import * from ..models.isipkd import *
import initial_data import initial_data
from tools import mkdir
ALEMBIC_CONF = """ ALEMBIC_CONF = """
...@@ -68,6 +71,17 @@ def usage(argv): ...@@ -68,6 +71,17 @@ def usage(argv):
'(example: "%s development.ini")' % (cmd, cmd)) '(example: "%s development.ini")' % (cmd, cmd))
sys.exit(1) sys.exit(1)
def create_schema(engine, schema):
sql = select([('schema_name')]).\
select_from('information_schema.schemata').\
where("schema_name = '%s'" % schema)
q = engine.execute(sql)
if not q.fetchone():
engine.execute(CreateSchema(schema))
def create_schemas(engine):
for schema in ['efiling', 'admin', 'aset', 'eis', 'gaji', 'apbd']:
create_schema(engine, schema)
def main(argv=sys.argv): def main(argv=sys.argv):
if len(argv) != 2: if len(argv) != 2:
...@@ -75,6 +89,7 @@ def main(argv=sys.argv): ...@@ -75,6 +89,7 @@ def main(argv=sys.argv):
config_uri = argv[1] config_uri = argv[1]
setup_logging(config_uri) setup_logging(config_uri)
settings = get_appsettings(config_uri) settings = get_appsettings(config_uri)
mkdir(settings['static_files'])
# Create Ziggurat tables # Create Ziggurat tables
alembic_ini_file = 'alembic.ini' alembic_ini_file = 'alembic.ini'
if not os.path.exists(alembic_ini_file): if not os.path.exists(alembic_ini_file):
...@@ -92,5 +107,7 @@ def main(argv=sys.argv): ...@@ -92,5 +107,7 @@ def main(argv=sys.argv):
engine = engine_from_config(settings, 'sqlalchemy.') engine = engine_from_config(settings, 'sqlalchemy.')
DBSession.configure(bind=engine) DBSession.configure(bind=engine)
init_model() init_model()
create_schemas(engine)
Base.metadata.create_all(engine) Base.metadata.create_all(engine)
initial_data.insert() initial_data.insert()
transaction.commit()
import os
import sys
from ..tools import get_settings
def is_live(pid):
try:
os.kill(pid, 0)
except OSError:
return
return True
def get_pid(pidfile):
try:
f = open(pidfile,'r')
pid_int = int(f.read().split()[0])
f.close()
return pid_int
except IOError:
return
except ValueError:
return
except IndexError:
return
def get_pid_file(pid_name=None):
if not pid_name:
pid_name = os.path.split(sys.argv[0])[-1]
pid_name = os.path.splitext(pid_name)[0]
settings = get_settings()
dir_path = settings['session.lock_dir']
return os.path.join(settings['session.lock_dir'], pid_name)
def make_pid(pid_file):
pid = get_pid(pid_file)
if pid and is_live(pid):
msg = 'PID saya {pid} masih ada.'.format(pid=pid)
print(msg)
sys.exit()
pid = os.getpid()
f = open(pid_file, 'w')
f.write(str(pid))
f.close()
return pid
def one_pid():
pid_file = get_pid_file()
make_pid(pid_file)
return pid_file
def mkdir(dir_name):
if not os.path.exists(dir_name):
os.makedirs(dir_name)
def get_fullpath(filename):
dir_name = os.path.split(__file__)[0]
return os.path.join(dir_name, filename)
...@@ -3,8 +3,12 @@ import re ...@@ -3,8 +3,12 @@ import re
import json import json
import urllib2 import urllib2
import urllib import urllib
from email.utils import parseaddr import csv, codecs, cStringIO
import colander import colander
import locale
import pytz
from email.utils import parseaddr
from types import ( from types import (
IntType, IntType,
LongType, LongType,
...@@ -13,10 +17,17 @@ from datetime import ( ...@@ -13,10 +17,17 @@ from datetime import (
datetime, datetime,
timedelta, timedelta,
) )
import locale
import pytz
from pyramid.threadlocal import get_current_registry from pyramid.threadlocal import get_current_registry
STATUS = (
(1, 'Aktif'),
(0, 'Inaktif'),
)
SUMMARIES = (
(1, 'Header'),
(0, 'Detail'),
)
################ ################
# Phone number # # Phone number #
...@@ -126,6 +137,284 @@ def create_now(): ...@@ -126,6 +137,284 @@ def create_now():
tz = get_timezone() tz = get_timezone()
return datetime.now(tz) return datetime.now(tz)
def date_from_str(value):
separator = None
value = value.split()[0] # dd-mm-yyyy HH:MM:SS
for s in ['-', '/']:
if value.find(s) > -1:
separator = s
break
if separator:
t = map(lambda x: int(x), value.split(separator))
y, m, d = t[2], t[1], t[0]
if d > 999: # yyyy-mm-dd
y, d = d, y
else: # if len(value) == 8: # yyyymmdd
y, m, d = int(value[:4]), int(value[4:6]), int(value[6:])
return date(y, m, d)
def dmy(tgl):
return tgl.strftime('%d-%m-%Y')
def dmyhms(t):
return t.strftime('%d-%m-%Y %H:%M:%S')
def next_month(year, month):
if month == 12:
month = 1
year += 1
else:
month += 1
return year, month
def best_date(year, month, day):
try:
return date(year, month, day)
except ValueError:
last_day = calendar.monthrange(year, month)[1]
return date(year, month, last_day)
def next_month_day(year, month, day):
year, month = next_month(year, month)
return best_date(year, month, day)
################
# Months #
################
BULANS = (
('01', 'Januari'),
('02', 'Februari'),
('03', 'Maret'),
('04', 'April'),
('05', 'Mei'),
('06', 'Juni'),
('07', 'Juli'),
('08', 'Agustus'),
('09', 'September'),
('10', 'Oktober'),
('11', 'November'),
('12', 'Desember'),
)
def get_months(request):
return BULANS
def email_validator(node, value):
name, email = parseaddr(value)
if not email or email.find('@') < 0:
raise colander.Invalid(node, 'Invalid email format')
def row2dict(row):
d = {}
for column in row.__table__.columns:
d[column.name] = str(getattr(row, column.name))
return d
def _upper(chain):
ret = chain.upper()
if ret:
return ret
else:
return chain
def clean(s):
r = ''
for ch in s:
if ch not in string.printable:
ch = ''
r += ch
return r
def xls_reader(filename, sheet):
workbook = xlrd.open_workbook(filename)
worksheet = workbook.sheet_by_name(sheet)
num_rows = worksheet.nrows - 1
num_cells = worksheet.ncols - 1
curr_row = -1
csv = []
while curr_row < num_rows:
curr_row += 1
row = worksheet.row(curr_row)
curr_cell = -1
txt = []
while curr_cell < num_cells:
curr_cell += 1
# Cell Types: 0=Empty, 1=Text, 2=Number, 3=Date, 4=Boolean, 5=Error, 6=Blank
cell_type = worksheet.cell_type(curr_row, curr_cell)
cell_value = worksheet.cell_value(curr_row, curr_cell)
if cell_type==1 or cell_type==2:
try:
cell_value = str(cell_value)
except:
cell_value = '0'
else:
cell_value = clean(cell_value)
if curr_cell==0 and cell_value.strip()=="Tanggal":
curr_cell=num_cells
elif curr_cell==0 and cell_value.strip()=="":
curr_cell = num_cells
curr_row = num_rows
else:
txt.append(cell_value)
if txt:
csv.append(txt)
return csv
class UTF8Recoder:
"""
Iterator that reads an encoded stream and reencodes the input to UTF-8
"""
def __init__(self, f, encoding):
self.reader = codecs.getreader(encoding)(f)
def __iter__(self):
return self
def next(self):
return self.reader.next().encode("utf-8")
class UnicodeReader:
"""
A CSV reader which will iterate over lines in the CSV file "f",
which is encoded in the given encoding.
"""
def __init__(self, f, dialect=csv.excel, encoding="utf-8", **kwds):
f = UTF8Recoder(f, encoding)
self.reader = csv.reader(f, dialect=dialect, **kwds)
def next(self):
row = self.reader.next()
return [unicode(s, "utf-8") for s in row]
def __iter__(self):
return self
class UnicodeWriter:
"""
A CSV writer which will write rows to CSV file "f",
which is encoded in the given encoding.
"""
def __init__(self, f, dialect=csv.excel, encoding="utf-8", **kwds):
# Redirect output to a queue
self.queue = cStringIO.StringIO()
self.writer = csv.writer(self.queue, dialect=dialect, **kwds)
self.stream = f
self.encoder = codecs.getincrementalencoder(encoding)()
def writerow(self, row):
self.writer.writerow([s.encode("utf-8") for s in row])
# Fetch UTF-8 output from the queue ...
data = self.queue.getvalue()
data = data.decode("utf-8")
# ... and reencode it into the target encoding
data = self.encoder.encode(data)
# write to the target stream
print data
self.stream.write(data)
# empty queue
self.queue.truncate(0)
def writerows(self, rows):
for row in rows:
self.writerow(row)
class CSVRenderer(object):
def __init__(self, info):
pass
def __call__(self, value, system):
""" Returns a plain CSV-encoded string with content-type
``text/csv``. The content-type may be overridden by
setting ``request.response.content_type``."""
request = system.get('request')
if request is not None:
response = request.response
ct = response.content_type
if ct == response.default_content_type:
response.content_type = 'text/csv'
fout = io.BytesIO() #StringIO()
fcsv = csv.writer(fout, delimiter=',', quotechar='"', quoting=csv.QUOTE_MINIMAL)
#fcsv = UnicodeWriter(fout, delimiter=',', quotechar=',', quoting=csv.QUOTE_MINIMAL)
#print value.get('header', [])
fcsv.writerow(value.get('header', []))
fcsv.writerows(value.get('rows', []))
return fout.getvalue()
class SaveFile(object):
def __init__(self, dir_path):
self.dir_path = dir_path
# Awalan nama file diacak sedangkan akhirannya tidak berubah
def create_fullpath(self, ext=''):
return fullpath
def save(self, content, filename=None):
fullpath = create_fullpath()
f = open(fullpath, 'wb')
f.write(content)
f.close()
return fullpath
def get_random_string():
return ''.join(choice(ascii_uppercase + ascii_lowercase + digits) \
for _ in range(6))
def get_ext(filename):
return os.path.splitext(filename)[-1]
class Upload(SaveFile):
def __init__(self):
settings = get_settings()
dir_path = os.path.realpath(settings['static_files'])
SaveFile.__init__(self, dir_path)
def save(self, file):
input_file = file['fp']
ext = get_ext(file['filename'])
filename = '%s%s' % (uuid.uuid4(),ext)
fullpath = os.path.join(self.dir_path, filename)
output_file = open(fullpath, 'wb')
input_file.seek(0)
while True:
data = input_file.read(2<<16)
if not data:
break
output_file.write(data)
output_file.close()
return filename
def to_str(v):
typ = type(v)
print typ, v
if typ == DateType:
return dmy(v)
if typ == DateTimeType:
return dmyhms(v)
if v == 0:
return '0'
if typ in [UnicodeType, StringType]:
return v.strip()
elif typ is BooleanType:
return v and '1' or '0'
return v and str(v) or ''
def dict_to_str(d):
r = {}
for key in d:
val = d[key]
r[key] = to_str(val)
return r
# Data Tables
def _DTstrftime(chain): def _DTstrftime(chain):
ret = chain and datetime.strftime(chain, "%d-%m-%Y") ret = chain and datetime.strftime(chain, "%d-%m-%Y")
if ret: if ret:
...@@ -149,6 +438,8 @@ def _DTactive(chain): ...@@ -149,6 +438,8 @@ def _DTactive(chain):
else: else:
return chain return chain
#Captcha Response
class RecaptchaResponse(object): class RecaptchaResponse(object):
def __init__(self, is_valid, error_code=None): def __init__(self, is_valid, error_code=None):
self.is_valid = is_valid self.is_valid = is_valid
......
...@@ -11,14 +11,7 @@ from deform import (Form, ValidationFailure, widget,) ...@@ -11,14 +11,7 @@ from deform import (Form, ValidationFailure, widget,)
from ..models import (DBSession, User,) from ..models import (DBSession, User,)
from pyramid.view import notfound_view_config from pyramid.view import notfound_view_config
STATUS = (
(0, 'Inaktif'),
(1, 'Aktif'),
)
SUMMARIES = (
(1, 'Header'),
(0, 'Detail'),
)
############################################################################### ###############################################################################
# Not Found # Not Found
...@@ -43,7 +36,7 @@ def not_found(self, request): ...@@ -43,7 +36,7 @@ def not_found(self, request):
######## ########
# Home # # Home #
######## ########
@view_config(route_name='home', renderer='templates/home.pt', permission='view') @view_config(route_name='home', renderer='templates/home.pt')
def view_home(request): def view_home(request):
return dict(project='esipkd') return dict(project='esipkd')
...@@ -84,7 +77,6 @@ def view_login(request): ...@@ -84,7 +77,6 @@ def view_login(request):
login_url = request.resource_url(request.context,'login') login_url = request.resource_url(request.context,'login')
referrer = request.url referrer = request.url
if referrer == login_url: if referrer == login_url:
referrer = '/' referrer = '/'
......
from email.utils import parseaddr
from sqlalchemy import not_
from pyramid.view import (
view_config,
)
from pyramid.httpexceptions import (
HTTPFound,
)
import colander
from deform import (
Form,
widget,
ValidationFailure,
)
from ..models import (
DBSession,
Route,
Group,
GroupRoutePermission,
)
from datatables import (
ColumnDT, DataTables)
from esipkd.tools import DefaultTimeZone, _DTstrftime, _DTnumberformat, _DTactive, STATUS
SESS_ADD_FAILED = 'groupperm add failed'
SESS_EDIT_FAILED = 'groupperm edit failed'
########
# List #
########
@view_config(route_name='groupperm', renderer='templates/groupperm/list.pt',
permission='edit')
def view_list(request):
#rows = DBSession.query(User).filter(User.id > 0).order_by('email')
return dict(rows=None)
#######
# Add #
#######
def form_validator(form, value):
def err_group():
raise colander.Invalid(form,
'Group Permission sudah ada dalam database')
q = DBSession.query(GroupRoutePermission).filter(GroupRoutePermission.route_id==value['route_id'],
GroupRoutePermission.group_id==value['group_id'])
found = q.first()
if found:
err_group()
class AddSchema(colander.Schema):
group_id = colander.SchemaNode(
colander.Integer(),
widget=widget.SelectWidget(values=DBSession.query(Group.id,Group.group_name).all()),
title="Group")
route_id = colander.SchemaNode(
colander.Integer(),
widget=widget.SelectWidget(values=DBSession.query(Route.id,Route.nama).all()),
title="Route")
def get_form(request, class_form):
schema = class_form(validator=form_validator)
schema = schema.bind(daftar_status=STATUS)
schema.request = request
return Form(schema, buttons=('save','cancel'))
def save(values, groupperm, row=None):
#route = DBSession.query(Route).filter_by(id=values['route_id']).first()
#group = DBSession.query(Group).filter_by(id=values['group_id']).first()
groupperm = GroupRoutePermission()
groupperm.from_dict(values)
DBSession.add(groupperm)
DBSession.flush()
return groupperm
def save_request(values, request, row=None):
row = save(values, request.user, row)
request.session.flash('groupperm sudah disimpan.')
def route_list(request):
return HTTPFound(location=request.route_url('groupperm'))
def session_failed(request, session_name):
r = dict(form=request.session[session_name])
del request.session[session_name]
return r
@view_config(route_name='groupperm-add', renderer='templates/groupperm/add.pt',
permission='add')
def view_add(request):
form = get_form(request, AddSchema)
if request.POST:
if 'save' in request.POST:
controls = request.POST.items()
#controls['email'] = controls['email'] or controls['groupperm_name']+'@local'
try:
c = form.validate(controls)
except ValidationFailure, e:
request.session[SESS_ADD_FAILED] = e.render()
return HTTPFound(location=request.route_url('groupperm-add'))
save_request(dict(controls), request)
return route_list(request)
elif SESS_ADD_FAILED in request.session:
return session_failed(request, SESS_ADD_FAILED)
return dict(form=form.render())
########
# Edit #
########
def query_id(request):
return DBSession.query(GroupRoutePermission).filter(GroupRoutePermission.route_id==request.matchdict['id2'],
GroupRoutePermission.group_id==request.matchdict['id'])
def id_not_found(request):
msg = 'Group ID %s Route %s not found.' % (request.matchdict['id'],request.matchdict['id2'])
request.session.flash(msg, 'error')
return route_list(request)
"""@view_config(route_name='groupperm-edit', renderer='templates/groupperm/edit.pt',
permission='edit')
def view_edit(request):
row = query_id(request).first()
if not row:
return id_not_found(request)
form = get_form(request, EditSchema)
if request.POST:
if 'save' in request.POST:
controls = request.POST.items()
#controls['email'] = controls['email'] or controls['groupperm_name']+'@local'
try:
c = form.validate(controls)
except ValidationFailure, e:
request.session[SESS_EDIT_FAILED] = e.render()
return HTTPFound(location=request.route_url('groupperm-edit',
id=row.id))
save_request(dict(controls), request, row)
return route_list(request)
elif SESS_EDIT_FAILED in request.session:
return session_failed(request, SESS_EDIT_FAILED)
values = row.to_dict()
return dict(form=form.render(appstruct=values))
"""
##########
# Delete #
##########
@view_config(route_name='groupperm-delete', renderer='templates/groupperm/delete.pt',
permission='delete')
def view_delete(request):
q = query_id(request)
row = q.first()
if not row:
return id_not_found(request)
form = Form(colander.Schema(), buttons=('delete','cancel'))
if request.POST:
if 'delete' in request.POST:
msg = 'Group %s Route ID %s sudah dihapus.' % (row.groups.group_name,
row.routes.nama)
q.delete()
DBSession.flush()
request.session.flash(msg)
return route_list(request)
return dict(row=row,
form=form.render())
##########
# Action #
##########
@view_config(route_name='groupperm-act', renderer='json',
permission='read')
def view_act(request):
req = request
params = req.params
url_dict = req.matchdict
if url_dict['act']=='grid':
columns = []
columns.append(ColumnDT('group_id'))
columns.append(ColumnDT('route_id'))
columns.append(ColumnDT('group_name'))
columns.append(ColumnDT('route_name'))
query = DBSession.query(GroupRoutePermission.route_id,
GroupRoutePermission.group_id,
Route.nama.label('route_name'),
Group.group_name).\
join(Route).join(Group)
rowTable = DataTables(req, GroupRoutePermission, query, columns)
return rowTable.output_result()
...@@ -49,17 +49,9 @@ def get_periode(year=True): ...@@ -49,17 +49,9 @@ def get_periode(year=True):
else: else:
return amonth return amonth
def get_units():
q = DBSession.query(Unit.id,Unit.nama).filter(
Unit.kode.like("1.20.05.%")
).order_by(Unit.nama)
return q.all()
def get_rekenings():
q = DBSession.query(Rekening.id,Rekening.nama).filter(
Rekening.kode.like('4.3.1.03.02.%'), Rekening.is_summary==0
).filter(Rekening.is_summary==0).order_by(Rekening.nama)
return q.all()
class InformasiSchema(colander.Schema): class InformasiSchema(colander.Schema):
nama = colander.SchemaNode( nama = colander.SchemaNode(
...@@ -78,6 +70,18 @@ class AddSchema(colander.Schema): ...@@ -78,6 +70,18 @@ class AddSchema(colander.Schema):
def deferred_missing(node, kw): def deferred_missing(node, kw):
return appstruct['readonly'] return appstruct['readonly']
""" """
def get_units():
q = DBSession.query(Unit.id,Unit.nama).filter(
Unit.kode.like("1.20.05.%")
).order_by(Unit.nama)
return q.all()
def get_rekenings():
q = DBSession.query(Rekening.id,Rekening.nama).filter(
Rekening.kode.like('4.3.1.03.02.%'), Rekening.is_summary==0
).filter(Rekening.is_summary==0).order_by(Rekening.nama)
return q.all()
no_tagihan = colander.SchemaNode( no_tagihan = colander.SchemaNode(
colander.String(), colander.String(),
widget=widget.TextInputWidget(), widget=widget.TextInputWidget(),
......
...@@ -23,7 +23,7 @@ from datatables import ( ...@@ -23,7 +23,7 @@ from datatables import (
SESS_ADD_FAILED = 'Gagal tambah jabatan' SESS_ADD_FAILED = 'Gagal tambah jabatan'
SESS_EDIT_FAILED = 'Gagal edit jabatan' SESS_EDIT_FAILED = 'Gagal edit jabatan'
from ..views import STATUS from ..tools import STATUS
######## ########
# List # # List #
......
from email.utils import parseaddr from email.utils import parseaddr
from sqlalchemy import not_ from sqlalchemy import not_, func
from pyramid.view import ( from pyramid.view import (
view_config, view_config,
) )
...@@ -14,7 +14,12 @@ from deform import ( ...@@ -14,7 +14,12 @@ from deform import (
) )
from ..models import DBSession from ..models import DBSession
from ..models.isipkd import( from ..models.isipkd import(
ObjekPajak,
SubjekPajak,
Unit, Unit,
Wilayah,
Pajak,
Rekening
) )
from datatables import ( from datatables import (
...@@ -22,7 +27,7 @@ from datatables import ( ...@@ -22,7 +27,7 @@ from datatables import (
SESS_ADD_FAILED = 'Gagal tambah Objek Pajak' SESS_ADD_FAILED = 'Gagal tambah Objek Pajak'
SESS_EDIT_FAILED = 'Gagal edit Objek Pajak' SESS_EDIT_FAILED = 'Gagal edit Objek Pajak'
from ..tools import STATUS
######## ########
# List # # List #
######## ########
...@@ -35,11 +40,6 @@ def view_list(request): ...@@ -35,11 +40,6 @@ def view_list(request):
####### #######
# Add # # Add #
####### #######
def email_validator(node, value):
name, email = parseaddr(value)
if not email or email.find('@') < 0:
raise colander.Invalid(node, 'Invalid email format')
def form_validator(form, value): def form_validator(form, value):
def err_kode(): def err_kode():
raise colander.Invalid(form, raise colander.Invalid(form,
...@@ -53,11 +53,11 @@ def form_validator(form, value): ...@@ -53,11 +53,11 @@ def form_validator(form, value):
if 'id' in form.request.matchdict: if 'id' in form.request.matchdict:
uid = form.request.matchdict['id'] uid = form.request.matchdict['id']
q = DBSession.query(Unit).filter_by(id=uid) q = DBSession.query(ObjekPajak).filter_by(id=uid)
r = q.first() r = q.first()
else: else:
r = None r = None
q = DBSession.query(Unit).filter_by(kode=value['kode']) q = DBSession.query(ObjekPajak).filter_by(kode=value['kode'])
found = q.first() found = q.first()
if r: if r:
if found and found.id != r.id: if found and found.id != r.id:
...@@ -65,7 +65,7 @@ def form_validator(form, value): ...@@ -65,7 +65,7 @@ def form_validator(form, value):
elif found: elif found:
err_email() err_email()
if 'nama' in value: # optional if 'nama' in value: # optional
found = Unit.get_by_nama(value['nama']) found = ObjekPajak.get_by_nama(value['nama'])
if r: if r:
if found and found.id != r.id: if found and found.id != r.id:
err_name() err_name()
...@@ -73,29 +73,48 @@ def form_validator(form, value): ...@@ -73,29 +73,48 @@ def form_validator(form, value):
err_name() err_name()
@colander.deferred @colander.deferred
def deferred_summary(node, kw): def deferred_status(node, kw):
values = kw.get('daftar_summary', []) values = kw.get('daftar_status', [])
return widget.SelectWidget(values=values) return widget.SelectWidget(values=values)
SUMMARIES = (
(1, 'Header'),
(0, 'Detail'),
)
class AddSchema(colander.Schema): class AddSchema(colander.Schema):
unit_select = DBSession.query(Unit.id, Unit.nama).filter(Unit.level_id>2).all()
wilayah_select = DBSession.query(Wilayah.id, Wilayah.nama).filter(Wilayah.level_id>1).all()
pajak_select = DBSession.query(Pajak.id, Pajak.nama).all()
sp_select = DBSession.query(SubjekPajak.id, SubjekPajak.nama).all()
subjekpajak_id = colander.SchemaNode(
colander.Integer(),
widget=widget.SelectWidget(values=sp_select),
title="Subjek Pajak"
)
wilayah_id = colander.SchemaNode(
colander.Integer(),
widget=widget.SelectWidget(values=wilayah_select),
title="Wilayah"
)
unit_id = colander.SchemaNode(
colander.Integer(),
widget=widget.SelectWidget(values=unit_select),
title="SKPD/Unit Kerja"
)
pajak_id = colander.SchemaNode(
colander.Integer(),
widget=widget.SelectWidget(values=pajak_select),
title="Pajak"
)
kode = colander.SchemaNode( kode = colander.SchemaNode(
colander.String(), colander.String(),
) )
nama = colander.SchemaNode( nama = colander.SchemaNode(
colander.String(), colander.String(),
missing=colander.drop) missing=colander.drop,
level_id = colander.SchemaNode( title="Uraian")
colander.Integer()) status = colander.SchemaNode(
is_summary = colander.SchemaNode(
colander.Integer(), colander.Integer(),
widget=widget.SelectWidget(values=SUMMARIES), widget=widget.SelectWidget(values=STATUS),
title="Header") title="Status")
class EditSchema(AddSchema): class EditSchema(AddSchema):
id = colander.SchemaNode(colander.Integer(), id = colander.SchemaNode(colander.Integer(),
...@@ -105,13 +124,13 @@ class EditSchema(AddSchema): ...@@ -105,13 +124,13 @@ class EditSchema(AddSchema):
def get_form(request, class_form): def get_form(request, class_form):
schema = class_form(validator=form_validator) schema = class_form(validator=form_validator)
schema = schema.bind(daftar_summary=SUMMARIES) schema = schema.bind(daftar_status=STATUS)
schema.request = request schema.request = request
return Form(schema, buttons=('simpan','batal')) return Form(schema, buttons=('simpan','batal'))
def save(values, row=None): def save(values, row=None):
if not row: if not row:
row = Unit() row = ObjekPajak()
row.from_dict(values) row.from_dict(values)
#if values['password']: #if values['password']:
# row.password = values['password'] # row.password = values['password']
...@@ -156,7 +175,7 @@ def view_add(request): ...@@ -156,7 +175,7 @@ def view_add(request):
# Edit # # Edit #
######## ########
def query_id(request): def query_id(request):
return DBSession.query(Unit).filter_by(id=request.matchdict['id']) return DBSession.query(ObjekPajak).filter_by(id=request.matchdict['id'])
def id_not_found(request): def id_not_found(request):
msg = 'op ID %s not found.' % request.matchdict['id'] msg = 'op ID %s not found.' % request.matchdict['id']
...@@ -216,14 +235,19 @@ def view_act(request): ...@@ -216,14 +235,19 @@ def view_act(request):
req = request req = request
params = req.params params = req.params
url_dict = req.matchdict url_dict = req.matchdict
if url_dict['act']=='grid': if url_dict['act']=='grid':
columns = [] columns = []
columns.append(ColumnDT('id')) columns.append(ColumnDT('id'))
columns.append(ColumnDT('registrasi'))
columns.append(ColumnDT('kode')) columns.append(ColumnDT('kode'))
columns.append(ColumnDT('nama')) columns.append(ColumnDT('nama'))
columns.append(ColumnDT('level_id')) columns.append(ColumnDT('pajak'))
columns.append(ColumnDT('is_summary')) columns.append(ColumnDT('wilayah'))
query = DBSession.query(Unit) columns.append(ColumnDT('status'))
rowTable = DataTables(req, Unit, query, columns) query = DBSession.query(ObjekPajak.id, ObjekPajak.kode,ObjekPajak.nama,
Rekening.kode.label('pajak'), SubjekPajak.kode.label('registrasi'),
Wilayah.nama.label('wilayah'), ObjekPajak.status).\
join(SubjekPajak).join(Wilayah).join(Pajak).join(Rekening)
rowTable = DataTables(req, ObjekPajak, query, columns)
return rowTable.output_result() return rowTable.output_result()
...@@ -18,7 +18,7 @@ from ..models.isipkd import( ...@@ -18,7 +18,7 @@ from ..models.isipkd import(
Rekening Rekening
) )
from ..views import STATUS from ..tools import STATUS
from datatables import ( from datatables import (
ColumnDT, DataTables) ColumnDT, DataTables)
......
...@@ -19,7 +19,7 @@ from ..models.isipkd import( ...@@ -19,7 +19,7 @@ from ..models.isipkd import(
Unit Unit
) )
from ..views import STATUS from ..tools import STATUS
from datatables import ( from datatables import (
ColumnDT, DataTables) ColumnDT, DataTables)
......
from email.utils import parseaddr
from sqlalchemy import not_, func
from pyramid.view import (
view_config,
)
from pyramid.httpexceptions import (
HTTPFound,
)
import colander
from deform import (
Form,
widget,
ValidationFailure,
)
from ..models import DBSession
from ..models.isipkd import(
ObjekPajak,
SubjekPajak,
Unit,
Wilayah,
Pajak,
Rekening
)
from datatables import (
ColumnDT, DataTables)
SESS_ADD_FAILED = 'Gagal tambah Objek Pajak'
SESS_EDIT_FAILED = 'Gagal edit Objek Pajak'
from ..tools import STATUS
########
# List #
########
@view_config(route_name='sptpd', renderer='templates/sptpd/list.pt',
permission='read')
def view_list(request):
return dict(rows={})
#######
# Add #
#######
def form_validator(form, value):
def err_kode():
raise colander.Invalid(form,
'Kode sptpd %s sudah digunakan oleh ID %d' % (
value['kode'], found.id))
def err_name():
raise colander.Invalid(form,
'Uraian %s sudah digunakan oleh ID %d' % (
value['nama'], found.id))
if 'id' in form.request.matchdict:
uid = form.request.matchdict['id']
q = DBSession.query(ObjekPajak).filter_by(id=uid)
r = q.first()
else:
r = None
q = DBSession.query(ObjekPajak).filter_by(kode=value['kode'])
found = q.first()
if r:
if found and found.id != r.id:
err_kode()
elif found:
err_email()
if 'nama' in value: # sptpdtional
found = ObjekPajak.get_by_nama(value['nama'])
if r:
if found and found.id != r.id:
err_name()
elif found:
err_name()
@colander.deferred
def deferred_status(node, kw):
values = kw.get('daftar_status', [])
return widget.SelectWidget(values=values)
class AddSchema(colander.Schema):
unit_select = DBSession.query(Unit.id, Unit.nama).filter(Unit.level_id>2).all()
wilayah_select = DBSession.query(Wilayah.id, Wilayah.nama).filter(Wilayah.level_id>1).all()
pajak_select = DBSession.query(Pajak.id, Pajak.nama).all()
sp_select = DBSession.query(SubjekPajak.id, SubjekPajak.nama).all()
subjekpajak_id = colander.SchemaNode(
colander.Integer(),
widget=widget.SelectWidget(values=sp_select),
title="Subjek Pajak"
)
wilayah_id = colander.SchemaNode(
colander.Integer(),
widget=widget.SelectWidget(values=wilayah_select),
title="Wilayah"
)
unit_id = colander.SchemaNode(
colander.Integer(),
widget=widget.SelectWidget(values=unit_select),
title="SKPD/Unit Kerja"
)
pajak_id = colander.SchemaNode(
colander.Integer(),
widget=widget.SelectWidget(values=pajak_select),
title="Pajak"
)
kode = colander.SchemaNode(
colander.String(),
)
nama = colander.SchemaNode(
colander.String(),
missing=colander.drop,
title="Uraian")
status = colander.SchemaNode(
colander.Integer(),
widget=widget.SelectWidget(values=STATUS),
title="Status")
class EditSchema(AddSchema):
id = colander.SchemaNode(colander.Integer(),
missing=colander.drop,
widget=widget.HiddenWidget(readonly=True))
def get_form(request, class_form):
schema = class_form(validator=form_validator)
schema = schema.bind(daftar_status=STATUS)
schema.request = request
return Form(schema, buttons=('simpan','batal'))
def save(values, row=None):
if not row:
row = ObjekPajak()
row.from_dict(values)
#if values['password']:
# row.password = values['password']
DBSession.add(row)
DBSession.flush()
return row
def save_request(values, request, row=None):
if 'id' in request.matchdict:
values['id'] = request.matchdict['id']
print "****",values, "****", request
row = save(values, row)
request.session.flash('SPTPD %s sudah disimpan.' % row.kode)
def route_list(request):
return HTTPFound(location=request.route_url('sptpd'))
def session_failed(request, session_name):
r = dict(form=request.session[session_name])
del request.session[session_name]
return r
@view_config(route_name='sptpd-add', renderer='templates/sptpd/add.pt',
permission='add')
def view_add(request):
form = get_form(request, AddSchema)
if request.POST:
if 'simpan' in request.POST:
controls = request.POST.items()
try:
c = form.validate(controls)
except ValidationFailure, e:
request.session[SESS_ADD_FAILED] = e.render()
return HTTPFound(location=request.route_url('sptpd-add'))
save_request(dict(controls), request)
return route_list(request)
elif SESS_ADD_FAILED in request.session:
return session_failed(request, SESS_ADD_FAILED)
return dict(form=form.render())
########
# Edit #
########
def query_id(request):
return DBSession.query(ObjekPajak).filter_by(id=request.matchdict['id'])
def id_not_found(request):
msg = 'sptpd ID %s not found.' % request.matchdict['id']
request.session.flash(msg, 'error')
return route_list(request)
@view_config(route_name='sptpd-edit', renderer='templates/sptpd/edit.pt',
permission='edit')
def view_edit(request):
row = query_id(request).first()
if not row:
return id_not_found(request)
form = get_form(request, EditSchema)
if request.POST:
if 'simpan' in request.POST:
controls = request.POST.items()
try:
c = form.validate(controls)
except ValidationFailure, e:
request.session[SESS_EDIT_FAILED] = e.render()
return HTTPFound(location=request.route_url('sptpd-edit',
id=row.id))
save_request(dict(controls), request, row)
return route_list(request)
elif SESS_EDIT_FAILED in request.session:
return session_failed(request, SESS_EDIT_FAILED)
values = row.to_dict()
return dict(form=form.render(appstruct=values))
##########
# Delete #
##########
@view_config(route_name='sptpd-delete', renderer='templates/sptpd/delete.pt',
permission='delete')
def view_delete(request):
q = query_id(request)
row = q.first()
if not row:
return id_not_found(request)
form = Form(colander.Schema(), buttons=('delete','cancel'))
if request.POST:
if 'delete' in request.POST:
msg = 'sptpd ID %d %s has been deleted.' % (row.id, row.kode)
q.delete()
DBSession.flush()
request.session.flash(msg)
return route_list(request)
return dict(row=row,
form=form.render())
##########
# Action #
##########
@view_config(route_name='sptpd-act', renderer='json',
permission='read')
def view_act(request):
req = request
params = req.params
url_dict = req.matchdict
if url_dict['act']=='grid':
columns = []
columns.append(ColumnDT('id'))
columns.append(ColumnDT('registrasi'))
columns.append(ColumnDT('kode'))
columns.append(ColumnDT('nama'))
columns.append(ColumnDT('pajak'))
columns.append(ColumnDT('wilayah'))
columns.append(ColumnDT('status'))
query = DBSession.query(ObjekPajak.id, ObjekPajak.kode,ObjekPajak.nama,
Rekening.kode.label('pajak'), SubjekPajak.kode.label('registrasi'),
Wilayah.nama.label('wilayah'), ObjekPajak.status).\
join(SubjekPajak).join(Wilayah).join(Pajak).join(Rekening)
rowTable = DataTables(req, ObjekPajak, query, columns)
return rowTable.output_result()
...@@ -42,9 +42,13 @@ ...@@ -42,9 +42,13 @@
<li tal:attributes="class request.path == '/' and 'active'"><a href="/">Home</a></li> <li tal:attributes="class request.path == '/' and 'active'"><a href="/">Home</a></li>
<li tal:attributes="class request.path == '/pkb/add' and 'active'"><a href="/pkb/add">PKB</a></li> <li tal:attributes="class request.path == '/pkb/add' and 'active'"><a href="/pkb/add">PKB</a></li>
<li tal:attributes="class request.path == '/pap/add' and 'active'"><a href="/pap/add">PAP</a></li> <li tal:attributes="class request.path == '/pap/add' and 'active'"><a href="/pap/add">PAP</a></li>
<li tal:attributes="class request.path == '/sptpd' and 'active'"><a href="/sptpd">Register Bayar</a></li>
<li tal:attributes="class request.path == '/sspd' and 'active'"><a href="/sspd">Penerimaan</a></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> <li tal:attributes="class request.path == '/pbbkb' and 'active'"><a href="/pbbkb">PBB-KB</a></li>
<li tal:attributes="class request.path == '/hibah/add' and 'active'"><a href="/hibah/add">Hibah</a></li> <li tal:attributes="class request.path == '/hibah/add' and 'active'"><a href="/hibah/add">Hibah</a></li>
<li tal:attributes="class request.path == '/lain/add' and 'active'"><a href="/lain/add">P. Lainnya</a></li> <li tal:attributes="class request.path == '/lain/add' and 'active'"><a href="/lain/add">P. Lainnya</a></li-->
<li tal:condition="not request.user" tal:attributes="class request.path == '/login' and 'active'"><a href="/login">Login</a></li> <li tal:condition="not request.user" tal:attributes="class request.path == '/login' and 'active'"><a href="/login">Login</a></li>
...@@ -53,6 +57,9 @@ ...@@ -53,6 +57,9 @@
<ul class="dropdown-menu"> <ul class="dropdown-menu">
<li><a href="/user">User</a></li> <li><a href="/user">User</a></li>
<li><a href="/group">Group</a></li> <li><a href="/group">Group</a></li>
<li><a href="/usergroup">User Group</a></li>
<li><a href="/groupperm">Group Permission</a></li>
<li><a href="/skpd">SKPD/Unit</a></li> <li><a href="/skpd">SKPD/Unit</a></li>
<li><a href="/jabatan">Jabatan</a></li> <li><a href="/jabatan">Jabatan</a></li>
<li><a href="/pegawai">Pegawai</a></li> <li><a href="/pegawai">Pegawai</a></li>
......
<html metal:use-macro="load: ../base.pt">
<div metal:fill-slot="content" class="form-550">
<h3>Tambah Group Permission</h3>
<hr>
<div tal:content="structure 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 Permission ID # ${row.groups.group_name} Route ID# ${row.routes.nama} ?
</div>
</div>
<div tal:content="structure form"/>
</div>
</html>
<html metal:use-macro="load: ../base.pt">
<div metal:fill-slot="content" class="form-550">
<h3>Edit User Group</h3>
<hr>
<div tal:content="structure 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>Group Permission</h4>
<hr>
<div class="container">
<!--form class="form-inline" role="form" id="frm_upload" name="frm_upload">
<label for="upload" class="control-label">Upload:</label>
<input type="text" class="form-control" id="upload">
<button type="submit" class="btn btn-default">Upload</button>
</form-->
</div>
<p>
<table id="table1" name="table1" class="table table-bordered table-hover table-condensed" >
<thead>
<tr>
<th>Route ID</th>
<th>Group ID</th>
<th>Group</th>
<th>Route</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, mID2;
var oTable;
var iPos;
var oFormUrl = "/groupperm/";
var oTableUrl = oFormUrl+"grid/act";
$(document).ready(function () {
oTable = $('#table1').dataTable({
"sAjaxSource": oTableUrl,
"bServerSide": true,
"bProcessing": true,
"sDom": '<"toolbar">lfrtip',
"bScrollCollapse": true,
"bSort": false,
"bInfo": false,
"bFilter": false,
"bAutoWidth": false,
"bPaginate": true,
"sPaginationType": "full_numbers",
"lengthMenu": [
[10, 25, 50, -1],
[10, 25, 50, "All"]
],
"aoColumnDefs": [
{"bSearchable": false, "bVisible": false, "aTargets": [0,1]}
],
"aoColumns": [
null,
null,
null,
null
],
});
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_delete" class="btn btn btn-danger pull-left" type="button">Hapus</button>',
' &nbsp;',
'</div>',
];
var tb = tb_array.join(' ');
$("div.toolbar").html(tb);
$('#table1 tbody').on('click', 'tr', function () {
if ($(this).hasClass('selected')) {
mID = ''; mID2 = '';
$(this).removeClass('selected');
} else {
iPos = oTable.fnGetPosition(this);
var aData = oTable.fnGetData(iPos);
mID = aData[0];
mID2 = aData[1];
oTable.$('tr.selected').removeClass('selected');
$(this).addClass('selected');
}
});
$('#btn_tambah').click(function () {
window.location = oFormUrl+'add';
});
$('#btn_delete').click(function () {
if (mID) {
var hapus = confirm('Hapus data ini?');
if (hapus == true) {
window.location = oFormUrl+mID+'/'+mID2+'/delete';
};
} else {
alert('Silahkan pilih data yang akan dihapus');
}
});
});
</script>
</div>
</html>
<html metal:use-macro="load: ../base.pt">
<div metal:fill-slot="content" class="form-550">
<h3>Tambah Objek</h3>
<hr>
<div tal:content="structure 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 Objek ID #${row.id} ${row.nama} ?
</div>
</div>
<div tal:content="structure form"/>
</div>
</html>
<html metal:use-macro="load: ../base.pt">
<div metal:fill-slot="content" class="form-550">
<h3>Edit Objek</h3>
<hr>
<div tal:content="structure 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>Objek</h4>
<hr>
<div class="container">
<!--form class="form-inline" role="form" id="frm_upload" name="frm_upload">
<label for="upload" class="control-label">Upload:</label>
<input type="text" class="form-control" id="upload">
<button type="submit" class="btn btn-default">Upload</button>
</form-->
</div>
<p>
<table id="table1" name="table1" class="table table-bordered table-hover table-condensed" >
<thead>
<tr>
<th>ID</th>
<th>Registrasi</th>
<th>No. OP</th>
<th>Uraian</th>
<th>Rekening</th>
<th>Wilayah</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 = "/op/";
var oTableUrl = oFormUrl+"grid/act";
$(document).ready(function () {
oTable = $('#table1').dataTable({
"sAjaxSource": oTableUrl,
"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, -1],
[10, 25, 50, "All"]
],
"aoColumnDefs": [
{"bSearchable": false, "bVisible": false, "aTargets": [0]}
],
"aoColumns": [
null,
{"sWidth": "100px", "sClass": "left"},
{"sWidth": "50px", "sClass": "left"},
null,
{"sWidth": "100px", "sClass": "center"},
null,
{"sWidth": "40px", "sClass": "center"}
],
});
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">Print</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_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>
<html metal:use-macro="load: ../base.pt">
<div metal:fill-slot="content" class="form-550">
<h3>Tambah User Group</h3>
<hr>
<div tal:content="structure 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 user ID # ${row.user_id}group ID# ${row.group_id} ?
</div>
</div>
<div tal:content="structure form"/>
</div>
</html>
<html metal:use-macro="load: ../base.pt">
<div metal:fill-slot="content" class="form-550">
<h3>Edit User Group</h3>
<hr>
<div tal:content="structure 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>User Group</h4>
<hr>
<div class="container">
<!--form class="form-inline" role="form" id="frm_upload" name="frm_upload">
<label for="upload" class="control-label">Upload:</label>
<input type="text" class="form-control" id="upload">
<button type="submit" class="btn btn-default">Upload</button>
</form-->
</div>
<p>
<table id="table1" name="table1" class="table table-bordered table-hover table-condensed" >
<thead>
<tr>
<th>User ID</th>
<th>Group ID</th>
<th>User</th>
<th>Group</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, mID2;
var oTable;
var iPos;
var oFormUrl = "/usergroup/";
var oTableUrl = oFormUrl+"grid/act";
$(document).ready(function () {
oTable = $('#table1').dataTable({
"sAjaxSource": oTableUrl,
"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, -1],
[10, 25, 50, "All"]
],
"aoColumnDefs": [
{"bSearchable": false, "bVisible": false, "aTargets": [0,1]}
],
"aoColumns": [
null,
null,
null,
null
],
});
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_delete" class="btn btn btn-danger pull-left" type="button">Hapus</button>',
' &nbsp;',
'</div>',
];
var tb = tb_array.join(' ');
$("div.toolbar").html(tb);
$('#table1 tbody').on('click', 'tr', function () {
if ($(this).hasClass('selected')) {
mID = ''; mID2 = '';
$(this).removeClass('selected');
} else {
iPos = oTable.fnGetPosition(this);
var aData = oTable.fnGetData(iPos);
mID = aData[0];
mID2 = aData[1];
oTable.$('tr.selected').removeClass('selected');
$(this).addClass('selected');
}
});
$('#btn_tambah').click(function () {
window.location = oFormUrl+'add';
});
$('#btn_delete').click(function () {
if (mID) {
var hapus = confirm('Hapus data ini?');
if (hapus == true) {
window.location = oFormUrl+mID+'/'+mID2+'/delete';
};
} else {
alert('Silahkan pilih data yang akan dihapus');
}
});
});
</script>
</div>
</html>
<html metal:use-macro="load: ../base.pt"> <html metal:use-macro="load: ../base.pt">
<div metal:fill-slot="content" class="form-550"> <div metal:fill-slot="content" class="form-550">
<h3>Tambah Pegawai</h3> <h3>Tambah Subjek</h3>
<hr> <hr>
<div tal:content="structure form"/> <div tal:content="structure form"/>
</div> </div>
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
<h3 class="panel-title">Warning</h3> <h3 class="panel-title">Warning</h3>
</div> </div>
<div class="panel-body"> <div class="panel-body">
Hapus pegawai ID #${row.id} ${row.nama} ? Hapus Subjek ID #${row.id} ${row.nama} ?
</div> </div>
</div> </div>
......
<html metal:use-macro="load: ../base.pt"> <html metal:use-macro="load: ../base.pt">
<div metal:fill-slot="content" class="form-550"> <div metal:fill-slot="content" class="form-550">
<h3>Edit Pegawai</h3> <h3>Edit Subjek</h3>
<hr> <hr>
<div tal:content="structure form"/> <div tal:content="structure form"/>
</div> </div>
......
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
<link href="/static/datatables/extensions/TableTools/css/dataTables.tableTools.min.css" rel="stylesheet"> <link href="/static/datatables/extensions/TableTools/css/dataTables.tableTools.min.css" rel="stylesheet">
<link href="/static/datatables/media/css/dataTables.bootstrap.css" rel="stylesheet"> <link href="/static/datatables/media/css/dataTables.bootstrap.css" rel="stylesheet">
<h4>Pegawai</h4> <h4>Subjek Pajak</h4>
<hr> <hr>
<div class="container"> <div class="container">
<!--form class="form-inline" role="form" id="frm_upload" name="frm_upload"> <!--form class="form-inline" role="form" id="frm_upload" name="frm_upload">
...@@ -18,12 +18,11 @@ ...@@ -18,12 +18,11 @@
<thead> <thead>
<tr> <tr>
<th>ID</th> <th>ID</th>
<th>NIP</th> <th>NPWPD/ Registrasi</th>
<th>Nama</th> <th>Nama</th>
<th>SKPD</th> <th>Alamat</th>
<th>Jabatan</th> <th>Alamat 2</th>
<th>Status</th> <th>Status</th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
...@@ -38,7 +37,7 @@ ...@@ -38,7 +37,7 @@
var mID; var mID;
var oTable; var oTable;
var iPos; var iPos;
var oFormUrl = "/pegawai/"; var oFormUrl = "/wp/";
var oTableUrl = oFormUrl+"grid/act"; var oTableUrl = oFormUrl+"grid/act";
$(document).ready(function () { $(document).ready(function () {
oTable = $('#table1').dataTable({ oTable = $('#table1').dataTable({
......
from email.utils import parseaddr
from sqlalchemy import not_
from pyramid.view import (
view_config,
)
from pyramid.httpexceptions import (
HTTPFound,
)
import colander
from deform import (
Form,
widget,
ValidationFailure,
)
from ..models import (
DBSession,
User,
Group,
UserGroup,
)
from datatables import (
ColumnDT, DataTables)
from esipkd.tools import DefaultTimeZone, _DTstrftime, _DTnumberformat, _DTactive, STATUS
SESS_ADD_FAILED = 'usergroup add failed'
SESS_EDIT_FAILED = 'usergroup edit failed'
########
# List #
########
@view_config(route_name='usergroup', renderer='templates/usergroup/list.pt',
permission='edit')
def view_list(request):
rows = DBSession.query(User).filter(User.id > 0).order_by('email')
return dict(rows=rows)
#######
# Add #
#######
def form_validator(form, value):
def err_group():
raise colander.Invalid(form,
'User Group sudah ada dalam database')
q = DBSession.query(UserGroup).filter(UserGroup.user_id==value['user_id'],
UserGroup.group_id==value['group_id'])
found = q.first()
if found:
err_group()
class AddSchema(colander.Schema):
user_id = colander.SchemaNode(
colander.Integer(),
widget=widget.SelectWidget(values=DBSession.query(User.id,User.email).all()),
title="User")
group_id = colander.SchemaNode(
colander.Integer(),
widget=widget.SelectWidget(values=DBSession.query(Group.id,Group.group_name).all()),
title="Group")
def get_form(request, class_form):
schema = class_form(validator=form_validator)
schema = schema.bind(daftar_status=STATUS)
schema.request = request
return Form(schema, buttons=('save','cancel'))
def save(values, usergroup, row=None):
user = DBSession.query(User).filter_by(id=values['user_id']).first()
group = DBSession.query(Group).filter_by(id=values['group_id']).first()
usergroup = UserGroup.set_one(None, user, group)
return user
def save_request(values, request, row=None):
row = save(values, request.user, row)
request.session.flash('UserGroup sudah disimpan.')
def route_list(request):
return HTTPFound(location=request.route_url('usergroup'))
def session_failed(request, session_name):
r = dict(form=request.session[session_name])
del request.session[session_name]
return r
@view_config(route_name='usergroup-add', renderer='templates/usergroup/add.pt',
permission='add')
def view_add(request):
form = get_form(request, AddSchema)
if request.POST:
if 'save' in request.POST:
controls = request.POST.items()
#controls['email'] = controls['email'] or controls['usergroup_name']+'@local'
try:
c = form.validate(controls)
except ValidationFailure, e:
request.session[SESS_ADD_FAILED] = e.render()
return HTTPFound(location=request.route_url('usergroup-add'))
save_request(dict(controls), request)
return route_list(request)
elif SESS_ADD_FAILED in request.session:
return session_failed(request, SESS_ADD_FAILED)
return dict(form=form.render())
########
# Edit #
########
def query_id(request):
return DBSession.query(UserGroup).filter(UserGroup.user_id==request.matchdict['id'],
UserGroup.group_id==request.matchdict['id2'])
def id_not_found(request):
msg = 'User %s Group ID %s not found.' % (request.matchdict['id'],request.matchdict['id2'])
request.session.flash(msg, 'error')
return route_list(request)
"""@view_config(route_name='usergroup-edit', renderer='templates/usergroup/edit.pt',
permission='edit')
def view_edit(request):
row = query_id(request).first()
if not row:
return id_not_found(request)
form = get_form(request, EditSchema)
if request.POST:
if 'save' in request.POST:
controls = request.POST.items()
#controls['email'] = controls['email'] or controls['usergroup_name']+'@local'
try:
c = form.validate(controls)
except ValidationFailure, e:
request.session[SESS_EDIT_FAILED] = e.render()
return HTTPFound(location=request.route_url('usergroup-edit',
id=row.id))
save_request(dict(controls), request, row)
return route_list(request)
elif SESS_EDIT_FAILED in request.session:
return session_failed(request, SESS_EDIT_FAILED)
values = row.to_dict()
return dict(form=form.render(appstruct=values))
"""
##########
# Delete #
##########
@view_config(route_name='usergroup-delete', renderer='templates/usergroup/delete.pt',
permission='delete')
def view_delete(request):
q = query_id(request)
row = q.first()
if not row:
return id_not_found(request)
form = Form(colander.Schema(), buttons=('delete','cancel'))
if request.POST:
if 'delete' in request.POST:
msg = 'User ID %d Group %d has been deleted.' % (row.user_id, row.group_id)
q.delete()
DBSession.flush()
request.session.flash(msg)
return route_list(request)
return dict(row=row,
form=form.render())
##########
# Action #
##########
@view_config(route_name='usergroup-act', renderer='json',
permission='read')
def view_act(request):
req = request
params = req.params
url_dict = req.matchdict
if url_dict['act']=='grid':
columns = []
columns.append(ColumnDT('user_id'))
columns.append(ColumnDT('group_id'))
columns.append(ColumnDT('user_name'))
columns.append(ColumnDT('group_name'))
query = DBSession.query(UserGroup.user_id, UserGroup.group_id, User.user_name, Group.group_name).\
join(User).join(Group)
rowTable = DataTables(req, UserGroup, query, columns)
return rowTable.output_result()
...@@ -35,11 +35,6 @@ def view_list(request): ...@@ -35,11 +35,6 @@ def view_list(request):
####### #######
# Add # # Add #
####### #######
def email_validator(node, value):
name, email = parseaddr(value)
if not email or email.find('@') < 0:
raise colander.Invalid(node, 'Invalid email format')
def form_validator(form, value): def form_validator(form, value):
def err_kode(): def err_kode():
raise colander.Invalid(form, raise colander.Invalid(form,
...@@ -81,9 +76,20 @@ SUMMARIES = ( ...@@ -81,9 +76,20 @@ SUMMARIES = (
(1, 'Header'), (1, 'Header'),
(0, 'Detail'), (0, 'Detail'),
) )
def wilayah_select():
return DBSession.query(Wilayah.id, Wilayah.nama).all()
@colander.deferred
def deferred_wilayah_select(node, kw):
choices = kw.get('wilayah_select()')
return widget.SelectWidget(values=choices)
@colander.deferred
def deferred_wilayah_select_default(node, kw):
print kw
return kw[1]
class AddSchema(colander.Schema): class AddSchema(colander.Schema):
wilayah_select = DBSession.query(Wilayah.id, Wilayah.nama).all()
kode = colander.SchemaNode( kode = colander.SchemaNode(
colander.String(), colander.String(),
) )
...@@ -94,7 +100,9 @@ class AddSchema(colander.Schema): ...@@ -94,7 +100,9 @@ class AddSchema(colander.Schema):
title="Level") title="Level")
parent_id = colander.SchemaNode( parent_id = colander.SchemaNode(
colander.Integer(), colander.Integer(),
widget=widget.SelectWidget(values=wilayah_select), #default=deferred_wilayah_select_default,
#widget=deferred_wilayah_select,
widget=widget.SelectWidget(values=wilayah_select()),
title="Parent", title="Parent",
missing=colander.drop) missing=colander.drop)
...@@ -107,7 +115,7 @@ class EditSchema(AddSchema): ...@@ -107,7 +115,7 @@ class EditSchema(AddSchema):
def get_form(request, class_form): def get_form(request, class_form):
schema = class_form(validator=form_validator) schema = class_form(validator=form_validator)
schema = schema.bind(daftar_summary=SUMMARIES) schema = schema.bind(choices=wilayah_select())
schema.request = request schema.request = request
return Form(schema, buttons=('simpan','batal')) return Form(schema, buttons=('simpan','batal'))
......
...@@ -14,12 +14,15 @@ from deform import ( ...@@ -14,12 +14,15 @@ from deform import (
) )
from ..models import DBSession from ..models import DBSession
from ..models.isipkd import( from ..models.isipkd import(
Unit, SubjekPajak,
) )
from datatables import ( from datatables import (
ColumnDT, DataTables) ColumnDT, DataTables)
from ..tools import STATUS
SESS_ADD_FAILED = 'Gagal tambah wp' SESS_ADD_FAILED = 'Gagal tambah wp'
SESS_EDIT_FAILED = 'Gagal edit wp' SESS_EDIT_FAILED = 'Gagal edit wp'
...@@ -53,11 +56,11 @@ def form_validator(form, value): ...@@ -53,11 +56,11 @@ def form_validator(form, value):
if 'id' in form.request.matchdict: if 'id' in form.request.matchdict:
uid = form.request.matchdict['id'] uid = form.request.matchdict['id']
q = DBSession.query(Unit).filter_by(id=uid) q = DBSession.query(SubjekPajak).filter_by(id=uid)
r = q.first() r = q.first()
else: else:
r = None r = None
q = DBSession.query(Unit).filter_by(kode=value['kode']) q = DBSession.query(SubjekPajak).filter_by(kode=value['kode'])
found = q.first() found = q.first()
if r: if r:
if found and found.id != r.id: if found and found.id != r.id:
...@@ -65,7 +68,7 @@ def form_validator(form, value): ...@@ -65,7 +68,7 @@ def form_validator(form, value):
elif found: elif found:
err_email() err_email()
if 'uraian' in value: # optional if 'uraian' in value: # optional
found = Unit.get_by_uraian(value['uraian']) found = SubjekPajak.get_by_uraian(value['uraian'])
if r: if r:
if found and found.id != r.id: if found and found.id != r.id:
err_name() err_name()
...@@ -73,29 +76,25 @@ def form_validator(form, value): ...@@ -73,29 +76,25 @@ def form_validator(form, value):
err_name() err_name()
@colander.deferred @colander.deferred
def deferred_summary(node, kw): def deferred_status(node, kw):
values = kw.get('daftar_summary', []) values = kw.get('daftar_status', [])
return widget.SelectWidget(values=values) return widget.SelectWidget(values=values)
SUMMARIES = (
(1, 'Header'),
(0, 'Detail'),
)
class AddSchema(colander.Schema): class AddSchema(colander.Schema):
kode = colander.SchemaNode( kode = colander.SchemaNode(
colander.String(), colander.String(),
) )
uraian = colander.SchemaNode( nama = colander.SchemaNode(
colander.String())
alamat_1 = colander.SchemaNode(
colander.String())
alamat_2 = colander.SchemaNode(
colander.String(), colander.String(),
missing=colander.drop) missing=colander.drop)
level_id = colander.SchemaNode( status = colander.SchemaNode(
colander.Integer())
is_summary = colander.SchemaNode(
colander.Integer(), colander.Integer(),
widget=widget.SelectWidget(values=SUMMARIES), widget=widget.SelectWidget(values=STATUS),
title="Header") title="Status")
class EditSchema(AddSchema): class EditSchema(AddSchema):
id = colander.SchemaNode(colander.Integer(), id = colander.SchemaNode(colander.Integer(),
...@@ -105,13 +104,13 @@ class EditSchema(AddSchema): ...@@ -105,13 +104,13 @@ class EditSchema(AddSchema):
def get_form(request, class_form): def get_form(request, class_form):
schema = class_form(validator=form_validator) schema = class_form(validator=form_validator)
schema = schema.bind(daftar_summary=SUMMARIES) schema = schema.bind(daftar_status=STATUS)
schema.request = request schema.request = request
return Form(schema, buttons=('simpan','batal')) return Form(schema, buttons=('simpan','batal'))
def save(values, row=None): def save(values, row=None):
if not row: if not row:
row = Unit() row = SubjekPajak()
row.from_dict(values) row.from_dict(values)
#if values['password']: #if values['password']:
# row.password = values['password'] # row.password = values['password']
...@@ -156,7 +155,7 @@ def view_add(request): ...@@ -156,7 +155,7 @@ def view_add(request):
# Edit # # Edit #
######## ########
def query_id(request): def query_id(request):
return DBSession.query(Unit).filter_by(id=request.matchdict['id']) return DBSession.query(SubjekPajak).filter_by(id=request.matchdict['id'])
def id_not_found(request): def id_not_found(request):
msg = 'wp ID %s not found.' % request.matchdict['id'] msg = 'wp ID %s not found.' % request.matchdict['id']
...@@ -221,9 +220,10 @@ def view_act(request): ...@@ -221,9 +220,10 @@ def view_act(request):
columns = [] columns = []
columns.append(ColumnDT('id')) columns.append(ColumnDT('id'))
columns.append(ColumnDT('kode')) columns.append(ColumnDT('kode'))
columns.append(ColumnDT('uraian')) columns.append(ColumnDT('nama'))
columns.append(ColumnDT('level_id')) columns.append(ColumnDT('alamat_1'))
columns.append(ColumnDT('is_summary')) columns.append(ColumnDT('alamat_2'))
query = DBSession.query(Unit) columns.append(ColumnDT('status'))
rowTable = DataTables(req, Unit, query, columns) query = DBSession.query(SubjekPajak)
rowTable = DataTables(req, SubjekPajak, query, columns)
return rowTable.output_result() return rowTable.output_result()
git add .
git commit -m 'auto'
git push esipkd
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!