Skip to content
Toggle navigation
Projects
Groups
Snippets
Help
aa.gusti
/
opensipkd-base
This project
Loading...
Sign in
Toggle navigation
Go to a project
Project
Repository
Settings
Activity
Graph
Charts
Create a new issue
Commits
Issue Boards
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Commit 324d8d62
authored
Nov 27, 2024
by
aa.gusti
Browse Files
Options
Browse Files
Tag
Download
Email Patches
Plain Diff
perbaikan template upload
1 parent
8783308f
Hide whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
217 additions
and
86 deletions
opensipkd/base/__init__.py
opensipkd/base/views/__init__.py
opensipkd/base/views/base_views.py
opensipkd/base/views/partner.py
opensipkd/base/views/partner_base.py
opensipkd/base/views/widgets/captcha.pt
opensipkd/base/views/widgets/file_upload.pt
opensipkd/base/views/widgets/form.pt
opensipkd/models/partner.py
opensipkd/base/__init__.py
View file @
324d8d6
...
@@ -2,13 +2,14 @@ import locale
...
@@ -2,13 +2,14 @@ import locale
import
logging
import
logging
import
re
import
re
# from opensipkd.tools.captcha import get_captcha_url
from
.routes
import
routes
from
.routes
import
routes
try
:
try
:
from
urllib
import
(
urlencode
,
quote
,
quote_plus
,
)
from
urllib
import
(
urlencode
,
quote
,
quote_plus
,
)
except
ImportError
:
except
ImportError
:
from
urllib.parse
import
(
urlencode
,
quote
,
quote_plus
,
)
from
urllib.parse
import
(
urlencode
,
quote
,
quote_plus
,
)
from
collections
import
OrderedDict
from
pyramid.events
import
NewRequest
from
pyramid.events
import
NewRequest
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
...
@@ -498,7 +499,7 @@ def get_module_submenus(parent_id):
...
@@ -498,7 +499,7 @@ def get_module_submenus(parent_id):
q
=
DBSession
.
query
(
Route
)
\
q
=
DBSession
.
query
(
Route
)
\
.
filter
(
Route
.
parent_id
==
parent_id
)
\
.
filter
(
Route
.
parent_id
==
parent_id
)
\
.
order_bY
(
Route
.
order_id
)
.
order_bY
(
Route
.
order_id
)
return
[
r
.
kode
for
r
in
q
uery
.
all
()]
return
[
r
.
kode
for
r
in
q
.
all
()]
partner_idcard_url
=
'partner/idcard'
partner_idcard_url
=
'partner/idcard'
...
@@ -561,6 +562,7 @@ def main(global_config, **settings):
...
@@ -561,6 +562,7 @@ def main(global_config, **settings):
config
.
add_request_method
(
is_devel
,
'devel'
,
reify
=
True
)
config
.
add_request_method
(
is_devel
,
'devel'
,
reify
=
True
)
config
.
add_request_method
(
get_host
,
'_host'
,
reify
=
True
)
config
.
add_request_method
(
get_host
,
'_host'
,
reify
=
True
)
config
.
add_request_method
(
get_host
,
'home'
,
reify
=
True
)
config
.
add_request_method
(
get_host
,
'home'
,
reify
=
True
)
# config.add_request_method(get_captcha_url, 'captcha', reify=True)
# config.add_request_method(get_urls, 'route_urls', reify=True)
# config.add_request_method(get_urls, 'route_urls', reify=True)
config
.
add_request_method
(
google_signin_client_id
,
config
.
add_request_method
(
google_signin_client_id
,
'google_signin_client_id'
,
reify
=
True
)
'google_signin_client_id'
,
reify
=
True
)
...
@@ -592,6 +594,10 @@ def main(global_config, **settings):
...
@@ -592,6 +594,10 @@ def main(global_config, **settings):
os
.
makedirs
(
captcha_files
)
os
.
makedirs
(
captcha_files
)
config
.
add_static_view
(
'captcha'
,
captcha_files
)
config
.
add_static_view
(
'captcha'
,
captcha_files
)
config
.
add_static_view
(
'partner/files'
,
get_params
(
"partner_files"
,
settings
=
settings
,
alternate
=
"/tmp/partner"
))
config
.
add_renderer
(
'csv'
,
'opensipkd.tools.CSVRenderer'
)
config
.
add_renderer
(
'csv'
,
'opensipkd.tools.CSVRenderer'
)
config
.
add_renderer
(
'json'
,
json_renderer
())
config
.
add_renderer
(
'json'
,
json_renderer
())
config
.
add_renderer
(
'json_rpc'
,
json_rpc
())
config
.
add_renderer
(
'json_rpc'
,
json_rpc
())
...
...
opensipkd/base/views/__init__.py
View file @
324d8d6
...
@@ -3,32 +3,25 @@ from datetime import timedelta
...
@@ -3,32 +3,25 @@ from datetime import timedelta
import
colander
import
colander
from
deform
import
(
from
deform
import
(
Form
,
ValidationFailure
,
widget
,
Button
,
)
Form
,
ValidationFailure
,
widget
,
Button
,
FileData
)
from
opensipkd.tools.api
import
JsonRpcInvalidLoginError
from
opensipkd.base
import
get_params
,
get_urls
from
opensipkd.models
import
(
DBSession
,
UserService
,
)
from
opensipkd.tools
import
mem_tmp_store
from
pyramid.httpexceptions
import
(
from
pyramid.httpexceptions
import
(
HTTPFound
,
HTTPForbidden
,
HTTPNotFound
,
HTTPInternalServerError
,
HTTPFound
,
HTTPForbidden
,
HTTPNotFound
,
HTTPInternalServerError
,
HTTPSeeOther
)
HTTPSeeOther
)
from
pyramid.i18n
import
TranslationStringFactory
from
pyramid.i18n
import
TranslationStringFactory
from
pyramid.interfaces
import
IRoutesMapper
from
pyramid.interfaces
import
IRoutesMapper
from
pyramid.renderers
import
render_to_response
from
pyramid.renderers
import
render_to_response
from
pyramid.response
import
Response
from
pyramid.security
import
remember
from
pyramid.view
import
view_config
from
pyramid.view
import
view_config
from
opensipkd.base
import
get_params
,
get_urls
from
.base_views
import
BaseView
,
DataTables
,
ColumnDT
from
opensipkd.base.tools.api
import
rpc_auth
from
.base_views
import
BaseView
from
opensipkd.models
import
(
DBSession
,
UserService
,
)
from
.common
import
DataTables
,
ColumnDT
from
pyramid.csrf
import
new_csrf_token
_
=
TranslationStringFactory
(
'login'
)
_
=
TranslationStringFactory
(
'login'
)
log
=
logging
.
getLogger
(
__name__
)
log
=
logging
.
getLogger
(
__name__
)
@view_config
(
context
=
HTTPNotFound
,
renderer
=
'templates/404.pt'
)
@view_config
(
context
=
HTTPNotFound
,
renderer
=
'templates/404.pt'
)
def
not_found
(
request
):
def
not_found
(
request
):
path
=
request
.
path
path
=
request
.
path
...
@@ -55,6 +48,33 @@ def internal_server_error(request):
...
@@ -55,6 +48,33 @@ def internal_server_error(request):
# return response
# return response
class
Validator
(
object
):
def
__init__
(
self
,
row
):
self
.
row
=
row
class
FileSchema
(
colander
.
Schema
):
file_name
=
colander
.
SchemaNode
(
FileData
(),
widget
=
widget
.
FileUploadWidget
(
mem_tmp_store
,
size
=
104857600
),
missing
=
colander
.
drop
,
title
=
"File"
)
description
=
colander
.
SchemaNode
(
colander
.
String
(),
missing
=
colander
.
drop
,
validator
=
colander
.
Length
(
max
=
256
),
)
class
FilesSchema
(
colander
.
SequenceSchema
):
file_name
=
FileSchema
()
def
after_bin
(
self
,
node
,
kw
):
self
[
"file_name"
]
.
title
=
""
########
########
# Home #
# Home #
########
########
...
@@ -106,14 +126,14 @@ class Password(colander.Schema):
...
@@ -106,14 +126,14 @@ class Password(colander.Schema):
new_password
=
colander
.
SchemaNode
(
new_password
=
colander
.
SchemaNode
(
colander
.
String
(),
widget
=
widget
.
CheckedPasswordWidget
())
colander
.
String
(),
widget
=
widget
.
CheckedPasswordWidget
())
# retype_password = colander.SchemaNode(
# retype_password = colander.SchemaNode(
# colander.String(), widget=widget.PasswordWidget())
# colander.String(), widget=widget.PasswordWidget())
def
password_validator
(
form
,
value
):
def
password_validator
(
form
,
value
):
if
not
UserService
.
check_password
(
form
.
request
.
user
,
value
[
'old_password'
]):
if
not
UserService
.
check_password
(
form
.
request
.
user
,
value
[
'old_password'
]):
raise
colander
.
Invalid
(
form
,
'Invalid old password.'
)
raise
colander
.
Invalid
(
form
,
'Invalid old password.'
)
# if value['new_password'] != value['retype_password']:
# if value['new_password'] != value['retype_password']:
# raise colander.Invalid(form, 'Retype mismatch.')
# raise colander.Invalid(form, 'Retype mismatch.')
@view_config
(
@view_config
(
...
@@ -151,6 +171,4 @@ two_minutes = timedelta(1.0 / 24 / 60)
...
@@ -151,6 +171,4 @@ two_minutes = timedelta(1.0 / 24 / 60)
@colander.deferred
@colander.deferred
def
deferred_jenis
(
node
,
kw
):
def
deferred_jenis
(
node
,
kw
):
values
=
kw
.
get
(
'daftar_jenis'
,
[])
values
=
kw
.
get
(
'daftar_jenis'
,
[])
return
widget
.
RadioChoiceWidget
(
values
=
values
)
return
widget
.
RadioChoiceWidget
(
values
=
values
)
\ No newline at end of file
\ No newline at end of file
opensipkd/base/views/base_views.py
View file @
324d8d6
...
@@ -9,7 +9,6 @@ from datatables import ColumnDT
...
@@ -9,7 +9,6 @@ from datatables import ColumnDT
from
dateutil.relativedelta
import
relativedelta
from
dateutil.relativedelta
import
relativedelta
from
deform
import
(
widget
,
Form
,
ValidationFailure
,
FileData
,
)
from
deform
import
(
widget
,
Form
,
ValidationFailure
,
FileData
,
)
from
deform.widget
import
SelectWidget
from
deform.widget
import
SelectWidget
from
opensipkd.base.views.upload
import
tmpstore
from
opensipkd.tools
import
dmy
,
get_settings
,
get_ext
,
\
from
opensipkd.tools
import
dmy
,
get_settings
,
get_ext
,
\
date_from_str
,
get_random_string
date_from_str
,
get_random_string
from
opensipkd.tools.buttons
import
btn_save
,
btn_cancel
,
btn_close
,
btn_delete
,
\
from
opensipkd.tools.buttons
import
btn_save
,
btn_cancel
,
btn_close
,
btn_delete
,
\
...
@@ -19,6 +18,7 @@ from opensipkd.tools.captcha import get_captcha
...
@@ -19,6 +18,7 @@ from opensipkd.tools.captcha import get_captcha
from
opensipkd.tools.report
import
csv_response
,
file_response
from
opensipkd.tools.report
import
csv_response
,
file_response
from
pyramid.httpexceptions
import
HTTPFound
,
HTTPNotFound
from
pyramid.httpexceptions
import
HTTPFound
,
HTTPNotFound
from
opensipkd.base.views.upload
import
tmpstore
from
.common
import
DataTables
from
.common
import
DataTables
from
..
import
DBSession
,
get_params
,
get_urls
from
..
import
DBSession
,
get_params
,
get_urls
from
..scripts.initializedb
import
append_csv
from
..scripts.initializedb
import
append_csv
...
@@ -149,6 +149,9 @@ class BaseView(object):
...
@@ -149,6 +149,9 @@ class BaseView(object):
self
.
edit_schema
=
""
self
.
edit_schema
=
""
self
.
add_schema
=
""
self
.
add_schema
=
""
self
.
upload_schema
=
UploadSchema
self
.
upload_schema
=
UploadSchema
self
.
upload_exts
=
(
".csv"
,
".tsv"
)
self
.
upload_keys
=
[
"kode"
]
self
.
table
=
""
self
.
table
=
""
self
.
home
=
self
.
req
.
_host
self
.
home
=
self
.
req
.
_host
self
.
buttons
=
None
self
.
buttons
=
None
...
@@ -156,7 +159,6 @@ class BaseView(object):
...
@@ -156,7 +159,6 @@ class BaseView(object):
self
.
bindings
=
{}
self
.
bindings
=
{}
self
.
autocomplete
=
'on'
self
.
autocomplete
=
'on'
self
.
action_suffix
=
"/grid/act"
self
.
action_suffix
=
"/grid/act"
self
.
upload_keys
=
[
"kode"
]
self
.
report_file
=
""
self
.
report_file
=
""
self
.
new_buttons
=
{}
self
.
new_buttons
=
{}
self
.
is_object
=
False
self
.
is_object
=
False
...
@@ -263,7 +265,7 @@ class BaseView(object):
...
@@ -263,7 +265,7 @@ class BaseView(object):
return
arg
return
arg
def
get_bindings
(
self
,
row
=
None
):
def
get_bindings
(
self
,
row
=
None
):
return
{}
return
{
"row"
:
row
}
def
next_view
(
self
,
form
,
**
kwargs
):
def
next_view
(
self
,
form
,
**
kwargs
):
return
return
...
@@ -296,11 +298,20 @@ class BaseView(object):
...
@@ -296,11 +298,20 @@ class BaseView(object):
result
=
(
btn_close
,)
result
=
(
btn_close
,)
return
result
return
result
def
before_view
(
self
,
**
kw
):
return
False
def
view_view
(
self
,
**
kwargs
):
# row = query_id(request).first()
def
view_view
(
self
,
**
kwargs
):
# row = query_id(request).first()
request
=
self
.
req
request
=
self
.
req
row
=
self
.
query_id
()
.
first
()
row
=
self
.
query_id
()
.
first
()
if
not
row
:
if
not
row
:
return
self
.
id_not_found
()
return
self
.
id_not_found
()
before_view
=
self
.
before_view
(
row
=
row
)
if
before_view
:
return
before_view
bindings
=
self
.
get_bindings
(
row
)
bindings
=
self
.
get_bindings
(
row
)
buttons
=
kwargs
.
get
(
"buttons"
,
None
)
buttons
=
kwargs
.
get
(
"buttons"
,
None
)
if
not
buttons
:
if
not
buttons
:
...
@@ -339,7 +350,11 @@ class BaseView(object):
...
@@ -339,7 +350,11 @@ class BaseView(object):
buttons
=
(
btn_post
,
btn_close
)
buttons
=
(
btn_post
,
btn_close
)
return
self
.
view_view
(
buttons
=
buttons
)
return
self
.
view_view
(
buttons
=
buttons
)
def
view_upload
(
self
,
exts
=
(
'.png'
,
'.ico'
),
**
args
):
def
view_upload
(
self
,
**
kw
):
exts
=
kw
.
get
(
"exts"
)
if
not
exts
:
exts
=
self
.
upload_exts
delimiter
=
args
.
get
(
"delimiter"
)
delimiter
=
args
.
get
(
"delimiter"
)
bindings
=
self
.
get_bindings
()
bindings
=
self
.
get_bindings
()
form
=
self
.
get_form
(
self
.
upload_schema
,
bindings
=
bindings
)
form
=
self
.
get_form
(
self
.
upload_schema
,
bindings
=
bindings
)
...
@@ -516,6 +531,9 @@ class BaseView(object):
...
@@ -516,6 +531,9 @@ class BaseView(object):
else
:
else
:
return
self
.
next_act
(
**
kwargs
)
return
self
.
next_act
(
**
kwargs
)
def
get_captcha_url
(
self
):
return
get_urls
(
"/captcha/"
)
+
get_captcha
(
self
.
req
)
def
view_add
(
self
,
**
kwargs
):
def
view_add
(
self
,
**
kwargs
):
# bindings = self.get_bindings()
# bindings = self.get_bindings()
form
=
self
.
get_form
(
self
.
add_schema
,
**
kwargs
)
form
=
self
.
get_form
(
self
.
add_schema
,
**
kwargs
)
...
@@ -538,6 +556,8 @@ class BaseView(object):
...
@@ -538,6 +556,8 @@ class BaseView(object):
if
isinstance
(
f
.
typ
,
colander
.
Date
):
if
isinstance
(
f
.
typ
,
colander
.
Date
):
e
.
cstruct
[
f
.
name
]
=
date_from_str
(
e
.
cstruct
[
f
.
name
]
=
date_from_str
(
e
.
cstruct
[
f
.
name
])
e
.
cstruct
[
f
.
name
])
if
f
.
name
==
"captcha"
:
e
.
cstruct
[
f
.
name
]
=
self
.
get_captcha_url
()
form
.
set_appstruct
(
e
.
cstruct
)
form
.
set_appstruct
(
e
.
cstruct
)
return
self
.
returned_form
(
form
,
table
,
**
kwargs
)
return
self
.
returned_form
(
form
,
table
,
**
kwargs
)
...
@@ -703,8 +723,9 @@ class BaseView(object):
...
@@ -703,8 +723,9 @@ class BaseView(object):
def
query_id
(
self
):
def
query_id
(
self
):
q
=
self
.
db_session
.
query
(
self
.
table
)
.
filter_by
(
q
=
self
.
db_session
.
query
(
self
.
table
)
.
filter_by
(
id
=
self
.
req
.
matchdict
[
'id'
])
id
=
self
.
req
.
matchdict
[
'id'
])
if
hasattr
(
self
.
table
,
'company_id'
)
and
self
.
req
.
user
.
company_id
:
if
self
.
req
.
user
:
q
=
q
.
filter_by
(
company_id
=
self
.
req
.
user
.
company_id
)
if
hasattr
(
self
.
table
,
'company_id'
)
and
self
.
req
.
user
.
company_id
:
q
=
q
.
filter_by
(
company_id
=
self
.
req
.
user
.
company_id
)
return
q
return
q
def
filter_company
(
self
,
query
):
def
filter_company
(
self
,
query
):
...
...
opensipkd/base/views/partner.py
View file @
324d8d6
...
@@ -2,17 +2,17 @@ import colander
...
@@ -2,17 +2,17 @@ import colander
from
deform
import
(
from
deform
import
(
widget
,
Button
,
widget
,
Button
,
)
)
from
pyramid.i18n
import
TranslationStringFactory
from
pyramid.view
import
(
view_config
,
)
from
opensipkd.base
import
get_id_card_folder
from
opensipkd.base
import
get_id_card_folder
from
opensipkd.models
import
DBSession
,
Partner
from
opensipkd.models
import
DBSession
,
Partner
from
opensipkd.models
import
(
from
opensipkd.models
import
(
ResProvinsi
,
ResDati2
,
ResKecamatan
,
ResDesa
)
ResProvinsi
,
ResDati2
,
ResKecamatan
,
ResDesa
)
from
opensipkd.models.common
import
ResCompany
from
opensipkd.models.common
import
ResCompany
from
opensipkd.tools
import
Upload
,
img_exts
from
opensipkd.tools
import
Upload
,
img_exts
from
pyramid.i18n
import
TranslationStringFactory
from
pyramid.view
import
(
view_config
,
)
from
.company
import
company_widget
from
.company
import
company_widget
from
.partner_base
import
PartnerSchema
from
.partner_base
import
PartnerSchema
# from .. import partner_idcard_url
# from .. import partner_idcard_url
...
@@ -243,6 +243,7 @@ class ViewPartner(BaseView):
...
@@ -243,6 +243,7 @@ class ViewPartner(BaseView):
value
[
"status"
]
=
'status'
in
value
and
value
[
'status'
]
and
1
or
0
value
[
"status"
]
=
'status'
in
value
and
value
[
'status'
]
and
1
or
0
def
get_bindings
(
self
,
row
=
None
):
def
get_bindings
(
self
,
row
=
None
):
result
=
super
()
.
get_bindings
(
row
)
provinsi_list
=
ResProvinsi
.
get_list
()
provinsi_list
=
ResProvinsi
.
get_list
()
dati2_list
=
row
and
row
.
provinsi_id
and
ResDati2
.
get_list
(
dati2_list
=
row
and
row
.
provinsi_id
and
ResDati2
.
get_list
(
row
.
provinsi_id
)
or
[]
row
.
provinsi_id
)
or
[]
...
@@ -250,17 +251,19 @@ class ViewPartner(BaseView):
...
@@ -250,17 +251,19 @@ class ViewPartner(BaseView):
row
.
dati2_id
)
or
[]
row
.
dati2_id
)
or
[]
desa_list
=
row
and
row
.
kecamatan_id
and
ResDesa
.
get_list
(
desa_list
=
row
and
row
.
kecamatan_id
and
ResDesa
.
get_list
(
row
.
kecamatan_id
)
or
[]
row
.
kecamatan_id
)
or
[]
re
turn
dict
(
re
sult
.
update
(
dict
(
provinsi_list
=
provinsi_list
,
provinsi_list
=
provinsi_list
,
dati2_list
=
dati2_list
,
dati2_list
=
dati2_list
,
kecamatan_list
=
kecamatan_list
,
kecamatan_list
=
kecamatan_list
,
desa_list
=
desa_list
,
desa_list
=
desa_list
,
company_list
=
ResCompany
.
get_list
()
company_list
=
ResCompany
.
get_list
()
)
))
return
result
def
save_request
(
self
,
values
,
row
=
None
):
def
save_request
(
self
,
values
,
row
=
None
):
if
"idcard"
in
values
and
values
[
"idcard"
]:
if
"idcard"
in
values
and
values
[
"idcard"
]:
if
str
(
self
.
req
.
POST
[
'upload'
]
.
decode
(
'utf-8'
)
)
!=
""
:
if
str
(
self
.
req
.
POST
[
'upload'
])
!=
""
:
folder
=
self
.
get_params
(
"idcard_folder"
,
'/tmp/idcard'
)
folder
=
self
.
get_params
(
"idcard_folder"
,
'/tmp/idcard'
)
upload
=
Upload
(
folder
)
upload
=
Upload
(
folder
)
file_name
=
upload
.
save
(
self
.
req
,
'upload'
,
img_exts
)
file_name
=
upload
.
save
(
self
.
req
,
'upload'
,
img_exts
)
...
@@ -288,4 +291,4 @@ class ViewPartner(BaseView):
...
@@ -288,4 +291,4 @@ class ViewPartner(BaseView):
@colander.deferred
@colander.deferred
def
partner_widget
(
node
,
kw
):
def
partner_widget
(
node
,
kw
):
values
=
kw
.
get
(
'partner_list'
,
[])
values
=
kw
.
get
(
'partner_list'
,
[])
return
widget
.
Select2Widget
(
values
=
values
)
return
widget
.
Select2Widget
(
values
=
values
)
\ No newline at end of file
\ No newline at end of file
opensipkd/base/views/partner_base.py
View file @
324d8d6
...
@@ -5,15 +5,70 @@ from opensipkd.base.views.dati2 import dati2_widget
...
@@ -5,15 +5,70 @@ from opensipkd.base.views.dati2 import dati2_widget
from
opensipkd.base.views.desa
import
desa_widget
from
opensipkd.base.views.desa
import
desa_widget
from
opensipkd.base.views.kecamatan
import
kecamatan_widget
from
opensipkd.base.views.kecamatan
import
kecamatan_widget
from
opensipkd.base.views.provinsi
import
provinsi_widget
from
opensipkd.base.views.provinsi
import
provinsi_widget
from
opensipkd.models
import
Partner
from
opensipkd.tools
import
mem_tmp_store
from
opensipkd.tools
import
mem_tmp_store
from
translationstring
import
TranslationStringFactory
from
..
import
get_urls
from
..
import
get_urls
from
.
import
Validator
_
=
TranslationStringFactory
(
'partner'
)
class
PartnerEmailValidator
(
colander
.
Email
,
Validator
):
def
__init__
(
self
,
row
):
Validator
.
__init__
(
self
,
row
)
colander
.
Email
.
__init__
(
self
)
def
__call__
(
self
,
node
,
value
):
def
email_found
():
data
=
dict
(
email
=
email
,
rid
=
found
.
id
,
rname
=
found
.
nama
)
ts
=
_
(
'email-already-used'
,
default
=
'Email ${email} already used by Partner ID ${rid}: ${rname}'
,
mapping
=
data
)
raise
colander
.
Invalid
(
node
,
ts
)
if
self
.
match_object
.
match
(
value
)
is
None
:
raise
colander
.
Invalid
(
node
,
_
(
'Invalid email format'
))
email
=
value
.
lower
()
q
=
Partner
.
query
()
.
filter_by
(
email
=
email
)
found
=
q
.
first
()
if
found
and
(
not
self
.
row
or
self
.
row
.
email
!=
found
.
email
):
email_found
()
@colander.deferred
def
partner_email_validator
(
node
,
kw
):
return
PartnerEmailValidator
(
kw
[
'row'
])
class
PartnerKodeValidator
(
Validator
):
def
__init__
(
self
,
row
):
Validator
.
__init__
(
self
,
row
)
def
__call__
(
self
,
node
,
value
):
def
err_found
():
data
=
dict
(
kode
=
val
,
rid
=
found
.
id
,
rnama
=
found
.
nama
)
ts
=
_
(
'kode-already-used'
,
default
=
'Kode ${kode} already used by Partner ID ${rid}: ${rnama}'
,
mapping
=
data
)
raise
colander
.
Invalid
(
node
,
ts
)
val
=
value
q
=
Partner
.
query
()
.
filter_by
(
kode
=
val
)
found
=
q
.
first
()
if
found
and
(
not
self
.
row
or
self
.
row
.
kode
!=
found
.
kode
):
err_found
()
@colander.deferred
def
partner_kode_validator
(
node
,
kw
):
return
PartnerKodeValidator
(
kw
[
'row'
])
class
NamaSchema
(
colander
.
Schema
):
class
NamaSchema
(
colander
.
Schema
):
kode
=
colander
.
SchemaNode
(
kode
=
colander
.
SchemaNode
(
colander
.
String
(),
colander
.
String
(),
validator
=
colander
.
Length
(
max
=
32
)
,
validator
=
partner_kode_validator
,
oid
=
"kode"
,
oid
=
"kode"
,
title
=
"Kode"
,
title
=
"Kode"
,
width
=
"100pt"
)
width
=
"100pt"
)
...
@@ -21,7 +76,10 @@ class NamaSchema(colander.Schema):
...
@@ -21,7 +76,10 @@ class NamaSchema(colander.Schema):
colander
.
String
(),
colander
.
String
(),
validator
=
colander
.
Length
(
max
=
64
),
validator
=
colander
.
Length
(
max
=
64
),
oid
=
"nama"
)
oid
=
"nama"
)
email
=
colander
.
SchemaNode
(
colander
.
String
(),
validator
=
partner_email_validator
,
oid
=
"email"
)
class
PartnerSchema
(
NamaSchema
):
class
PartnerSchema
(
NamaSchema
):
nip
=
colander
.
SchemaNode
(
nip
=
colander
.
SchemaNode
(
...
@@ -103,10 +161,7 @@ class PartnerSchema(NamaSchema):
...
@@ -103,10 +161,7 @@ class PartnerSchema(NamaSchema):
missing
=
colander
.
drop
,
missing
=
colander
.
drop
,
title
=
"Desa/Kelurahan"
,
title
=
"Desa/Kelurahan"
,
oid
=
"desa_id"
)
oid
=
"desa_id"
)
email
=
colander
.
SchemaNode
(
colander
.
String
(),
validator
=
colander
.
Length
(
max
=
128
),
oid
=
"email"
)
phone
=
colander
.
SchemaNode
(
phone
=
colander
.
SchemaNode
(
colander
.
String
(),
colander
.
String
(),
validator
=
colander
.
Length
(
max
=
16
),
validator
=
colander
.
Length
(
max
=
16
),
...
@@ -136,4 +191,4 @@ class PartnerSchema(NamaSchema):
...
@@ -136,4 +191,4 @@ class PartnerSchema(NamaSchema):
prefix
=
get_urls
(
request
.
route_url
(
"home"
))
prefix
=
get_urls
(
request
.
route_url
(
"home"
))
self
[
"provinsi_id"
]
.
slave_url
=
f
"{prefix}/dati2/select/act?provinsi_id="
self
[
"provinsi_id"
]
.
slave_url
=
f
"{prefix}/dati2/select/act?provinsi_id="
self
[
"dati2_id"
]
.
slave_url
=
f
"{prefix}/kecamatan/select/act?dati2_id="
self
[
"dati2_id"
]
.
slave_url
=
f
"{prefix}/kecamatan/select/act?dati2_id="
self
[
"kecamatan_id"
]
.
slave_url
=
f
"{prefix}/desa/select/act?kecamatan_id="
self
[
"kecamatan_id"
]
.
slave_url
=
f
"{prefix}/desa/select/act?kecamatan_id="
\ No newline at end of file
\ No newline at end of file
opensipkd/base/views/widgets/captcha.pt
View file @
324d8d6
...
@@ -22,4 +22,4 @@
...
@@ -22,4 +22,4 @@
});
});
</script>
</script>
</span>
</span>
\ No newline at end of file
\ No newline at end of file
opensipkd/base/views/widgets/file_upload.pt
View file @
324d8d6
<tal:block tal:define="oid oid|field.oid;
<tal:block tal:define="oid oid|field.oid;
css_class css_class|field.widget.css_class;
css_class css_class|field.widget.css_class;
style style|field.widget.style;
style style|field.widget.style;
preview_url cstruct.get('preview_url')|'';
preview_url cstruct.get('preview_url')|'';
ext str(cstruct.get('filename').split('.')[-1:][0]).lower()|[];
ext str(cstruct.get('filename').split('.')[-1:][0]).lower()|[];
fname str(cstruct.get('filename'))|'';
fname str(cstruct.get('filename'))|'';
delete cstruct.get('delete')|'';
delete cstruct.get('delete')|'';
maxsize field.widget.size|5242880;">
maxsize field.widget.size|5242880;
${field.start_mapping()}
img ['jpg', 'jpeg', 'gif', 'png', 'svg', 'eps', 'psd'];
<img id="preview-${oid}" alt="" src="${preview_url}" style="width:100px;height:auto;display:block;"
video ['avi', 'mov', 'mpv']
onload="window.URL.revokeObjectURL(this.src);"></img>
">
<a id="label-${oid}" tal:condition="preview_url" class="label label-default" href="${preview_url}"
${field.start_mapping()}
target="_blank"><i class="fa fa-search"></i> View</a>
<img tal:condition="ext in img" id="preview-${oid}" alt="" src="${preview_url}"
<input type="file" name="upload" id="${oid}"
style="width:100px;height:auto;display:block;"
tal:attributes="style style;
onload="window.URL.revokeObjectURL(this.src);"></img>
accept accept|field.widget.accept;
<video tal:condition="ext in video" width="100%" height="100%" controls
data-filename fname;
src="${preview_url}" type="video/${ext}">
attributes|field.widget.attributes|{};"/>
Your browser does not support the video tag.
<input tal:define="uid cstruct.get('uid')"
</video>
tal:condition="uid"
type="hidden" name="uid" value="${uid}"/>
<video tal:condition="ext=='mp4'" width="100%" height="100%" controls
${field.end_mapping()}
src="${preview_url}" type="video/mp4">
<script type="text/javascript">
Your browser does not support the video tag.
deform.addCallback('${oid}', function (oid) {
</video>
$('#' + oid).upload();
});
<embed tal:condition="ext=='pdf'" src="${preview_url}" width="100%" height="400">
document.getElementById("${oid}").onchange = function() {
if(this.files[0].size > ${maxsize}){
<a id="label-${oid}" tal:condition="preview_url" class="label label-default" href="${preview_url}"
alert("File is too big!");
target="_blank"><i class="fa fa-search"></i> View</a>
this.value = "";
document.getElementById('preview-'+this.id).src = '';
<input type="file" name="upload" id="${oid}"
}
tal:attributes="style style;
document.getElementById('preview-'+this.id).src = window.URL.createObjectURL(this.files[0]);
accept accept|field.widget.accept;
document.getElementById('labeldelete-'+this.id).remove();
data-filename fname;
document.getElementById('label-'+this.id).remove();
attributes|field.widget.attributes|{};"/>
};
<input tal:define="uid cstruct.get('uid')"
</script>
tal:condition="uid"
</tal:block>
type="hidden" name="uid" value="${uid}"/>
${field.end_mapping()}
<script type="text/javascript">
deform.addCallback('${oid}', function (oid) {
$('#' + oid).upload();
});
document.getElementById("${oid}").onchange = function () {
if (this.files[0].size > ${maxsize}) {
alert("File is too big!");
this.value = "";
document.getElementById('preview-' + this.id).src = '';
}
document.getElementById('preview-' + this.id).src = window.URL.createObjectURL(this.files[0]);
document.getElementById('labeldelete-' + this.id).remove();
document.getElementById('label-' + this.id).remove();
};
</script>
</tal:block>
\ No newline at end of file
\ No newline at end of file
opensipkd/base/views/widgets/form.pt
View file @
324d8d6
...
@@ -41,6 +41,7 @@
...
@@ -41,6 +41,7 @@
<div tal:repeat="child field"
<div tal:repeat="child field"
tal:replace="structure child.render_template(item_template)"/>
tal:replace="structure child.render_template(item_template)"/>
</div>
</div>
<div class="row">
<div class="row">
<div class="form-group deform-form-buttons">
<div class="form-group deform-form-buttons">
<tal:loop tal:repeat="button buttons">
<tal:loop tal:repeat="button buttons">
...
@@ -105,4 +106,4 @@
...
@@ -105,4 +106,4 @@
);
);
</script>
</script>
</form>
</form>
\ No newline at end of file
\ No newline at end of file
opensipkd/models/partner.py
View file @
324d8d6
...
@@ -5,11 +5,12 @@ from sqlalchemy import (
...
@@ -5,11 +5,12 @@ from sqlalchemy import (
SmallInteger
,
SmallInteger
,
DateTime
,
ForeignKey
DateTime
,
ForeignKey
)
)
from
sqlalchemy.orm
import
Mapped
,
mapped_column
,
relationship
from
sqlalchemy.orm
import
backref
from
.common
import
NamaModel
from
.base
import
NamaModel
,
StandarModel
from
.wilayah
import
ResProvinsi
,
ResDesa
,
ResKecamatan
,
ResDati2
from
.meta
import
(
Base
)
from
.meta
import
(
Base
)
from
sqlalchemy.orm
import
relationship
,
backref
from
.wilayah
import
ResProvinsi
,
ResDesa
,
ResKecamatan
,
ResDati2
class
PartnerModel
(
NamaModel
):
class
PartnerModel
(
NamaModel
):
...
@@ -76,6 +77,7 @@ class Partner(Base, PartnerModel):
...
@@ -76,6 +77,7 @@ class Partner(Base, PartnerModel):
"ResKecamatan"
,
backref
=
backref
(
'partner'
))
"ResKecamatan"
,
backref
=
backref
(
'partner'
))
res_desa
=
relationship
(
res_desa
=
relationship
(
"ResDesa"
,
backref
=
backref
(
'partner'
))
"ResDesa"
,
backref
=
backref
(
'partner'
))
partner_files
:
Mapped
[
"PartnerFiles"
]
=
relationship
(
back_populates
=
"partner"
)
# npwp = Column(String(16))
# npwp = Column(String(16))
# npwpd = Column(String(16))
# npwpd = Column(String(16))
...
@@ -97,7 +99,15 @@ class Partner(Base, PartnerModel):
...
@@ -97,7 +99,15 @@ class Partner(Base, PartnerModel):
row
=
cls
.
query
()
.
filter_by
(
mobile
=
ident
)
.
first
()
row
=
cls
.
query
()
.
filter_by
(
mobile
=
ident
)
.
first
()
return
row
return
row
class
PartnerFiles
(
Base
,
StandarModel
):
__tablename__
=
'partner_files'
partner_id
:
Mapped
[
int
]
=
mapped_column
(
ForeignKey
(
Partner
.
id
))
file_name
:
Mapped
[
str
]
=
mapped_column
(
String
(
256
))
description
:
Mapped
[
str
]
=
mapped_column
(
String
(
256
),
nullable
=
True
)
partner
:
Mapped
[
"Partner"
]
=
relationship
(
back_populates
=
"partner_files"
)
# class PartnerUserModel(Base, DefaultModel):
# class PartnerUserModel(Base, DefaultModel):
# __tablename__ = 'partner_user'
# __tablename__ = 'partner_user'
# partner_id = Column(Integer, ForeignKey(Partner.id))
# partner_id = Column(Integer, ForeignKey(Partner.id))
# user_id = Column(Integer, ForeignKey(User.id))
# user_id = Column(Integer, ForeignKey(User.id))
\ No newline at end of file
\ No newline at end of file
Write
Preview
Markdown
is supported
Attach a file
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to post a comment