Commit 25e2a5fb by aa.gusti

Perubahan Route

1 parent 72ebe4ad
4.0.0 17-11-2024
Penambahan Field pada tabel routes
Tabel Routes berfungsi juga sebagai menu generator
4.0.0 09-07-2024 4.0.0 09-07-2024
Perubahan Colander>2.0 Perubahan Colander>2.0
Perubahan SQLAlchemy>2.0 Perubahan SQLAlchemy>2.0
......
...@@ -156,7 +156,18 @@ Contoh:: ...@@ -156,7 +156,18 @@ Contoh::
</Proxy> </Proxy>
</VirtualHost> </VirtualHost>
``` ```
# Migrasi
Karena ada penambahan dari fungsi table route berfungsi sebagai menu
generator, maka diperlukan upgrade khusus bagi aplikasi lama
```
alembic -c config_file -n alembic_models upgrade head
```
Tambahkan Konfigurasi berikut ini
```
[alembic_models]
sqlalchemy.url = postgresql://user:password@localhost:5432/db
script_location = opensipkd.models:alembic
```
# Virtual Directory # Virtual Directory
## Setting Ini File ## Setting Ini File
......
...@@ -62,6 +62,7 @@ static_route = [ ...@@ -62,6 +62,7 @@ static_route = [
] ]
# 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):
# diganti menggunakan @view_config(context=HTTPNotFound, renderer='templates/404.pt') pada base.views # diganti menggunakan @view_config(context=HTTPNotFound, renderer='templates/404.pt') pada base.views
...@@ -155,6 +156,8 @@ def add_global(event): ...@@ -155,6 +156,8 @@ def add_global(event):
event['get_urls'] = get_urls event['get_urls'] = get_urls
event['get_csrf_token'] = get_csrf_token event['get_csrf_token'] = get_csrf_token
event['get_params'] = get_params event['get_params'] = get_params
event['get_module_menus'] = get_module_menus
event['get_module_submenus'] = get_module_submenus
def get_params(request, params, alternate=None, settings=None): def get_params(request, params, alternate=None, settings=None):
...@@ -424,8 +427,8 @@ def get_home(request): ...@@ -424,8 +427,8 @@ def get_home(request):
return request.route_url('home')[:-1] return request.route_url('home')[:-1]
def set_routes(config, app_id=None): def _set_routes1(config, app_id):
q = DBSession.query(Route) q = DBSession.query(Route).filter(Route.path != None, Route.module == None, Route.status==1)
if not app_id: if not app_id:
q.filter(or_(Route.app_id == 0, None == Route.app_id)) q.filter(or_(Route.app_id == 0, None == Route.app_id))
else: else:
...@@ -441,6 +444,58 @@ def set_routes(config, app_id=None): ...@@ -441,6 +444,58 @@ def set_routes(config, app_id=None):
default_renderer="json_rpc") default_renderer="json_rpc")
def _set_routes2(config, module="base"):
q = DBSession.query(Route).filter(Route.module == module, Route.status==1)
for route in q:
if route.type == 0:
config.add_route(route.kode, route.path)
if route.nama:
titles[route.kode] = route.nama
elif route.type == 1:
config.add_jsonrpc_endpoint(route.kode, route.path,
default_renderer="json_rpc")
return q
def set_routes(config, app_id=None):
if app_id and type(app_id) == str:
return _set_routes2(config, app_id)
else:
return _set_routes1(config, app_id)
def get_route_names(rows):
return [r.kode for r in rows if not r.is_menu]
def get_children(rows):
return [{"id": r.id, "path": r.path, "nama": r.nama, "is_menu": r.is_menu,
"icon": r.icon,
"route_names": [r.kode] + get_route_names(r.children),
"children": get_children(r.children),
"has_sub": r.path.find("/") == -1
}
for r in rows if r.is_menu and r.status==1]
def get_module_menus(module):
query = DBSession.query(Route) \
.filter(Route.module == module,
Route.is_menu == 1,
Route.parent_id == None)
result = get_children(query.order_by(Route.order_id))
log.debug(result)
return result
def get_module_submenus(parent_id):
q = DBSession.query(Route) \
.filter(Route.parent_id == parent_id) \
.order_bY(Route.order_id)
return [r.kode for r in query.all()]
partner_idcard_url = 'partner/idcard' partner_idcard_url = 'partner/idcard'
...@@ -451,7 +506,8 @@ def main(global_config, **settings): ...@@ -451,7 +506,8 @@ def main(global_config, **settings):
None: {"js": "opensipkd.base:static/jquery/jquery.maskMoney.min.js"}} None: {"js": "opensipkd.base:static/jquery/jquery.maskMoney.min.js"}}
engine = engine_from_config( engine = engine_from_config(
settings, 'sqlalchemy.', client_encoding='utf8', max_identifier_length=30) # , convert_unicode=True settings, 'sqlalchemy.', client_encoding='utf8',
max_identifier_length=30) # , convert_unicode=True
DBSession.configure(bind=engine) DBSession.configure(bind=engine)
LogDBSession.configure(bind=engine) LogDBSession.configure(bind=engine)
Base.metadata.bind = engine Base.metadata.bind = engine
...@@ -512,6 +568,10 @@ def main(global_config, **settings): ...@@ -512,6 +568,10 @@ def main(global_config, **settings):
config.add_request_method(get_params, 'get_params', reify=True) config.add_request_method(get_params, 'get_params', reify=True)
config.add_request_method(get_csrf_token, 'get_csrf_token', reify=True) config.add_request_method(get_csrf_token, 'get_csrf_token', reify=True)
# Penambahan Module Auto Generate Menu
# config.add_request_method(get_module_menus, 'get_module_menus', reify=True)
# config.add_request_method(get_module_submenus, 'get_module_submenus', reify=True)
# config.add_translation_dirs('opensipkd.base:locale/') # config.add_translation_dirs('opensipkd.base:locale/')
config.add_static_view('static', 'opensipkd.base:static', config.add_static_view('static', 'opensipkd.base:static',
......
...@@ -242,6 +242,8 @@ def append_csv(table, filename, keys, get_file_func=get_file, ...@@ -242,6 +242,8 @@ def append_csv(table, filename, keys, get_file_func=get_file,
value = cf[fname] value = cf[fname]
fname_orig = fmap[fname] fname_orig = fmap[fname]
if not value and callback:
value = callback("value", data=cf, field=fname_orig)
data[fname_orig] = value data[fname_orig] = value
for key in keys: for key in keys:
...@@ -279,6 +281,7 @@ def append_csv(table, filename, keys, get_file_func=get_file, ...@@ -279,6 +281,7 @@ def append_csv(table, filename, keys, get_file_func=get_file,
# update: tambah periksa nilai default. # update: tambah periksa nilai default.
# Jika default=None berarti wajib ada nilainya # Jika default=None berarti wajib ada nilainya
# by tatang 2024-10-12 # by tatang 2024-10-12
log.debug(data)
raise Exception( raise Exception(
f"Table {str(table.__name__)} Field '{c['name']}' wajib ada {c['type']} ") f"Table {str(table.__name__)} Field '{c['name']}' wajib ada {c['type']} ")
......
...@@ -159,12 +159,11 @@ class BaseView(object): ...@@ -159,12 +159,11 @@ class BaseView(object):
self.upload_keys = ["kode"] self.upload_keys = ["kode"]
self.report_file = "" self.report_file = ""
self.new_buttons = {} self.new_buttons = {}
self.is_object = False
def query_register(self, **kwargs): def query_register(self, **kwargs):
pass pass
def route_list(self, **kwargs): def route_list(self, **kwargs):
msg = kwargs.get("msg") msg = kwargs.get("msg")
error = kwargs.get("error", "") error = kwargs.get("error", "")
...@@ -274,7 +273,7 @@ class BaseView(object): ...@@ -274,7 +273,7 @@ class BaseView(object):
resources = form.get_widget_resources() resources = form.get_widget_resources()
readonly = "readonly" in kwargs and kwargs["readonly"] or False readonly = "readonly" in kwargs and kwargs["readonly"] or False
kwargs["readonly"] = readonly kwargs["readonly"] = readonly
is_object = kwargs.get("is_object") is_object = kwargs.get("is_object", self.is_object)
if is_object: if is_object:
return dict(form=form, return dict(form=form,
table=table and table.render() or None, table=table and table.render() or None,
...@@ -520,7 +519,7 @@ class BaseView(object): ...@@ -520,7 +519,7 @@ class BaseView(object):
form = self.get_form(self.add_schema, **kwargs) form = self.get_form(self.add_schema, **kwargs)
table = self.get_item_table(**kwargs) table = self.get_item_table(**kwargs)
resources = form.get_widget_resources() resources = form.get_widget_resources()
is_object = kwargs.get("is_object", False) is_object = kwargs.get("is_object", self.is_object)
if self.req.POST: if self.req.POST:
if 'save' in self.req.POST: if 'save' in self.req.POST:
controls = self.req.POST.items() controls = self.req.POST.items()
...@@ -621,7 +620,7 @@ class BaseView(object): ...@@ -621,7 +620,7 @@ class BaseView(object):
def view_edit(self, **kwargs): def view_edit(self, **kwargs):
request = self.req request = self.req
row = self.query_id().first() row = self.query_id().first()
is_object = kwargs.get("is_object", False) is_object = kwargs.get("is_object", self.is_object)
if not row: if not row:
return self.id_not_found(**kwargs) return self.id_not_found(**kwargs)
...@@ -673,7 +672,7 @@ class BaseView(object): ...@@ -673,7 +672,7 @@ class BaseView(object):
request = self.req request = self.req
q = self.query_id() q = self.query_id()
row = q.first() row = q.first()
is_object = kwargs.get("is_object", False) is_object = kwargs.get("is_object", self.is_object)
if not row: if not row:
return self.id_not_found() return self.id_not_found()
if not self.bindings: if not self.bindings:
......
...@@ -96,8 +96,10 @@ class EditSchema(AddSchema): ...@@ -96,8 +96,10 @@ class EditSchema(AddSchema):
class ListSchema(colander.Schema): class ListSchema(colander.Schema):
id = colander.SchemaNode(colander.Integer(), id = colander.SchemaNode(colander.Integer(),
title=_("action", default="Action")) title=_("action", default="Action"))
module= colander.SchemaNode(colander.String(), title="Kode", width='100pt')
kode = colander.SchemaNode(colander.String(), title="Kode", width='100pt') kode = colander.SchemaNode(colander.String(), title="Kode", width='100pt')
nama = colander.SchemaNode(colander.String(), title="Nama") nama = colander.SchemaNode(colander.String(), title="Nama")
permission = colander.SchemaNode(colander.String(), title="Permission")
status = colander.SchemaNode(colander.Boolean(), title="Status", status = colander.SchemaNode(colander.Boolean(), title="Status",
width='50pt') width='50pt')
need_login = colander.SchemaNode(colander.Integer(), title="Login", need_login = colander.SchemaNode(colander.Integer(), title="Login",
......
...@@ -20,6 +20,7 @@ ...@@ -20,6 +20,7 @@
desa_path ['desa', 'desa-add', 'desa-edit', 'desa-view', 'desa-delete']; desa_path ['desa', 'desa-add', 'desa-edit', 'desa-view', 'desa-delete'];
css css|[]; css css|[];
js js|[]; js js|[];
route_name route_name|request.matched_route.name;
"> ">
<head> <head>
...@@ -159,64 +160,64 @@ ...@@ -159,64 +160,64 @@
<a href="#"><i class="fa fa-lg fa-fw fa-shield"></i><span class="menu-item-parent">Admin</span></a> <a href="#"><i class="fa fa-lg fa-fw fa-shield"></i><span class="menu-item-parent">Admin</span></a>
<ul> <ul>
<li tal:condition="has_permission(request, ['user-view', 'user-edit'])" <li tal:condition="has_permission(request, ['user-view', 'user-edit'])"
tal:attributes="class request.matched_route.name in user_path and 'active'"> tal:attributes="class route_name in user_path and 'active'">
<a href="${home}/user">User</a> <a href="${home}/user">User</a>
</li> </li>
<li tal:condition="has_permission(request, ['user-view', 'user-edit'])" <li tal:condition="has_permission(request, ['user-view', 'user-edit'])"
tal:attributes="class request.matched_route.name in user_area_path and 'active'"> tal:attributes="class route_name in user_area_path and 'active'">
<a href="${home}/user/area">User Area</a> <a href="${home}/user/area">User Area</a>
</li> </li>
<li tal:condition="has_permission(request, ['user-view', 'user-edit'])" <li tal:condition="has_permission(request, ['user-view', 'user-edit'])"
tal:attributes="class request.matched_route.name in user_dep_path and 'active'"> tal:attributes="class route_name in user_dep_path and 'active'">
<a href="${home}/user/departemen">User Departemen</a> <a href="${home}/user/departemen">User Departemen</a>
</li> </li>
<li tal:condition="has_permission(request, ['user-view', 'user-edit'])" <li tal:condition="has_permission(request, ['user-view', 'user-edit'])"
tal:attributes="class request.matched_route.name in user_ext_path and 'active'"> tal:attributes="class route_name in user_ext_path and 'active'">
<a href="${home}/user/ext">External User</a> <a href="${home}/user/ext">External User</a>
</li> </li>
<li tal:condition="has_permission(request, ['user-view', 'user-edit'])" <li tal:condition="has_permission(request, ['user-view', 'user-edit'])"
tal:attributes="class request.matched_route.name in group_path and 'active'"> tal:attributes="class route_name in group_path and 'active'">
<a href="${home}/group">Group</a> <a href="${home}/group">Group</a>
</li> </li>
<li tal:condition="has_permission(request, 'upload-logo')" <li tal:condition="has_permission(request, 'upload-logo')"
tal:attributes="class request.matched_route.name in ['upload-logo'] and 'active'"> tal:attributes="class route_name in ['upload-logo'] and 'active'">
<a href="${home}/upload/logo">Upload Logo</a></li> <a href="${home}/upload/logo">Upload Logo</a></li>
<li tal:condition="has_permission(request, 'parameter')" <li tal:condition="has_permission(request, 'parameter')"
tal:attributes="class request.matched_route.name in param_path and 'active'"> tal:attributes="class route_name in param_path and 'active'">
<a href="${home}/parameter">Parameter</a></li> <a href="${home}/parameter">Parameter</a></li>
<li tal:condition="has_permission(request, 'company')" <li tal:condition="has_permission(request, 'company')"
tal:attributes="class request.matched_route.name in company_path and 'active'"> tal:attributes="class route_name in company_path and 'active'">
<a href="${home}/company">Pemerintah</a></li> <a href="${home}/company">Pemerintah</a></li>
<li tal:condition="has_permission(request, 'eselon')" <li tal:condition="has_permission(request, 'eselon')"
tal:attributes="class request.matched_route.name in eselon_path and 'active'"> tal:attributes="class route_name in eselon_path and 'active'">
<a href="${home}/eselon">Eselon</a></li> <a href="${home}/eselon">Eselon</a></li>
<li tal:condition="has_permission(request, 'jabatan')" <li tal:condition="has_permission(request, 'jabatan')"
tal:attributes="class request.matched_route.name in jabatan_path and 'active'"> tal:attributes="class route_name in jabatan_path and 'active'">
<a href="${home}/jabatan">Jabatan</a></li> <a href="${home}/jabatan">Jabatan</a></li>
<li tal:condition="has_permission(request, 'departemen')" <li tal:condition="has_permission(request, 'departemen')"
tal:attributes="class request.matched_route.name in dep_path and 'active'"> tal:attributes="class route_name in dep_path and 'active'">
<a href="${home}/departemen">Departemen</a></li> <a href="${home}/departemen">Departemen</a></li>
<li tal:condition="has_permission(request, 'partner')" <li tal:condition="has_permission(request, 'partner')"
tal:attributes="class request.matched_route.name in partner_path and 'active'"> tal:attributes="class route_name in partner_path and 'active'">
<a href="${home}/partner">Partner</a></li> <a href="${home}/partner">Partner</a></li>
<li tal:condition="has_permission(request, 'partner-departemen')" <li tal:condition="has_permission(request, 'partner-departemen')"
tal:attributes="class request.matched_route.name in part_dep_path and 'active'"> tal:attributes="class route_name in part_dep_path and 'active'">
<a href="${home}/partner/departemen">Partner Departemen</a></li> <a href="${home}/partner/departemen">Partner Departemen</a></li>
<li tal:condition="has_permission(request, 'provinsi')" <li tal:condition="has_permission(request, 'provinsi')"
tal:attributes="class request.matched_route.name in provinsi_path and 'active'"> tal:attributes="class route_name in provinsi_path and 'active'">
<a href="${home}/provinsi">Provinsi</a></li> <a href="${home}/provinsi">Provinsi</a></li>
<li tal:condition="has_permission(request, 'dati2')" <li tal:condition="has_permission(request, 'dati2')"
tal:attributes="class request.matched_route.name in dati2_path and 'active'"> tal:attributes="class route_name in dati2_path and 'active'">
<a href="${home}/dati2">Kabupaten/Kota</a></li> <a href="${home}/dati2">Kabupaten/Kota</a></li>
<li tal:condition="has_permission(request, 'kecamatan')" <li tal:condition="has_permission(request, 'kecamatan')"
tal:attributes="class request.matched_route.name in kecamatan_path and 'active'"> tal:attributes="class route_name in kecamatan_path and 'active'">
<a href="${home}/kecamatan">Kecamatan</a></li> <a href="${home}/kecamatan">Kecamatan</a></li>
<li tal:condition="has_permission(request, 'desa')" <li tal:condition="has_permission(request, 'desa')"
tal:attributes="class request.matched_route.name in desa_path and 'active'"> tal:attributes="class route_name in desa_path and 'active'">
<a href="${home}/desa">Desa/Kelurahan</a></li> <a href="${home}/desa">Desa/Kelurahan</a></li>
<li tal:condition="has_permission(request, 'log')" <li tal:condition="has_permission(request, 'log')"
tal:attributes="class request.matched_route.name in ['log'] and 'active'"> tal:attributes="class route_name in ['log'] and 'active'">
<a href="${home}/log">Log</a></li> <a href="${home}/log">Log</a></li>
</ul> </ul>
......
...@@ -24,7 +24,7 @@ def table_has_column(table, column, schema=None): ...@@ -24,7 +24,7 @@ def table_has_column(table, column, schema=None):
return has_column return has_column
def fields_update(table, field, typ, schema="pad"): def fields_update(table, field, typ, schema="public"):
context = op.get_context() context = op.get_context()
helpers = context.opts['helpers'] helpers = context.opts['helpers']
if not helpers.table_has_column(table, field, schema): if not helpers.table_has_column(table, field, schema):
......
"""create table """ugrade routes
Revision ID: 1a608edd4715 Revision ID: 1a608edd4715
Revises: Revises:
...@@ -17,7 +17,18 @@ import sqlalchemy as sa ...@@ -17,7 +17,18 @@ import sqlalchemy as sa
def upgrade(): def upgrade():
pass schema = "public"
context = op.get_context()
helpers = context.opts['helpers']
helpers.fields_update("routes", "module", sa.String(256), schema)
helpers.fields_update("routes", "is_menu", sa.SmallInteger, schema)
helpers.fields_update("routes", "parent_id", sa.Integer, schema)
helpers.fields_update("routes", "order_id", sa.Integer, schema)
helpers.fields_update("routes", "permission", sa.String(256), schema)
helpers.fields_update("routes", "class_view", sa.String(256), schema)
helpers.fields_update("routes", "def_func", sa.String(256), schema)
helpers.fields_update("routes", "template", sa.String(256), schema)
helpers.fields_update("routes", "icon", sa.String(256), schema)
def downgrade(): def downgrade():
......
...@@ -10,11 +10,23 @@ from .users import User ...@@ -10,11 +10,23 @@ from .users import User
class Route(Base, NamaModel): class Route(Base, NamaModel):
__tablename__ = 'routes' __tablename__ = 'routes'
__table_args__ = {'extend_existing': True} __table_args__ = {'extend_existing': True}
id = Column(Integer, primary_key=True)
kode = Column(String(128), unique=True) kode = Column(String(128), unique=True)
path = Column(String(256), nullable=False, unique=True) path = Column(String(256), nullable=False, unique=True)
status = Column(Integer, nullable=False, server_default='1') status = Column(Integer, nullable=False, server_default='1')
type = Column(SmallInteger, nullable=False, server_default='0') type = Column(SmallInteger, nullable=False, server_default='0')
app_id = Column(SmallInteger, nullable=False, server_default='0') app_id = Column(SmallInteger, nullable=False, server_default='0')
module = Column(String(256))
is_menu = Column(SmallInteger)
parent_id = Column(Integer, ForeignKey("routes.id"))
order_id = Column(Integer)
permission = Column(String(256))
class_view = Column(String(256))
def_func = Column(String(256))
template = Column(String(256))
icon = Column(String(256))
children = relationship(
"Route", backref=backref('parent', remote_side=[id]))
class Parameter(Base, NamaModel): class Parameter(Base, NamaModel):
......
...@@ -3,7 +3,7 @@ from sqlalchemy import ( ...@@ -3,7 +3,7 @@ from sqlalchemy import (
Integer, Integer,
ForeignKey, ForeignKey,
String, String,
SmallInteger, Boolean, SmallInteger, Boolean,Text
) )
from sqlalchemy.orm import ( from sqlalchemy.orm import (
relationship, relationship,
...@@ -19,9 +19,9 @@ class Menus(Base, NamaModel): ...@@ -19,9 +19,9 @@ class Menus(Base, NamaModel):
__tablename__ = 'menus' __tablename__ = 'menus'
__table_args__ = (TABLE_ARGS,) __table_args__ = (TABLE_ARGS,)
id = Column(Integer, primary_key=True) id = Column(Integer, primary_key=True)
order_id = Column(SmallInteger)
parent_id = Column(Integer, ForeignKey('public.menus.id')) parent_id = Column(Integer, ForeignKey('public.menus.id'))
level_id = Column(SmallInteger) level_id = Column(SmallInteger)
order_id = Column(SmallInteger)
valu = Column(String(256)) # value/action valu = Column(String(256)) # value/action
meth = Column(String(256)) # new method meth = Column(String(256)) # new method
page_typ = Column(String(256)) # PageType page_typ = Column(String(256)) # PageType
......
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!