Commit cd4afcc7 by aa.gusti

update registrasi

1 parent a162349c
...@@ -417,11 +417,14 @@ def main(global_config, **settings): ...@@ -417,11 +417,14 @@ def main(global_config, **settings):
config.add_static_view('static', 'opensipkd.base:static', cache_max_age=3600) config.add_static_view('static', 'opensipkd.base:static', cache_max_age=3600)
config.add_static_view('deform_static', 'deform:static') config.add_static_view('deform_static', 'deform:static')
# config.add_static_view('files', get_params('static_files')) # config.add_static_view('files', get_params('static_files'))
# config.add_static_view('captcha', get_params('captcha_files')) # Captcha
captcha_files = get_params('captcha_files', '/tmp/captcha')
if not os.path.exists(captcha_files):
os.makedirs(captcha_files)
config.add_static_view('captcha',captcha_files )
# config.add_static_view('tts', path=get_params('tts_files')) # config.add_static_view('tts', path=get_params('tts_files'))
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())
# dipindahkan ke config pyramid.include # dipindahkan ke config pyramid.include
# config.include('pyramid_rpc.jsonrpc') # config.include('pyramid_rpc.jsonrpc')
......
from datetime import (datetime) import os
from pyramid.httpexceptions import HTTPFound
from pyramid.view import view_config
from ..views import BaseView
import colander
from deform import (Form, widget, ValidationFailure, Button)
from email.utils import parseaddr from email.utils import parseaddr
from ..models import User, DBSession, Partner, Group, UserGroup
from opensipkd.base.views.user_login import send_email_security_code import colander
from opensipkd.base.views.user import insert as save_user, add_member_count from deform import (Form, widget, ValidationFailure, Button, FileData)
from pyramid.i18n import TranslationStringFactory from opensipkd.base import get_params
from opensipkd.tools import get_settings
from opensipkd.tools import get_settings, get_ext, Upload
from opensipkd.tools.captcha import get_captcha from opensipkd.tools.captcha import get_captcha
from pyramid.httpexceptions import HTTPFound
from pyramid.i18n import TranslationStringFactory
from pyramid.view import view_config
from ziggurat_foundations.models.services.user import UserService from ziggurat_foundations.models.services.user import UserService
from opensipkd.base.views.user import insert as save_user
from opensipkd.base.views.user_login import send_email_security_code
from .user_group import save as save_groups from .user_group import save as save_groups
from ..models import User, DBSession, Partner, Group, UserGroup
from ..views import BaseView
_ = TranslationStringFactory('user') _ = TranslationStringFactory('user')
...@@ -46,6 +50,15 @@ class NamaSchema(colander.Schema): ...@@ -46,6 +50,15 @@ class NamaSchema(colander.Schema):
oid="email") oid="email")
class Store(dict):
def preview_url(self, name):
return ""
store = Store()
reg_exts = ['.png', '.jpg', '.pdf', '.jpeg']
class RegSchema(colander.Schema): class RegSchema(colander.Schema):
kode = colander.SchemaNode( kode = colander.SchemaNode(
colander.String(), colander.String(),
...@@ -54,16 +67,28 @@ class RegSchema(colander.Schema): ...@@ -54,16 +67,28 @@ class RegSchema(colander.Schema):
title="No.Identitas/NIK", title="No.Identitas/NIK",
oid="kode") oid="kode")
detail = NamaSchema() detail = NamaSchema()
captcha = colander.SchemaNode(
colander.String(), doc_id_card = colander.SchemaNode(
oid="captcha") FileData(),
widget=widget.FileUploadWidget(store))
# captcha = colander.SchemaNode(
# colander.String(),
# oid="captcha")
def after_bin(self, schema, kwargs):
request = kwargs["request"]
if get_params('reg_idcard') != '1':
del self["doc_id_card"]
if get_params('reg_captcha') != '1':
del self["captcha"]
class RegEditSchema(colander.Schema): class RegEditSchema(colander.Schema):
kode = colander.SchemaNode( kode = colander.SchemaNode(
colander.String(), colander.String(),
widget=widget.TextInputWidget(readonly=True), widget=widget.TextInputWidget(readonly=True),
title="NIK", title="No.Identitas/NIK",
oid="kode") oid="kode")
detail = NamaSchema() detail = NamaSchema()
password = colander.SchemaNode( password = colander.SchemaNode(
...@@ -76,16 +101,23 @@ class RegEditSchema(colander.Schema): ...@@ -76,16 +101,23 @@ class RegEditSchema(colander.Schema):
missing=colander.drop, missing=colander.drop,
widget=widget.HiddenWidget(readonly=True), widget=widget.HiddenWidget(readonly=True),
) )
doc_id_card = colander.SchemaNode(
FileData(),
widget=widget.String())
def after_bin(self, schema, kwargs): def after_bin(self, schema, kwargs):
request = kwargs["request"] request = kwargs["request"]
self.kode["widget"] = widget.TextInputWidget(readonly=True)
if "kode" not in request.params: if "kode" not in request.params:
self.kode["widget"] = widget.TextInputWidget() self.kode["widget"] = widget.TextInputWidget()
if "email" in request.params: if "email" in request.params:
print(self.detail)
self.detail.email["widget"] = widget.TextInputWidget(readonly=True) self.detail.email["widget"] = widget.TextInputWidget(readonly=True)
self.detail.email["missing"] = colander.drop self.detail.email["missing"] = colander.drop
if request.get_params('reg_id_card') != '0':
del self["doc_id_card"]
def email_found_user(email): def email_found_user(email):
return User.get_by_identity(email) return User.get_by_identity(email)
...@@ -111,11 +143,10 @@ def show_error(request, msg): ...@@ -111,11 +143,10 @@ def show_error(request, msg):
_show_error(request, msg) _show_error(request, msg)
return HTTPFound(location=request.route_url('home')) return HTTPFound(location=request.route_url('home'))
# Validasi saat Register
# Validasi saat Register # 1. Cek email pada Users jika ada dan Users.id beda reject
# 1. Cek email pada Users jika ada dan Users.id beda reject # 2. Cek email pada Partner jika ada dan Partner.id beda reject
# 2. Cek email pada Partner jika ada dan Partner.id beda reject # 3. Cek NIK (kode) pada Partner jika ada dan Partner.id beda reject
# 3. Cek NIK (kode) pada Partner jika ada dan Partner.id beda reject
def form_validator(form, value): def form_validator(form, value):
...@@ -123,20 +154,23 @@ def form_validator(form, value): ...@@ -123,20 +154,23 @@ def form_validator(form, value):
def err_captcha(): def err_captcha():
msg = 'Captcha harus diisi' msg = 'Captcha harus diisi'
raise colander.Invalid(form, msg) raise colander.Invalid(form['captcha'], msg)
def err_email(): def err_email():
raise colander.Invalid( raise colander.Invalid(
form, 'e-mail %s sudah ada yang menggunakan' % value['email']) form['detail']['email'], 'e-mail %s sudah ada yang menggunakan' % value['email'])
def err_nik(): def err_nik():
raise colander.Invalid( raise colander.Invalid(
form, 'NIK %s sudah ada yang menggunakan' % value['kode']) form['kode'], 'NIK %s sudah ada yang menggunakan' % value['kode'])
def err_login(): def err_login():
raise colander.Invalid( raise colander.Invalid(
form, 'User atau Password tidak sesuai') form, 'User atau Password tidak sesuai')
def err_file():
raise colander.Invalid(form, f'Extension harus salahsatu dari {reg_exts}')
request = form.request request = form.request
# Cek Login # Cek Login
if 'password' in value: if 'password' in value:
...@@ -145,14 +179,15 @@ def form_validator(form, value): ...@@ -145,14 +179,15 @@ def form_validator(form, value):
err_login() err_login()
if not request.user: if not request.user:
if 'captcha' not in value or not value['captcha'] \ if get_params("reg_captcha") == '1':
or 'captcha' not in request.session or not request.session['captcha']: if 'captcha' not in value or not value['captcha'] \
err_captcha() or 'captcha' not in request.session or not request.session['captcha']:
err_captcha()
captcha = 'captcha' in value and value['captcha'].upper() or None captcha = 'captcha' in value and value['captcha'].upper() or None
if not captcha or captcha != request.session['captcha']: if not captcha or captcha != request.session['captcha']:
err_captcha() err_captcha()
if 'id' in request.matchdict: if 'id' in request.matchdict:
uid = request.matchdict['id'] uid = request.matchdict['id']
...@@ -160,6 +195,7 @@ def form_validator(form, value): ...@@ -160,6 +195,7 @@ def form_validator(form, value):
partner = q.first() partner = q.first()
else: else:
partner = None partner = None
detail = value['detail'] detail = value['detail']
email = detail['email'] email = detail['email']
...@@ -188,12 +224,17 @@ def form_validator(form, value): ...@@ -188,12 +224,17 @@ def form_validator(form, value):
if user and form.request.user: if user and form.request.user:
if user.id != form.request.user.id: if user.id != form.request.user.id:
err_email() err_email()
if 'doc_id_card' in value:
ext = get_ext(value["doc_id_card"]["filename"])
if ext not in reg_exts:
err_file()
def get_form(request, class_form, buttons=('batal', 'simpan'), def get_form(request, class_form, buttons=('batal', 'simpan'),
validator=form_validator): validator=form_validator):
schema = class_form(validator=validator) schema = class_form(validator=validator)
schema = schema.bind(request = request) schema = schema.bind(request=request)
schema.request = request
return Form(schema, buttons=buttons) return Form(schema, buttons=buttons)
...@@ -280,7 +321,7 @@ def reg_buttons(): ...@@ -280,7 +321,7 @@ def reg_buttons():
class RegistrasiAdd(BaseView): class RegistrasiAdd(BaseView):
@view_config(route_name='register', renderer='templates/form_input.pt') @view_config(route_name='register', renderer='templates/register.pt')
def view_add(self): def view_add(self):
request = self.req request = self.req
if request.user: if request.user:
...@@ -289,23 +330,36 @@ class RegistrasiAdd(BaseView): ...@@ -289,23 +330,36 @@ class RegistrasiAdd(BaseView):
return HTTPFound(location=request.route_url("profile")) return HTTPFound(location=request.route_url("profile"))
form = get_form(request, RegSchema, reg_buttons()) form = get_form(request, RegSchema, reg_buttons())
captcha = get_params("reg_captcha") and get_captcha(request) or None
if request.POST: if request.POST:
if 'register' in request.POST: if 'register' in request.POST:
# input_file = request.POST['upload'].file
# filename = request.POST['upload'].filename.lower()
# ext = get_ext(filename).lower()
# raise ext
controls = request.POST.items() controls = request.POST.items()
try: try:
controls = form.validate(controls) controls = form.validate(controls)
except ValidationFailure as e: except ValidationFailure as e:
form.set_appstruct(e.cstruct) form.set_appstruct(e.cstruct)
return dict(form=form, captcha=get_captcha(request)) return dict(form=form.render(), captcha=captcha, scripts="")
values = dict(controls)
path = get_params('reg_folder', '/tmp/registrasi')
if not os.path.exists(path):
os.makedirs(path)
save_request(dict(controls), request) upload = Upload(path)
values["doc_id_card"] = upload.save(request, 'upload')
save_request(values, request)
request.session.flash('Registrasi Sukses.') request.session.flash('Registrasi Sukses.')
if 'captcha' in request.session: if 'captcha' in request.session:
del (request.session['captcha']) del (request.session['captcha'])
return route_list(request) return route_list(request)
values = {} values = {}
if request.user: if request.user:
values['email'] = request.user.email values['email'] = request.user.email
...@@ -314,7 +368,7 @@ class RegistrasiAdd(BaseView): ...@@ -314,7 +368,7 @@ class RegistrasiAdd(BaseView):
return dict(form=form.render(), captcha=get_captcha(request), return dict(form=form.render(), captcha=get_captcha(request),
scripts="") scripts="")
@view_config(route_name='profile', renderer='templates/form_input.pt', @view_config(route_name='profile', renderer='templates/register.pt',
permission='view') permission='view')
def es_reg_edt(self): def es_reg_edt(self):
request = self.req request = self.req
......
<!DOCTYPE html> <!DOCTYPE html>
<html lang="en-us" <html lang="en-us"
tal:define=" tal:define="home request.route_url('home')[:-1];
home request.route_url('home')[:-1];
user_path ['user', 'user-add', 'user-edit', 'user-view', 'user-delete']; user_path ['user', 'user-add', 'user-edit', 'user-view', 'user-delete'];
group_path ['group', 'group-add', 'group-edit', 'group-view', 'group-delete']; group_path ['group', 'group-add', 'group-edit', 'group-view', 'group-delete'];
param_path ['parameter', 'parameter-add', 'parameter-edit', 'parameter-view', 'parameter-delete']; param_path ['parameter', 'parameter-add', 'parameter-edit', 'parameter-view', 'parameter-delete'];
......
<html metal:use-macro="load: ./base3.1.pt"> <html metal:use-macro="load: ./base3.1.pt">
<div metal:fill-slot="content"> <div metal:fill-slot="content">
<div class="panel panel-default"> <div class="panel panel-default">
<div class="panel-heading"> <div class="panel-heading">
<h3 class="panel-title"><i class="fa fa-fw fa-plus"></i>&nbsp;${request.title}</h3> <h3 class="panel-title"><i class="fa fa-fw fa-plus"></i>&nbsp;${request.title}</h3>
</div>
<div class="panel-body">
<div tal:content="structure form"></div>
</div>
</div> </div>
<div class="panel-body">
<div tal:content="structure form"></div>
</div>
</div>
</div> </div>
<script metal:fill-slot="scripts">
$(document).ready(function () {
$(".read-only").attr("readonly", true);
$(".readonly").attr("readonly", true);
$(".date").attr("readonly", true);
$(".date").datepicker({
format: 'dd-mm-yyyy'
});
${structure:scripts}
});
</script> <div metal:fill-slot="scripts">
<script>
$(document).ready(function () {
$(".read-only").attr("readonly", true);
$(".readonly").attr("readonly", true);
$(".date").attr("readonly", true);
$(".date").datepicker({
format: 'dd-mm-yyyy'
});
${structure:scripts}
});
</script>
<div metal:define-slot="scripts">
</div>
</div>
</html> </html>
<html metal:use-macro="load: form_inout.pt">
<div metal:fill-slot="content">
<style>
button {
margin: 0px 3px;
}
</style>
<!-- Tampilan untuk general error -->
<div tal:define="field form" class="alert alert-danger" tal:condition="field.error">
<div class="errorMsgLbl" i18n:translate="">
Terdapat kesalahan pengisian
</div>
<p class="errorMsg">${field.errormsg}</p>
</div>
<!-- END Tampilan untuk general error -->
<div class="panel-body">
<!-- Proses Template Form -->
<form method="post" accept-charset="utf-8" id="deform" class="form-horizontal"
enctype="multipart/form-data"
style="background-color:white;">
<input type="hidden" name="_charset_">
<input type="hidden" value="deform" name="__formid__">
<div class="col-md-6 col-md-offset-3 col-xs-12 well">
<div class="col-md-12">
<!-- Looping Semua Field-->
<div tal:repeat="f form">
<!-- Proses Saat Field hidden-->
<div tal:condition="f.widget.hidden">
${structure:f.serialize()}
</div>
<!-- Proses Saat Field Normal dan bukan Children-->
<div tal:condition="not f.widget.hidden and not f.children"
class="form-group">
<!-- Field Reqired menggunakan class required -->
<label for="${f.oid}"
class="control-label col-md-4 ${f.required and 'required' or ''}"
id="req-${f.oid}">
${f.title}</label>
<div class="col-md-8">
${structure:f.serialize()}
<p id="error-${f.oid}" class="help-block" tal:condition="f.error"
tal:repeat="error f.error.messages()">
${error}</p>
</div>
</div>
<!-- Proses saat Form Adalah Children -->
<div tal:condition="f.children">
<!--div class="panel panel-default" title="">
<div class="panel-heading">${f.title}</div>
<div class="panel-body" -->
<input type="hidden"
name="__start__"
value="${f.name}:mapping"
readonly="readonly">
<div class="form-group" tal:repeat="f2 f.children">
<div id="item-${f2.oid}">
<label for="${f2.oid}" id="req-${f2.oid}"
class="control-label col-md-4 ${f2.required and 'required' or ''}">
${f2.title}</label>
<div class="col-md-8">
${structure:f2.serialize()}
<p id="error-${f2.oid}" class="help-block" tal:condition="f2.error"
tal:repeat="error f2.error.messages()">
${error}</p>
</div>
</div>
</div>
<input type="hidden" name="__end__" value="${f.name}:mapping" readonly="readonly">
<!--/div>
</div>
</div-->
</div>
</div>
<div class="input-group-btn">
<button tal:repeat="fb form.buttons"
type="${fb.type}" class="btn ${fb.css_class} pull-right"
name="${fb.name}">${fb.title}</button>
</div>
<label class="control-label text-danger">** Data di Isi sesuai dengan yang tertera pada KTP</label>
</div>
</div>
</form>
<!-- End Template Form -->
<!-- </div> -->
</div>
</div>
<div metal:fill-slot="scripts">
<script tal:condition="${captcha}">
$(document).ready(function () {
$("#captcha").parent().prepend(
'<img style="height:30px; width:auto; margin-bottom:5px;" ' +
'src="${home}/captcha/${captcha}.png">')
$('#captcha').on('input', function (evt) {
$(this).val(function (_, val) {
return val.toUpperCase();
});
});
});
</script>
</div>
</html>
<html metal:use-macro="load: base3.pt"> <html metal:use-macro="load: form_input.pt">
<div metal:fill-slot="content"> <div metal:fill-slot="scripts">
<style> <script>
button { $(document).ready(function () {
margin:0px 3px; $("#captcha").parent().prepend('<img style="height:30px; width:auto; margin-bottom:5px;'+
} '" src="${home}/captcha/${captcha}.png">')
</style>
<!-- Tampilan untuk general error -->
<div tal:define="field form" class="alert alert-danger" tal:condition="field.error">
<div class="errorMsgLbl" i18n:translate="">
Terdapat kesalahan pengisian
</div>
<p class="errorMsg">${field.errormsg}</p>
</div>
<!-- END Tampilan untuk general error -->
<div class="panel-body">
<!-- Proses Template Form --> $('#captcha').on('input', function (evt) {
<form method="post" accept-charset="utf-8" id="deform" class="form-horizontal" $(this).val(function (_, val) {
enctype="multipart/form-data" return val.toUpperCase();
style="background-color:white;"> });
<input type="hidden" name="_charset_"> });
<input type="hidden" value="deform" name="__formid__"> });
<div class="col-md-6 col-md-offset-3 col-xs-12 well">
<div class="col-md-12">
<!-- Looping Semua Field-->
<div tal:repeat="f form">
<!-- Proses Saat Field hidden-->
<div tal:condition="f.widget.hidden">
${structure:f.serialize()}
</div>
<!-- Proses Saat Field Normal dan bukan Children--> </script>
<div tal:condition="not f.widget.hidden and not f.children"
class="form-group" >
<!-- Field Reqired menggunakan class required -->
<label for="${f.oid}"
class="control-label col-md-4 ${f.required and 'required' or ''}"
id="req-${f.oid}">
${f.title}</label>
<div class="col-md-8">
${structure:f.serialize()}
<p id="error-${f.oid}" class="help-block" tal:condition="f.error"
tal:repeat="error f.error.messages()">
${error}</p>
</div>
</div>
<!-- Proses saat Form Adalah Children -->
<div tal:condition="f.children">
<!--div class="panel panel-default" title="">
<div class="panel-heading">${f.title}</div>
<div class="panel-body" -->
<input type="hidden"
name="__start__"
value="${f.name}:mapping"
readonly="readonly">
<div class="form-group" tal:repeat="f2 f.children">
<div id="item-${f2.oid}" >
<label for="${f2.oid}" id="req-${f2.oid}"
class="control-label col-md-4 ${f2.required and 'required' or ''}">
${f2.title}</label>
<div class="col-md-8">
${structure:f2.serialize()}
<p id="error-${f2.oid}" class="help-block" tal:condition="f2.error"
tal:repeat="error f2.error.messages()">
${error}</p>
</div>
</div>
</div>
<input type="hidden" name="__end__" value="${f.name}:mapping" readonly="readonly">
<!--/div>
</div>
</div-->
</div>
</div>
<div class="input-group-btn">
<button tal:repeat="fb form.buttons"
type="${fb.type}" class="btn ${fb.css_class} pull-right" name="${fb.name}">${fb.title}</button>
</div>
<label class="control-label text-danger">** Data di Isi sesuai dengan yang tertera pada KTP</label>
</div>
</div>
</form>
<!-- End Template Form -->
<!-- </div> -->
</div>
</div>
<div metal:fill-slot="scripts">
<script tal:condition=captcha>
$(document).ready(function () {
$("#captcha").parent().prepend(
'<img style="height:30px; width:auto; margin-bottom:5px;" ' +
'src="${home}/captcha/${captcha}.png">')
$('#captcha').on('input', function(evt) {
$(this).val(function(_, val) {
return val.toUpperCase();
});
});
});
</script>
</div> </div>
</html> </html>
......
...@@ -2,8 +2,11 @@ import os ...@@ -2,8 +2,11 @@ import os
import re import re
import colander import colander
import transaction
from datatables import (ColumnDT, DataTables, ) from datatables import (ColumnDT, DataTables, )
from deform import (Form, widget, ValidationFailure, Button, ) from deform import (Form, widget, ValidationFailure, Button, )
from sqlalchemy.exc import IntegrityError
from opensipkd.tools import create_now from opensipkd.tools import create_now
from opensipkd.tools.buttons import btn_cancel, btn_save, btn_close from opensipkd.tools.buttons import btn_cancel, btn_save, btn_close
from opensipkd.tools.report import open_rml_row, csv_response, open_rml_pdf, pdf_response from opensipkd.tools.report import open_rml_row, csv_response, open_rml_pdf, pdf_response
...@@ -220,7 +223,7 @@ def insert(request, values): ...@@ -220,7 +223,7 @@ def insert(request, values):
user.email = values['email'].lower() user.email = values['email'].lower()
user.user_name = re.sub(' ', '', values['user_name']) # .lower() user.user_name = re.sub(' ', '', values['user_name']) # .lower()
user.security_code_date = create_now() user.security_code_date = create_now()
company_id = request.user.company_id or values["company_id"] company_id = request.user and request.user.company_id or "company_id" in values and values["company_id"] or None
user.company_id = company_id user.company_id = company_id
remain = regenerate_security_code(user) remain = regenerate_security_code(user)
if 'is_api_key' in values: if 'is_api_key' in values:
...@@ -228,7 +231,14 @@ def insert(request, values): ...@@ -228,7 +231,14 @@ def insert(request, values):
if 'password' in values: if 'password' in values:
UserService.set_password(user, values['password']) UserService.set_password(user, values['password'])
DBSession.add(user) DBSession.add(user)
DBSession.flush() try:
DBSession.flush()
except IntegrityError as e:
transaction.abort()
user.user_name = user.email
DBSession.add(user)
DBSession.flush()
if 'groups' in values and values['groups']: if 'groups' in values and values['groups']:
for gid in values['groups']: for gid in values['groups']:
ug = UserGroup() ug = UserGroup()
......
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!