Commit 3918cc17 by iqbal

Merge branch 'beta-4.2-training' of https://git.opensipkd.com/aa.gusti/opensipkd…

…-base into beta-4.2-training
2 parents 05c0278c 8389b461
id,kategori,alamat,singkat,level_id,nama,kode,status,created,create_uid
4,kategori2,alamat2,nama singkat2,1,Bu Yongki,998,1,2025-03-14 13:34:00,1
5,kategori3,alamat3,nama singkat3,1,Pak yongki4,997,1,2025-03-04 09:00:35,1
\ No newline at end of file \ No newline at end of file
external_id,external_user_name,provider_name,local_user_id
2,eksternal user 1,Santos,1
3,eksternal user 2,Bareskim,4
4,eksternal user 3,Landond turmp,2
\ No newline at end of file \ No newline at end of file
id,partner_id,nama,kode,status,created,create_uid
2,1,Bu yongki,666,1,2025-03-14 15:10:00,1
3,1,Bu yongki2,999,1,2025-03-14 15:15:00,1
\ No newline at end of file \ No newline at end of file
kategori,ibu_kota,nama,kode,status,created,create_uid,id
provinsi,Ibu kota1,nama1,ID-UUS,0,2025-03-02 14:29:46,1,88
provinsi2,Ibu kota4,nama3,ID-UIS,0,2025-03-02 15:29:46,1,87
\ No newline at end of file \ No newline at end of file
registered_date,email,status,user_name
2025-03-02,admin@local.host,1,admin
2025-03-02,guest@local.host,1,guest2
2025-03-02,prismana11@local.host,1,guest3
\ No newline at end of file \ No newline at end of file
jenis,nama_lain,nama_pendek,eselon_id/public.eselon.id,nama,kode,status,created
123,fredy,mercury,8,Bendahara Pengeluaran,421,1,2025-03-14
321,brian,may,7,Staf,542,1,2025-03-16
412,paul,mccartney,6,PPTK,643,1,2025-03-15
kode,nama,kategori,dati2_id/res_dati2.kode,status
32.07.01,Ciamis,kecamatan,ID-JB.05,1
32.07.02,Cikoneng,kecamatan,ID-JB.05,1
32.07.03,Cijeungjing,kecamatan,ID-JB.05,1
32.07.04,Sadananya,kecamatan,ID-JB.05,1
32.07.05,Cidolog,kecamatan,ID-JB.05,1
32.07.06,Cihaurbeuti,kecamatan,ID-JB.05,1
32.07.07,Panumbangan,kecamatan,ID-JB.05,1
32.07.08,Panjalu,kecamatan,ID-JB.05,1
32.07.09,Kawali,kecamatan,ID-JB.05,1
32.07.10,Panawangan,kecamatan,ID-JB.05,1
32.07.11,Cipaku,kecamatan,ID-JB.05,1
32.07.12,Jatinagara,kecamatan,ID-JB.05,1
32.07.13,Rajadesa,kecamatan,ID-JB.05,1
32.07.14,Sukadana,kecamatan,ID-JB.05,1
32.07.15,Rancah,kecamatan,ID-JB.05,1
32.07.16,Tambaksari,kecamatan,ID-JB.05,1
32.07.17,Lakbok,kecamatan,ID-JB.05,1
32.07.18,Banjarsari,kecamatan,ID-JB.05,1
32.07.19,Pamarican,kecamatan,ID-JB.05,1
32.07.29,Cimaragas,kecamatan,ID-JB.05,1
32.07.30,Cisaga,kecamatan,ID-JB.05,1
32.07.31,Sindangkasih,kecamatan,ID-JB.05,1
32.07.32,Baregbeg,kecamatan,ID-JB.05,1
32.07.33,Sukamantri,kecamatan,ID-JB.05,1
32.07.34,Lumbung,kecamatan,ID-JB.05,1
32.07.35,Purwadadi,kecamatan,ID-JB.05,1
32.07.37,Banjaranyar,kecamatan,ID-JB.05,1
\ No newline at end of file \ No newline at end of file
value,nama,kode,status,created
123,ndxaka,12345,1,2025-03-14
231,jonojoni,54321,1,2025-03-15
321,ploncowati,32145,1,2025-03-16
\ No newline at end of file \ No newline at end of file
partner_id/public.partner.id,departemen_id/public.departemen.id,jabatan_id/public.jabatan.id,mulai,selesai
1,1,1,2025-02-01,2025-03-12
\ No newline at end of file \ No newline at end of file
user_id/public.users.id,departemen_id/public.departemen.id,id
1,1,8
2,2,2
\ No newline at end of file \ No newline at end of file
...@@ -4,11 +4,8 @@ import inspect ...@@ -4,11 +4,8 @@ import inspect
import locale import locale
import logging import logging
import re import re
import urllib import urllib
from .routes import routes from .routes import routes
# from opensipkd.tools.captcha import get_captcha_url # from opensipkd.tools.captcha import get_captcha_url
try: try:
......
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>reports</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
</buildSpec>
<natures>
</natures>
</projectDescription>
eclipse.preferences.version=1
encoding/partner.jrxml=UTF-8
encoding/users.jrxml=UTF-8
<?xml version="1.0" encoding="UTF-8" ?>
<jdbcDataAdapter class="net.sf.jasperreports.data.jdbc.JdbcDataAdapterImpl">
<name>New Data Adapter 1</name>
<driver>org.postgresql.Driver</driver>
<username>postgres</username>
<password>postgres</password>
<url>jdbc:postgresql://localhost:5432/demo</url>
<database></database>
<savePassword>true</savePassword>
<serverAddress></serverAddress>
</jdbcDataAdapter>
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
<defaultValueExpression><![CDATA["PEMERINTAH KABUPATEN TANGERANG"]]></defaultValueExpression> <defaultValueExpression><![CDATA["PEMERINTAH KABUPATEN TANGERANG"]]></defaultValueExpression>
</parameter> </parameter>
<parameter name="Logo" class="java.lang.String"> <parameter name="Logo" class="java.lang.String">
<defaultValueExpression><![CDATA["C:\\Users\\ASUS L455\\Downloads\\tangeranglogo.png"]]></defaultValueExpression> <defaultValueExpression><![CDATA["C:\Users\ASUS\Downloads\bangkit.png"]]></defaultValueExpression>
</parameter> </parameter>
<queryString language="csv"> <queryString language="csv">
<![CDATA[]]> <![CDATA[]]>
......
kode,nama,kecamatan_id/res_kecamatan.kode,,,,,,,,,,,
32.76.01.01,Depok,32.76.01,,,,,,,,,,,
32.76.01.02,Depok Jaya,32.76.01,,,,,,,,,,,
32.76.01.03,Mampang,32.76.01,,,,,,,,,,,
32.76.01.04,Pancoran Mas,32.76.01,,,,,,,,,,,
32.76.01.05,Rangkapan Jaya,32.76.01,,,,,,,,,,,
32.76.01.06,Rangkapan Jaya Baru,32.76.01,,,,,,,,,,,
32.76.02.01,Cisalak Pasar,32.76.02,,,,,,,,,,,
32.76.02.02,Curug,32.76.02,,,,,,,,,,,
32.76.02.03,Harjamukti,32.76.02,,,,,,,,,,,
32.76.02.04,Mekarsari,32.76.02,,,,,,,,,,,
32.76.02.05,Pasir Gunung Selatan,32.76.02,,,,,,,,,,,
32.76.02.06,Tugu,32.76.02,,,,,,,,,,,
32.76.03.01,Bedahan,32.76.03,,,,,,,,,,,
32.76.03.02,Cinangka,32.76.03,,,,,,,,,,,
32.76.03.03,Kedaung,32.76.03,,,,,,,,,,,
32.76.03.04,Pasir Putih,32.76.03,,,,,,,,,,,
32.76.03.05,Pengasinan,32.76.03,,,,,,,,,,,
32.76.03.06,Sawangan Baru,32.76.03,,,,,,,,,,,
32.76.03.07,Sawangan Lama,32.76.03,,,,,,,,,,,
32.76.04.01,Grogol,32.76.04,,,,,,,,,,,
32.76.04.02,Krukut,32.76.04,,,,,,,,,,,
32.76.04.03,Limo,32.76.04,,,,,,,,,,,
32.76.04.04,Meruyung,32.76.04,,,,,,,,,,,
32.76.05.01,Abadijaya,32.76.05,,,,,,,,,,,
32.76.05.02,Baktijaya,32.76.05,,,,,,,,,,,
32.76.05.03,Cisalak,32.76.05,,,,,,,,,,,
32.76.05.04,Mekarjaya,32.76.05,,,,,,,,,,,
32.76.05.05,Sukmajaya,32.76.05,,,,,,,,,,,
32.76.05.06,Tirtajaya,32.76.05,,,,,,,,,,,
32.76.06.01,Beji,32.76.06,,,,,,,,,,,
32.76.06.02,Beji Timur,32.76.06,,,,,,,,,,,
32.76.06.03,Kemirimuka,32.76.06,,,,,,,,,,,
32.76.06.04,Kukusan,32.76.06,,,,,,,,,,,
32.76.06.05,Pondokcina,32.76.06,,,,,,,,,,,
32.76.06.06,Tanahbaru,32.76.06,,,,,,,,,,,
32.76.07.01,Cipayung,32.76.07,,,,,,,,,,,
32.76.07.02,Bojong Pondok Terong,32.76.07,,,,,,,,,,,
32.76.07.03,Cipayung,32.76.07,,,,,,,,,,,
32.76.07.04,Cipayung Jaya,32.76.07,,,,,,,,,,,
32.76.07.05,Pondok Jaya,32.76.07,,,,,,,,,,,
32.76.07.06,Ratujaya,32.76.07,,,,,,,,,,,
32.76.08.01,Cilodong,32.76.08,,,,,,,,,,,
32.76.08.02,Jatimulya,32.76.08,,,,,,,,,,,
32.76.08.03,Kalibaru,32.76.08,,,,,,,,,,,
32.76.08.04,Kalimulya,32.76.08,,,,,,,,,,,
32.76.08.05,Sukamaju,32.76.08,,,,,,,,,,,
32.76.09.01,Cinere,32.76.09,,,,,,,,,,,
32.76.09.02,Gandul,32.76.09,,,,,,,,,,,
32.76.09.03,Pangkalan Jati,32.76.09,,,,,,,,,,,
32.76.09.04,Pangkalan Jati Baru,32.76.09,,,,,,,,,,,
32.76.10.01,Cilangkap,32.76.10,,,,,,,,,,,
32.76.10.02,Cimpaeun,32.76.10,,,,,,,,,,,
32.76.10.03,Jatijajar,32.76.10,,,,,,,,,,,
32.76.10.04,Leuwinanggung,32.76.10,,,,,,,,,,,
32.76.10.05,Sukamaju Baru,32.76.10,,,,,,,,,,,
32.76.10.06,Sukatani,32.76.10,,,,,,,,,,,
32.76.10.07,Tapos,32.76.10,,,,,,,,,,,
32.76.11.01,Bojongsari Lama,32.76.11,,,,,,,,,,,
32.76.11.02,Bojongsaribaru,32.76.11,,,,,,,,,,,
32.76.11.03,Curug,32.76.11,,,,,,,,,,,
32.76.11.04,Durenmekar,32.76.11,,,,,,,,,,,
32.76.11.05,Durenseribu,32.76.11,,,,,,,,,,,
32.76.11.06,Pondokpetir,32.76.11,,,,,,,,,,,
32.76.11.07,Serua,32.76.11,,,,,,,,,,,
\ No newline at end of file \ No newline at end of file
kecamatan_id/pad.tblkecamatan.id,kelurahankd,kelurahannm,tmt,enabled
2,81,Sidodadi,2025-09-06 00:00:00,1
3,78,Sidorejo,2025-09-06 00:00:00,1
4,79,Sidoharjo,2025-09-06 00:00:00,1
5,80,Sidomulyo,2025-09-06 00:00:00,1
\ No newline at end of file \ No newline at end of file
...@@ -21,6 +21,7 @@ user-add,/user/add,Tambah User,1 ...@@ -21,6 +21,7 @@ user-add,/user/add,Tambah User,1
user-edit,/user/{id}/edit,Edit User,1 user-edit,/user/{id}/edit,Edit User,1
user-view,/user/{id}/view,View User,1 user-view,/user/{id}/view,View User,1
user-delete,/user/{id}/delete,Hapus User,1 user-delete,/user/{id}/delete,Hapus User,1
user-upload,/user/upload,Upload User,1
user-act,/user/{act}/act,Act User,1 user-act,/user/{act}/act,Act User,1
user-ext,/user/ext,Daftar User Ext,1 user-ext,/user/ext,Daftar User Ext,1
user-ext-add,/user/ext/add,Tambah User Ext, user-ext-add,/user/ext/add,Tambah User Ext,
...@@ -28,6 +29,7 @@ user-ext-edit,/user/ext/{id}/edit,Edit User Ext, ...@@ -28,6 +29,7 @@ user-ext-edit,/user/ext/{id}/edit,Edit User Ext,
user-ext-view,/user/ext/{id}/view,View User Ext, user-ext-view,/user/ext/{id}/view,View User Ext,
user-ext-delete,/user/ext/{id}/delete,Hapus User Ext, user-ext-delete,/user/ext/{id}/delete,Hapus User Ext,
user-ext-act,/user/ext/{act}/act,Act User Ext, user-ext-act,/user/ext/{act}/act,Act User Ext,
user-ext-upload,/user/ext/upload,Upload User Ext,
register,/register,Register, register,/register,Register,
register-external,/register/external,Register External, register-external,/register/external,Register External,
profile,/profile,Profile, profile,/profile,Profile,
...@@ -69,6 +71,7 @@ parameter-add,/parameter/add,Tambah paramater, ...@@ -69,6 +71,7 @@ parameter-add,/parameter/add,Tambah paramater,
parameter-edit,/parameter/{id}/edit,Edit parameter, parameter-edit,/parameter/{id}/edit,Edit parameter,
parameter-view,/parameter/{id}/view,View parameter, parameter-view,/parameter/{id}/view,View parameter,
parameter-delete,/parameter/{id}/delete,Hapus parameter, parameter-delete,/parameter/{id}/delete,Hapus parameter,
parameter-upload,/parameter/upload,Parameter Upload,1,0,
parameter-act,/parameter/{act}/act,Act parameter, parameter-act,/parameter/{act}/act,Act parameter,
upload-logo,/upload/logo,Unggah Logo, upload-logo,/upload/logo,Unggah Logo,
upload-background,/upload/background,Unggah Background, upload-background,/upload/background,Unggah Background,
...@@ -98,6 +101,7 @@ departemen-user-edt,/departemen/user/{id}/edt,User Organisasi Edit,1,0, ...@@ -98,6 +101,7 @@ departemen-user-edt,/departemen/user/{id}/edt,User Organisasi Edit,1,0,
departemen-user-view,/departemen/user/{id}/view,User Organisasi view,1,0, departemen-user-view,/departemen/user/{id}/view,User Organisasi view,1,0,
departemen-user-del,/departemen/user/{id}/del,User Organisasi Hapus,1,0, departemen-user-del,/departemen/user/{id}/del,User Organisasi Hapus,1,0,
departemen-user-rpt,/departemen/user/{rpt}/rpt,User Organisasi Report,1,0, departemen-user-rpt,/departemen/user/{rpt}/rpt,User Organisasi Report,1,0,
departemen-user-upload,/departemen/user/{id}/upload,User Departemen Upload,1,0,
rpc-user,/rpc/user,WebService User Management,1,1, rpc-user,/rpc/user,WebService User Management,1,1,
googleOauth2,/googleOauth2,'Google OAuth2',1 googleOauth2,/googleOauth2,'Google OAuth2',1
googlesignin,/googlesignin, "Google SignIn",1 googlesignin,/googlesignin, "Google SignIn",1
...@@ -119,6 +123,7 @@ jabatan-add,/jabatan/add,Tambah Jabatan, ...@@ -119,6 +123,7 @@ jabatan-add,/jabatan/add,Tambah Jabatan,
jabatan-edit,/jabatan/{id}/edit,Edit Jabatan, jabatan-edit,/jabatan/{id}/edit,Edit Jabatan,
jabatan-view,/jabatan/{id}/view,View Jabatan, jabatan-view,/jabatan/{id}/view,View Jabatan,
jabatan-delete,/jabatan/{id}/delete,Hapus Jabatan, jabatan-delete,/jabatan/{id}/delete,Hapus Jabatan,
jabatan-upload,/jabatan/upload,Upload Jabatan,1,0,
jabatan-act,/jabatan/{act}/act,Act Jabatan, jabatan-act,/jabatan/{act}/act,Act Jabatan,
jabatan-rpt,/jabatan/{rpt}/rpt,Rpt Jabatan, jabatan-rpt,/jabatan/{rpt}/rpt,Rpt Jabatan,
partner-departemen,/partner/departemen,Partner Departemen, partner-departemen,/partner/departemen,Partner Departemen,
...@@ -126,6 +131,7 @@ partner-departemen-add,/partner/departemen/add,Partner Departemen Add, ...@@ -126,6 +131,7 @@ partner-departemen-add,/partner/departemen/add,Partner Departemen Add,
partner-departemen-edit,/partner/departemen/{id}/edit,Partner Departemen Edit, partner-departemen-edit,/partner/departemen/{id}/edit,Partner Departemen Edit,
partner-departemen-view,/partner/departemen/{id}/view,Partner Departemen View, partner-departemen-view,/partner/departemen/{id}/view,Partner Departemen View,
partner-departemen-delete,/partner/departemen/{id}/delete,Partner Departemen Hapus, partner-departemen-delete,/partner/departemen/{id}/delete,Partner Departemen Hapus,
partner-departemen-upload,/partner/departemen/upload,Pertner Departemen Upload,1,0,
partner-departemen-act,/partner/departemen/{act}/act,Partner Departemen Act, partner-departemen-act,/partner/departemen/{act}/act,Partner Departemen Act,
partner-departemen-rpt,/partner/departemen/{rpt}/rpt,Partner Departemen Report, partner-departemen-rpt,/partner/departemen/{rpt}/rpt,Partner Departemen Report,
log,/log,Log Aplikasi, log,/log,Log Aplikasi,
...@@ -138,6 +144,7 @@ provinsi-view,/provinsi/{id}/view,Provinsi View,1,0, ...@@ -138,6 +144,7 @@ provinsi-view,/provinsi/{id}/view,Provinsi View,1,0,
provinsi-delete,/provinsi/{id}/delete,Provinsi Hapus,1,0, provinsi-delete,/provinsi/{id}/delete,Provinsi Hapus,1,0,
provinsi-act,/provinsi/{act}/act,Provinsi Act,1,0, provinsi-act,/provinsi/{act}/act,Provinsi Act,1,0,
provinsi-rpt,/provinsi/{rpt}/rpt,Provinsi Report,1,0, provinsi-rpt,/provinsi/{rpt}/rpt,Provinsi Report,1,0,
provinsi-upload,/provinsi/upload,UploadProvinsi,1,0,
dati2,/dati2,Kabupaten/Kota,1,0, dati2,/dati2,Kabupaten/Kota,1,0,
dati2-add,/dati2/add,Kabupaten/Kota Add,1,0, dati2-add,/dati2/add,Kabupaten/Kota Add,1,0,
dati2-edit,/dati2/{id}/edit,Kabupaten/Kota Edit,1,0, dati2-edit,/dati2/{id}/edit,Kabupaten/Kota Edit,1,0,
...@@ -168,4 +175,5 @@ company-edit,/company/{id}/edit,Pemda Edit,1,0, ...@@ -168,4 +175,5 @@ company-edit,/company/{id}/edit,Pemda Edit,1,0,
company-view,/company/{id}/view,Pemda View,1,0, company-view,/company/{id}/view,Pemda View,1,0,
company-delete,/company/{id}/delete,Pemda Hapus,1,0, company-delete,/company/{id}/delete,Pemda Hapus,1,0,
company-act,/company/{act}/act,Pemda Act,1,0, company-act,/company/{act}/act,Pemda Act,1,0,
company-rpt,/company/{rpt}/rpt,Pemda Report,1,0,
\ No newline at end of file \ No newline at end of file
company-rpt,/company/{rpt}/rpt,Pemda Report,1,0,
company-upload,/company/upload,Import Pemerintah,1,0,
\ No newline at end of file \ No newline at end of file
...@@ -11,6 +11,7 @@ from pyramid.interfaces import IRoutesMapper ...@@ -11,6 +11,7 @@ from pyramid.interfaces import IRoutesMapper
from pyramid.renderers import render_to_response from pyramid.renderers import render_to_response
from pyramid.view import view_config from pyramid.view import view_config
from deform.form import Button from deform.form import Button
from opensipkd.base import get_params, get_urls from opensipkd.base import get_params, get_urls
from opensipkd.models import ( from opensipkd.models import (
DBSession, UserService, ) DBSession, UserService, )
...@@ -22,8 +23,15 @@ log = logging.getLogger(__name__) ...@@ -22,8 +23,15 @@ log = logging.getLogger(__name__)
from datatables import ColumnDT from datatables import ColumnDT
# , DataTables, get_urls) # , DataTables, get_urls)
btn_upload = Button('upload', title=_('import'), css_class="btn-info") btn_upload = Button('upload', title=_('import'), css_class="btn-info")
from deform.form import Button
# Coba tambah tombol baru import
button_import = Button('upload', title=_('Import'), css_class='btn-info')
def no_action(): def no_action():
test = ColumnDT test = ColumnDT
......
import logging from . import DataTables, button_import
from .partner_base import PartnerSchema
from .. import get_urls
from ..views import BaseView
import logging
import colander import colander
from datatables import ColumnDT from datatables import ColumnDT
from deform import (widget, ) from deform import (widget, )
...@@ -8,10 +12,8 @@ from sqlalchemy.orm import aliased ...@@ -8,10 +12,8 @@ from sqlalchemy.orm import aliased
from opensipkd.models import DBSession, ResCompany, ResKecamatan, Partner from opensipkd.models import DBSession, ResCompany, ResKecamatan, Partner
from opensipkd.models import ResProvinsi, ResDati2, ResDesa, User from opensipkd.models import ResProvinsi, ResDati2, ResDesa, User
from . import DataTables from opensipkd.tools.buttons import btn_upload
from .partner_base import PartnerSchema
from .. import get_urls
from ..views import BaseView
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
SESS_ADD_FAILED = 'Tambah pemda gagal' SESS_ADD_FAILED = 'Tambah pemda gagal'
...@@ -52,13 +54,16 @@ class AddSchema(PartnerSchema): ...@@ -52,13 +54,16 @@ class AddSchema(PartnerSchema):
class EditSchema(AddSchema): class EditSchema(AddSchema):
id = colander.SchemaNode(colander.String(), missing=colander.drop, id = colander.SchemaNode(
widget=widget.HiddenWidget(readonly=True), colander.String(),
visible=False, ) missing=colander.drop,
partner_id = colander.SchemaNode(colander.Integer(), widget=widget.HiddenWidget(readonly=True),
widget=widget.HiddenWidget(), visible=False, )
missing=colander.drop, partner_id = colander.SchemaNode(
oid="partner_id") colander.Integer(),
widget=widget.HiddenWidget(),
missing=colander.drop,
oid="partner_id")
class ListSchema(colander.Schema): class ListSchema(colander.Schema):
...@@ -78,9 +83,7 @@ class ListSchema(colander.Schema): ...@@ -78,9 +83,7 @@ class ListSchema(colander.Schema):
validator=colander.Length(max=64, max_err='Maksimal 64 karakter'), validator=colander.Length(max=64, max_err='Maksimal 64 karakter'),
oid="parent_nm", oid="parent_nm",
field="alias.nama" field="alias.nama"
) )
status = colander.SchemaNode( status = colander.SchemaNode(
colander.Integer(), colander.Integer(),
widget=widget.CheckboxWidget(), widget=widget.CheckboxWidget(),
...@@ -95,6 +98,7 @@ class ViewCompany(BaseView): ...@@ -95,6 +98,7 @@ class ViewCompany(BaseView):
self.edit_schema = EditSchema self.edit_schema = EditSchema
self.list_schema = ListSchema self.list_schema = ListSchema
self.table = ResCompany self.table = ResCompany
self.list_buttons = self.list_buttons + self.list_report + (button_import,)
def form_validator(self, form, value): def form_validator(self, form, value):
err = colander.Invalid(form, "") err = colander.Invalid(form, "")
...@@ -170,14 +174,17 @@ class ViewCompany(BaseView): ...@@ -170,14 +174,17 @@ class ViewCompany(BaseView):
desa_list=desa_list desa_list=desa_list
) )
@view_config(route_name='company-view', @view_config(
renderer='templates/form.pt', permission='company') route_name='company-view',
renderer='templates/form.pt',
permission='company')
def view_view(self): def view_view(self):
return super().view_view() return super().view_view()
@view_config(route_name='company', @view_config(
renderer='templates/table.pt', route_name='company',
permission='company') renderer='templates/table.pt',
permission='company')
def view_list(self): def view_list(self):
return super().view_list() return super().view_list()
...@@ -187,8 +194,10 @@ class ViewCompany(BaseView): ...@@ -187,8 +194,10 @@ class ViewCompany(BaseView):
self.table.id == self.req.user.company_id) self.table.id == self.req.user.company_id)
return query return query
@view_config(route_name='company-act', renderer='json', @view_config(
permission='view') route_name='company-act',
renderer='json',
permission='view')
def view_act(self): def view_act(self):
request = self.req request = self.req
ses = request.session ses = request.session
...@@ -222,8 +231,10 @@ class ViewCompany(BaseView): ...@@ -222,8 +231,10 @@ class ViewCompany(BaseView):
log.error(r) log.error(r)
return r return r
@view_config(route_name='company-add', @view_config(
renderer='templates/form.pt', permission='company') route_name='company-add',
renderer='templates/form.pt',
permission='company')
def view_add(self): def view_add(self):
return super(ViewCompany, self).view_add() return super(ViewCompany, self).view_add()
...@@ -241,13 +252,17 @@ class ViewCompany(BaseView): ...@@ -241,13 +252,17 @@ class ViewCompany(BaseView):
d["parent_nm"] = parent.nama d["parent_nm"] = parent.nama
return d return d
@view_config(route_name='company-edit', @view_config(
renderer='templates/form.pt', permission='company') route_name='company-edit',
renderer='templates/form.pt',
permission='company')
def view_edit(self): def view_edit(self):
return super(ViewCompany, self).view_edit() return super(ViewCompany, self).view_edit()
@view_config(route_name='company-delete', @view_config(
renderer='templates/form_input.pt', permission='company') route_name='company-delete',
renderer='templates/form_input.pt',
permission='company')
def view_delete(self): def view_delete(self):
return super(ViewCompany, self).view_delete() return super(ViewCompany, self).view_delete()
...@@ -264,6 +279,7 @@ class ViewCompany(BaseView): ...@@ -264,6 +279,7 @@ class ViewCompany(BaseView):
part = None part = None
if "id" in values: if "id" in values:
del values["id"] del values["id"]
if not part: if not part:
part = Partner() part = Partner()
part.from_dict(values) part.from_dict(values)
...@@ -275,7 +291,6 @@ class ViewCompany(BaseView): ...@@ -275,7 +291,6 @@ class ViewCompany(BaseView):
values["partner_id"] = part.id values["partner_id"] = part.id
if parent_id: if parent_id:
values["parent_id"] = parent_id values["parent_id"] = parent_id
if "id" in self.req.matchdict: if "id" in self.req.matchdict:
values["id"] = self.req.matchdict["id"] values["id"] = self.req.matchdict["id"]
...@@ -284,4 +299,15 @@ class ViewCompany(BaseView): ...@@ -284,4 +299,15 @@ class ViewCompany(BaseView):
part.company_id = row.id part.company_id = row.id
DBSession.add(part) DBSession.add(part)
DBSession.flush() DBSession.flush()
return row return row
# Fungsi upload
@view_config(
route_name='company-upload',
renderer='templates/form.pt',
permission='company'
)
def view_upload(self):
self.upload_keys = ["id"]
return super().view_upload(exts=(".csv", ".tsv"))
\ No newline at end of file \ No newline at end of file
from datetime import datetime
import colander import colander
from . import button_import
from .company import company_widget
from .. import get_params
from ..views import ColumnDT, DataTables, BaseView, get_urls
from datetime import datetime
from deform import (widget, ) from deform import (widget, )
from opensipkd.models import DBSession, Departemen, Partner, PartnerDepartemen, ResCompany from opensipkd.models import DBSession, Departemen, Partner, PartnerDepartemen, ResCompany
from opensipkd.tools import (get_settings) from opensipkd.tools import (get_settings)
from opensipkd.tools.buttons import btn_upload
from pyramid.view import (view_config, ) from pyramid.view import (view_config, )
from sqlalchemy import func from sqlalchemy import func
from sqlalchemy.orm import aliased from sqlalchemy.orm import aliased
from .company import company_widget
from .. import get_params
from ..views import ColumnDT, DataTables, BaseView, get_urls
SESS_ADD_FAILED = 'Tambah departemen gagal' SESS_ADD_FAILED = 'Tambah departemen gagal'
SESS_EDIT_FAILED = 'Edit departemen gagal' SESS_EDIT_FAILED = 'Edit departemen gagal'
...@@ -45,8 +44,9 @@ def departemen_widget_form(): ...@@ -45,8 +44,9 @@ def departemen_widget_form():
class AddSchema(colander.Schema): class AddSchema(colander.Schema):
parent_id = colander.SchemaNode( parent_id = colander.SchemaNode(
colander.Integer(), colander.Integer(),
widget=widget.HiddenWidget(), oid="parent_id", missing=colander.drop, widget=widget.HiddenWidget(),
) oid="parent_id",
missing=colander.drop)
parent_nm = colander.SchemaNode( parent_nm = colander.SchemaNode(
colander.String(), missing=colander.drop, colander.String(), missing=colander.drop,
...@@ -58,27 +58,37 @@ class AddSchema(colander.Schema): ...@@ -58,27 +58,37 @@ class AddSchema(colander.Schema):
), ),
oid="parent_nm", title="Induk") oid="parent_nm", title="Induk")
parent_kd = colander.SchemaNode(colander.String(), parent_kd = colander.SchemaNode(
widget=widget.TextInputWidget(css_class="readonly"), colander.String(),
missing=colander.drop, oid="parent_kd", title="Kode Induk") widget=widget.TextInputWidget(css_class="readonly"),
missing=colander.drop, oid="parent_kd", title="Kode Induk")
kode = colander.SchemaNode(colander.String(), kode = colander.SchemaNode(
validator=colander.Length(max=32), oid="kode") colander.String(),
validator=colander.Length(max=32),
oid="kode")
nama = colander.SchemaNode(colander.String(), oid="nama") nama = colander.SchemaNode(colander.String(), oid="nama")
singkat = colander.SchemaNode(colander.String(), missing=colander.drop, singkat = colander.SchemaNode(
oid="singkat") colander.String(),
missing=colander.drop,
kategori = colander.SchemaNode(colander.String(), missing=colander.drop, oid="singkat")
oid="kategori")
kategori = colander.SchemaNode(
alamat = colander.SchemaNode(colander.String(), missing=colander.drop, colander.String(),
oid="alamat") missing=colander.drop,
company_id = colander.SchemaNode(colander.Integer(), oid="kategori")
widget=company_widget,
missing=colander.drop, alamat = colander.SchemaNode(
oid="company_id") colander.String(),
missing=colander.drop,
oid="alamat")
company_id = colander.SchemaNode(
colander.Integer(),
widget=company_widget,
missing=colander.drop,
oid="company_id")
status = colander.SchemaNode( status = colander.SchemaNode(
colander.Integer(), colander.Integer(),
...@@ -105,14 +115,31 @@ class EditSchema(AddSchema): ...@@ -105,14 +115,31 @@ class EditSchema(AddSchema):
class ListSchema(colander.Schema): class ListSchema(colander.Schema):
id = colander.SchemaNode(colander.String(), title="Action", visible=False) id = colander.SchemaNode(
kode = colander.SchemaNode(colander.String(), title="Kode") colander.String(),
nama = colander.SchemaNode(colander.String(), title="Nama") title="Action",
status = colander.SchemaNode(colander.Boolean(), title="Status", width='50pt', visible=False)
widget=widget.CheckboxWidget()) kode = colander.SchemaNode(
level_id = colander.SchemaNode(colander.Integer(), title="Level", width='40pt') colander.String(),
parent = colander.SchemaNode(colander.String(), title="Induk") title="Kode")
company_nm = colander.SchemaNode(colander.String(), title="Company") nama = colander.SchemaNode(
colander.String(),
title="Nama")
status = colander.SchemaNode(
colander.Boolean(),
title="Status",
width='50pt',
widget=widget.CheckboxWidget())
level_id = colander.SchemaNode(
colander.Integer(),
title="Level",
width='40pt')
parent = colander.SchemaNode(
colander.String(),
title="Induk")
company_nm = colander.SchemaNode(
colander.String(),
title="Company")
class ViewDepartemen(BaseView): class ViewDepartemen(BaseView):
...@@ -125,7 +152,7 @@ class ViewDepartemen(BaseView): ...@@ -125,7 +152,7 @@ class ViewDepartemen(BaseView):
# self.list_url = 'departemen' # self.list_url = 'departemen'
self.list_route = 'departemen' self.list_route = 'departemen'
self.form_scripts = "" self.form_scripts = ""
self.list_buttons = self.list_buttons + (btn_upload,) self.list_buttons = self.list_buttons + (button_import,)
def form_validator(self, form, value): def form_validator(self, form, value):
def err_kode(): def err_kode():
...@@ -323,26 +350,34 @@ class ViewDepartemen(BaseView): ...@@ -323,26 +350,34 @@ class ViewDepartemen(BaseView):
return {"company_list": ResCompany.get_list(), return {"company_list": ResCompany.get_list(),
"departemen_list":get_departemen_list()} "departemen_list":get_departemen_list()}
@view_config(route_name='departemen-add', renderer='templates/form.pt', @view_config(
permission='departemen') route_name='departemen-add',
renderer='templates/form.pt',
permission='departemen')
def view_add(self): def view_add(self):
return super(ViewDepartemen, self).view_add() return super(ViewDepartemen, self).view_add()
@view_config(route_name='departemen-edit', @view_config(
renderer='templates/form.pt', permission='departemen') route_name='departemen-edit',
renderer='templates/form.pt',
permission='departemen')
def view_edit(self): def view_edit(self):
return super(ViewDepartemen, self).view_edit() return super(ViewDepartemen, self).view_edit()
@view_config(route_name='departemen-delete', @view_config(
renderer='templates/form.pt', permission='departemen') route_name='departemen-delete',
renderer='templates/form.pt',
permission='departemen')
def view_delete(self): def view_delete(self):
return super(ViewDepartemen, self).view_delete() return super(ViewDepartemen, self).view_delete()
@view_config(route_name='departemen-upload', @view_config(
renderer='templates/form.pt', route_name='departemen-upload',
permission='departemen') renderer='templates/form.pt',
permission='departemen')
def view_upload(self): def view_upload(self):
return super().view_upload(exts=('.csv', '.tsv'), delimiter="\t") self.upload_keys = ["kode"]
return super().view_upload(exts=('.csv', '.tsv'))
# request = self.req # request = self.req
# form = self.get_form(UploadSchema) # form = self.get_form(UploadSchema)
......
...@@ -11,6 +11,7 @@ from opensipkd.tools.report import csv_response, open_rml_pdf, open_rml_row, \ ...@@ -11,6 +11,7 @@ from opensipkd.tools.report import csv_response, open_rml_pdf, open_rml_row, \
pdf_response pdf_response
from pyramid.i18n import TranslationStringFactory from pyramid.i18n import TranslationStringFactory
from pyramid.view import (view_config, ) from pyramid.view import (view_config, )
from . import BaseView, button_import
from ..views import BaseView from ..views import BaseView
...@@ -107,6 +108,7 @@ class ViewJabatan(BaseView): ...@@ -107,6 +108,7 @@ class ViewJabatan(BaseView):
self.edit_schema = EditSchema self.edit_schema = EditSchema
self.table = Jabatan self.table = Jabatan
self.list_schema = ListSchema self.list_schema = ListSchema
self.list_buttons = self.list_buttons + (button_import,)
# self.list_buttons = (btn_view, btn_add, btn_edit, btn_delete, btn_close) # self.list_buttons = (btn_view, btn_add, btn_edit, btn_delete, btn_close)
def get_bindings(self, row=None): def get_bindings(self, row=None):
...@@ -249,6 +251,12 @@ class ViewJabatan(BaseView): ...@@ -249,6 +251,12 @@ class ViewJabatan(BaseView):
permission='jabatan') permission='jabatan')
def view_delete(self): def view_delete(self):
return super().view_delete() return super().view_delete()
@view_config(route_name='jabatan-upload',
renderer='templates/form.pt', permission='jabatan')
def view_upload(self):
self.upload_keys = ["nama_lain"]
return super().view_upload(exts=(".csv", ".tsv"))
def form_validator(self, form, value): def form_validator(self, form, value):
def err_kode(): def err_kode():
......
...@@ -2,11 +2,11 @@ import colander ...@@ -2,11 +2,11 @@ import colander
from deform import (widget, ) from deform import (widget, )
from opensipkd.base.views.provinsi import provinsi_widget from opensipkd.base.views.provinsi import provinsi_widget
from opensipkd.models import DBSession, ResKecamatan, ResDati2, ResProvinsi from opensipkd.models import DBSession, ResKecamatan, ResDati2, ResProvinsi
from opensipkd.tools.buttons import btn_upload, btn_close, btn_add from opensipkd.tools.buttons import btn_close, btn_add
from pyramid.i18n import TranslationStringFactory from pyramid.i18n import TranslationStringFactory
from pyramid.view import (view_config, ) from pyramid.view import (view_config, )
from . import widget_os from . import widget_os, button_import
from .dati2 import dati2_widget from .dati2 import dati2_widget
from ..views import BaseView from ..views import BaseView
...@@ -75,7 +75,7 @@ class Views(BaseView): ...@@ -75,7 +75,7 @@ class Views(BaseView):
self.edit_schema = EditSchema self.edit_schema = EditSchema
self.table = ResKecamatan self.table = ResKecamatan
self.list_schema = ListSchema self.list_schema = ListSchema
self.list_buttons = (btn_add, btn_close, btn_upload) self.list_buttons = (btn_add, btn_close, button_import)
def form_validator(self, form, value): def form_validator(self, form, value):
def err_kode(): def err_kode():
...@@ -174,4 +174,4 @@ class Views(BaseView): ...@@ -174,4 +174,4 @@ class Views(BaseView):
@view_config(route_name='kecamatan-upload', @view_config(route_name='kecamatan-upload',
renderer='templates/form.pt', permission='wilayah') renderer='templates/form.pt', permission='wilayah')
def view_upload(self): def view_upload(self):
return super(Views, self).view_upload(exts=(".csv", ".tsv")) return super(Views, self).view_upload(exts=(".csv", ".tsv"))
\ No newline at end of file \ No newline at end of file
...@@ -2,6 +2,7 @@ from colander import Length ...@@ -2,6 +2,7 @@ from colander import Length
import colander import colander
from deform import (widget, ) from deform import (widget, )
from pyramid.view import (view_config, ) from pyramid.view import (view_config, )
from . import BaseView, button_import
from opensipkd.models import ( from opensipkd.models import (
DBSession, DBSession,
...@@ -76,6 +77,7 @@ class Views(BaseView): ...@@ -76,6 +77,7 @@ class Views(BaseView):
self.edit_schema = EditSchema self.edit_schema = EditSchema
self.table = Parameter self.table = Parameter
self.list_schema = ListSchema self.list_schema = ListSchema
self.list_buttons = self.list_buttons + (button_import,)
@view_config(route_name='parameter', renderer='templates/table.pt', @view_config(route_name='parameter', renderer='templates/table.pt',
permission='user-edit') permission='user-edit')
...@@ -117,3 +119,9 @@ class Views(BaseView): ...@@ -117,3 +119,9 @@ class Views(BaseView):
permission='user-edit') permission='user-edit')
def view_delete(self): def view_delete(self):
return super().view_delete() return super().view_delete()
@view_config(route_name='parameter-upload',
renderer='templates/form.pt', permission='user-upload')
def view_upload(self):
self.upload_keys = ["value"]
return super(Views, self).view_upload(exts=(".csv", ".tsv"))
\ No newline at end of file \ No newline at end of file
...@@ -20,7 +20,7 @@ class PartnerEmailValidator(colander.Email, Validator): ...@@ -20,7 +20,7 @@ class PartnerEmailValidator(colander.Email, Validator):
Validator.__init__(self, row) Validator.__init__(self, row)
colander.Email.__init__(self) colander.Email.__init__(self)
def __call__(self, node, value): def __call__(self, node, value):
def email_found(): def email_found():
data = dict(email=email, rid=found.id, rname=found.nama) data = dict(email=email, rid=found.id, rname=found.nama)
ts = _( ts = _(
......
...@@ -9,7 +9,7 @@ from opensipkd.models import DBSession as PartnerDBSession, DBSession, \ ...@@ -9,7 +9,7 @@ from opensipkd.models import DBSession as PartnerDBSession, DBSession, \
from opensipkd.models import Departemen, Jabatan from opensipkd.models import Departemen, Jabatan
from opensipkd.models import Partner, PartnerDepartemen from opensipkd.models import Partner, PartnerDepartemen
from opensipkd.tools import dmy, date_from_str from opensipkd.tools import dmy, date_from_str
from . import widget_os from . import widget_os, button_import
from ..views import ColumnDT, DataTables, BaseView from ..views import ColumnDT, DataTables, BaseView
SESS_ADD_FAILED = 'Tambah posisi partner gagal' SESS_ADD_FAILED = 'Tambah posisi partner gagal'
...@@ -26,7 +26,7 @@ class AddSchema(colander.Schema): ...@@ -26,7 +26,7 @@ class AddSchema(colander.Schema):
def departemen_widget(node, kw): def departemen_widget(node, kw):
departemen_list = DBSession.query(Departemen.id, Departemen.nama).all() departemen_list = DBSession.query(Departemen.id, Departemen.nama).all()
choices = [(str(departemen.id), departemen.nama) for departemen in departemen_list] choices = [(str(departemen.id), departemen.nama) for departemen in departemen_list]
return widget.CheckboxChoiceWidget(values=choices) return widget.CheckboxChoiceWidget(values=choices, multiple=True) # Enable multiple selection
@colander.deferred @colander.deferred
def jabatan_widget(node, kw): def jabatan_widget(node, kw):
...@@ -38,7 +38,6 @@ class AddSchema(colander.Schema): ...@@ -38,7 +38,6 @@ class AddSchema(colander.Schema):
colander.Integer(), colander.Integer(),
oid="partner_id", oid="partner_id",
widget=widget.HiddenWidget(), widget=widget.HiddenWidget(),
missing=colander.null, # Tetap izinkan kosong
title="Partner ID") title="Partner ID")
nama = colander.SchemaNode( nama = colander.SchemaNode(
colander.String(), colander.String(),
...@@ -51,21 +50,16 @@ class AddSchema(colander.Schema): ...@@ -51,21 +50,16 @@ class AddSchema(colander.Schema):
widget=widget.HiddenWidget(), widget=widget.HiddenWidget(),
missing=colander.drop) missing=colander.drop)
departemen = colander.SchemaNode( departemen = colander.SchemaNode(
colander.Set(), colander.Set(), # Menggunakan Set untuk multiple values
widget=departemen_widget, widget=departemen_widget,
oid="departemen_nm", oid="departemen_nm",
title="Departemen *") title="Departemen *")
jabatan_id = colander.SchemaNode( jabatan_id = colander.SchemaNode(
colander.Integer(), colander.Integer(),
oid="jabatan_id", oid="jabatan_id",
widget=widget.HiddenWidget(),
title="Jabatan",
missing=colander.drop)
jabatan = colander.SchemaNode(
colander.Integer(),
widget=jabatan_widget, widget=jabatan_widget,
oid="jabatan_nm", title="Jabatan *",
title="Jabatan *") missing=colander.drop)
mulai = colander.SchemaNode( mulai = colander.SchemaNode(
colander.String(), colander.String(),
oid="mulai", oid="mulai",
...@@ -79,9 +73,10 @@ class AddSchema(colander.Schema): ...@@ -79,9 +73,10 @@ class AddSchema(colander.Schema):
title="Selesai") title="Selesai")
class EditSchema(AddSchema): class EditSchema(AddSchema):
id = colander.SchemaNode(colander.String(), id = colander.SchemaNode(
missing=colander.drop, colander.String(),
widget=widget.HiddenWidget()) missing=colander.drop,
widget=widget.HiddenWidget())
class ListSchema(colander.Schema): class ListSchema(colander.Schema):
id = colander.SchemaNode(colander.Integer(), title="Action") id = colander.SchemaNode(colander.Integer(), title="Action")
...@@ -100,6 +95,7 @@ class ViewPartner(BaseView): ...@@ -100,6 +95,7 @@ class ViewPartner(BaseView):
self.add_schema = AddSchema self.add_schema = AddSchema
self.edit_schema = EditSchema self.edit_schema = EditSchema
self.list_route = 'partner-departemen' self.list_route = 'partner-departemen'
self.list_buttons = self.list_buttons + (button_import,)
def form_validator(self, form, value): def form_validator(self, form, value):
print(f"Validating form with values: {value}") # Debugging print(f"Validating form with values: {value}") # Debugging
...@@ -109,15 +105,23 @@ class ViewPartner(BaseView): ...@@ -109,15 +105,23 @@ class ViewPartner(BaseView):
def err_jabatan(): def err_jabatan():
raise colander.Invalid(form, 'Jabatan Belum Dipilih') raise colander.Invalid(form, 'Jabatan Belum Dipilih')
# Validasi jabatan def err_partner():
if not value['jabatan'] or value['jabatan'] == '': raise colander.Invalid(form, 'Partner Belum Dipilih')
# Validasi partner_id
if not value['partner_id']:
print("Validation failed: Partner ID kosong")
err_partner()
# Validasi jabatan_id
if not value['jabatan_id']:
print("Validation failed: Jabatan kosong") print("Validation failed: Jabatan kosong")
err_jabatan() err_jabatan()
# Validasi departemen # Validasi departemen
if not value['departemen'] or value['departemen'] == set(): if not value['departemen'] or value['departemen'] == set():
print("Validation failed: Departemen kosong") print("Validation failed: Departemen kosong")
err_departemen() err_departemen()
# Tidak memvalidasi partner_id agar opsional
def save_request(self, values, row=None): def save_request(self, values, row=None):
print(f"Saving with values: {values}") # Debugging print(f"Saving with values: {values}") # Debugging
...@@ -125,47 +129,41 @@ class ViewPartner(BaseView): ...@@ -125,47 +129,41 @@ class ViewPartner(BaseView):
if 'id' in request.matchdict: if 'id' in request.matchdict:
values['id'] = request.matchdict['id'] values['id'] = request.matchdict['id']
if 'mulai' in values: if 'mulai' in values:
if values['mulai']: values['mulai'] = date_from_str(values['mulai']) if values['mulai'] else None
values['mulai'] = date_from_str(values['mulai'])
else:
values['mulai'] = None
if 'selesai' in values: if 'selesai' in values:
if values['selesai']: values['selesai'] = date_from_str(values['selesai']) if values['selesai'] else None
values['selesai'] = date_from_str(values['selesai'])
else: # Ambil jabatan_id dari form
values['selesai'] = None if 'jabatan_id' in values and values['jabatan_id']:
values['jabatan_id'] = int(values['jabatan_id']) # Konversi ke integer
# Simpan jabatan yang dipilih dari dropdown
if 'jabatan' in values and values['jabatan']:
values['jabatan_id'] = values['jabatan']
query_struktural = DBSession.query(Jabatan.jenis).filter(
Jabatan.id == values['jabatan_id']).scalar()
values['jabatan_id'] = query_struktural if query_struktural else values['jabatan_id']
else: else:
values['jabatan_id'] = None values['jabatan_id'] = None
# Konversi colander.null ke Python None untuk partner_id # Pastikan partner_id ada dan valid
partner_id = values.get('partner_id') partner_id = values.get('partner_id')
if partner_id is colander.null: if not partner_id:
partner_id = None request.session.flash('Partner ID wajib diisi.', 'error')
return None
# Simpan setiap departemen yang dipilih sebagai baris baru # Simpan setiap departemen yang dipilih sebagai baris baru
if 'departemen' in values and values['departemen']: if 'departemen' in values and values['departemen']:
# Jika sedang mengedit, hapus entri lama untuk partner_id dan jabatan_id ini
if 'id' in values:
DBSession.query(PartnerDepartemen).filter_by(
partner_id=partner_id,
jabatan_id=values['jabatan_id']
).delete()
# Tambahkan entri baru untuk setiap departemen yang dipilih
for dept_id in values['departemen']: for dept_id in values['departemen']:
exists = DBSession.query(PartnerDepartemen).filter_by( new_row = PartnerDepartemen(
partner_id=partner_id, partner_id=partner_id,
departemen_id=int(dept_id), departemen_id=int(dept_id),
jabatan_id=values['jabatan_id'] jabatan_id=values['jabatan_id'],
).first() mulai=values['mulai'],
if not exists: selesai=values['selesai']
new_row = PartnerDepartemen( )
partner_id=partner_id, # Sekarang pasti None atau integer DBSession.add(new_row)
departemen_id=int(dept_id),
jabatan_id=values['jabatan_id'],
mulai=values['mulai'],
selesai=values['selesai']
)
DBSession.add(new_row)
DBSession.flush() DBSession.flush()
request.session.flash('Posisi Partner sudah disimpan.') request.session.flash('Posisi Partner sudah disimpan.')
return None return None
...@@ -173,7 +171,7 @@ class ViewPartner(BaseView): ...@@ -173,7 +171,7 @@ class ViewPartner(BaseView):
request.session.flash('Tidak ada departemen yang dipilih.', 'error') request.session.flash('Tidak ada departemen yang dipilih.', 'error')
return None return None
@view_config(route_name='partner-departemen', renderer='templates/form.pt', @view_config(route_name='partner-departemen', renderer='templates/table.pt',
permission='view') permission='view')
def view_list(self): def view_list(self):
return super().view_list() return super().view_list()
...@@ -308,16 +306,15 @@ class ViewPartner(BaseView): ...@@ -308,16 +306,15 @@ class ViewPartner(BaseView):
def get_values(self, row, istime=False): def get_values(self, row, istime=False):
values = super().get_values(row, istime) values = super().get_values(row, istime)
values['nama'] = row.partner.nama if row.partner else '' values['nama'] = row.partner.nama if row.partner else ''
values['jabatan'] = row.jabatan.nama values['jabatan_id'] = str(row.jabatan_id) if row.jabatan_id else ''
values['departemen'] = row.departemen.nama # Ambil semua departemen yang terkait dengan partner_id dan jabatan_id ini
values['mulai'] = dmy(row.mulai) departemen_ids = DBSession.query(PartnerDepartemen.departemen_id).filter_by(
values['selesai'] = dmy(row.selesai) partner_id=row.partner_id,
if not row.jabatan_id: jabatan_id=row.jabatan_id
values['jabatan_id'] = 0 ).all()
else: values['departemen'] = [str(dept_id[0]) for dept_id in departemen_ids] if departemen_ids else []
jb = Jabatan.query_id(row.jabatan_id).first() values['mulai'] = dmy(row.mulai) if row.mulai else ''
if jb: values['selesai'] = dmy(row.selesai) if row.selesai else ''
values['struktural_nm'] = jb.nama
return values return values
@view_config(route_name='partner-departemen-view', @view_config(route_name='partner-departemen-view',
...@@ -348,4 +345,10 @@ class ViewPartner(BaseView): ...@@ -348,4 +345,10 @@ class ViewPartner(BaseView):
renderer='templates/form.pt', renderer='templates/form.pt',
permission='partner-departemen') permission='partner-departemen')
def view_del(self): def view_del(self):
return super().view_delete()
\ No newline at end of file \ No newline at end of file
return super().view_delete()
@view_config(route_name='partner-departemen-upload',
renderer='templates/form.pt', permission='partner-departemen')
def view_upload(self):
self.upload_keys = ["mulai"]
return super().view_upload(exts=(".csv", ".tsv"))
\ No newline at end of file \ No newline at end of file
from . import widget_os, button_import
from ..views import BaseView
import colander import colander
from deform import (widget, )
from deform import (widget,)
from pyramid.i18n import TranslationStringFactory from pyramid.i18n import TranslationStringFactory
from pyramid.view import (view_config, ) from pyramid.view import (view_config, )
from . import widget_os
from opensipkd.models import DBSession, ResProvinsi, kategori_provinsi from opensipkd.models import DBSession, ResProvinsi, kategori_provinsi
from ..views import BaseView from opensipkd.tools.buttons import btn_upload
_ = TranslationStringFactory("opensipkd") _ = TranslationStringFactory("opensipkd")
SESS_ADD_FAILED = 'Tambah provinsi gagal' SESS_ADD_FAILED = 'Tambah provinsi gagal'
SESS_EDIT_FAILED = 'Edit provinsi gagal' SESS_EDIT_FAILED = 'Edit provinsi gagal'
@colander.deferred @colander.deferred
def provinsi_widget(node, kw): def provinsi_widget(node, kw):
values = kw.get('provinsi_list', []) values = kw.get('provinsi_list', [])
...@@ -80,6 +81,7 @@ class ViewProvinsi(BaseView): ...@@ -80,6 +81,7 @@ class ViewProvinsi(BaseView):
self.add_schema = AddSchema self.add_schema = AddSchema
self.edit_schema = EditSchema self.edit_schema = EditSchema
self.table = ResProvinsi self.table = ResProvinsi
self.list_buttons = self.list_buttons + self.list_report + (button_import,)
######## ########
# List # # List #
...@@ -118,33 +120,55 @@ class ViewProvinsi(BaseView): ...@@ -118,33 +120,55 @@ class ViewProvinsi(BaseView):
elif found: elif found:
err_nama() err_nama()
@view_config(route_name='provinsi-view', @view_config(
renderer='templates/form.pt', permission='provinsi') route_name='provinsi-view',
renderer='templates/form.pt',
permission='provinsi')
def view_view(self): # row = query_id(request).first() def view_view(self): # row = query_id(request).first()
return super(ViewProvinsi, self).view_view() return super(ViewProvinsi, self).view_view()
@view_config(route_name='provinsi', @view_config(
renderer='templates/table.pt', route_name='provinsi',
permission='provinsi') renderer='templates/table.pt',
permission='provinsi')
def view_list(self): def view_list(self):
return super(ViewProvinsi, self).view_list() return super(ViewProvinsi, self).view_list()
@view_config(route_name='provinsi-act', renderer='json', @view_config(
permission='view') route_name='provinsi-act',
renderer='json',
permission='view')
def view_act(self): def view_act(self):
return super(ViewProvinsi, self).view_act() return super(ViewProvinsi, self).view_act()
@view_config(route_name='provinsi-add', @view_config(
renderer='templates/form.pt', permission='provinsi') route_name='provinsi-add',
renderer='templates/form.pt',
permission='provinsi')
def view_add(self): def view_add(self):
return super(ViewProvinsi, self).view_add() return super(ViewProvinsi, self).view_add()
@view_config(route_name='provinsi-edit', @view_config(
renderer='templates/form.pt', permission='provinsi') route_name='provinsi-edit',
renderer='templates/form.pt',
permission='provinsi')
def view_edt(self): def view_edt(self):
return super(ViewProvinsi, self).view_edit() return super(ViewProvinsi, self).view_edit()
@view_config(route_name='provinsi-delete', # Fungsi delete
renderer='templates/form.pt', permission='provinsi') @view_config(
route_name='provinsi-delete',
renderer='templates/form.pt',
permission='provinsi')
def view_delete(self): def view_delete(self):
return super(ViewProvinsi, self).view_delete() return super(ViewProvinsi, self).view_delete()
# Tambah fungsi upload
@view_config(
route_name='provinsi-upload',
renderer='templates/form.pt',
permission='provinsi'
)
def view_upload(self):
self.upload_keys = ["id"]
return super().view_upload(exts=(".csv", ".tsv"))
\ No newline at end of file \ No newline at end of file
import logging import logging
import colander import colander
from deform import (widget, ) from deform import (widget, )
from pyramid.view import view_config from pyramid.view import view_config
...@@ -203,7 +202,8 @@ class Views(BaseView): ...@@ -203,7 +202,8 @@ class Views(BaseView):
""" """
@view_config( @view_config(
route_name='routes', renderer='templates/table.pt', route_name='routes',
renderer='templates/table.pt',
permission='edit-title') permission='edit-title')
def view_list(self): def view_list(self):
kwargs = {"allow_view": False, kwargs = {"allow_view": False,
......
from . import BaseView, button_import
from .company import company_widget
from .user_login import (regenerate_security_code, send_email_security_code, generate_api_key,)
import os import os
import re import re
import colander import colander
from deform import (widget, ) from deform import (widget, )
from opensipkd.tools import create_now, SaveFile from opensipkd.tools import create_now, SaveFile
from opensipkd.tools.report import open_rml_row, csv_response, open_rml_pdf, \ from opensipkd.tools.report import open_rml_row, csv_response, open_rml_pdf, pdf_response, file_response
pdf_response, file_response from opensipkd.models import (DBSession, User, Group, UserGroup, ResCompany,)
from pyramid.i18n import TranslationStringFactory from pyramid.i18n import TranslationStringFactory
from pyramid.view import view_config from pyramid.view import view_config
from sqlalchemy import (func, ) from sqlalchemy import (func,)
from ziggurat_foundations.models.services.user import UserService from ziggurat_foundations.models.services.user import UserService
from . import BaseView
from .company import company_widget
from .user_login import (
regenerate_security_code, send_email_security_code, generate_api_key, )
from opensipkd.models import (DBSession, User, Group, UserGroup, ResCompany, )
_ = TranslationStringFactory('user') _ = TranslationStringFactory('user')
class ListSchema(colander.Schema): class ListSchema(colander.Schema):
id = colander.SchemaNode(colander.String(), id = colander.SchemaNode(
title="Action", colander.String(),
searchable=False) title="Action",
searchable=False)
email = colander.SchemaNode(colander.String()) email = colander.SchemaNode(colander.String())
user_name = colander.SchemaNode(colander.String(), user_name = colander.SchemaNode(
title=_("user-name", colander.String(),
default="User Name")) title=_("user-name",
status = colander.SchemaNode(colander.Integer(), default="User Name"))
widget=widget.CheckboxWidget(), status = colander.SchemaNode(
width=50, colander.Integer(),
searchable=False) widget=widget.CheckboxWidget(),
last_login = colander.SchemaNode(colander.String(), width=50,
width=100, searchable=False)
field="last_login_date", last_login = colander.SchemaNode(
searchable=False) colander.String(),
registered = colander.SchemaNode(colander.String(), width=100,
width=100, field="last_login_date",
field="registered_date", searchable=False)
searchable=False) registered = colander.SchemaNode(
colander.String(),
width=100,
field="registered_date",
searchable=False)
class Views(BaseView): class Views(BaseView):
...@@ -50,10 +52,10 @@ class Views(BaseView): ...@@ -50,10 +52,10 @@ class Views(BaseView):
self.table = User self.table = User
self.edit_schema = EditSchema self.edit_schema = EditSchema
self.add_schema = AddSchema self.add_schema = AddSchema
self.list_buttons = self.list_buttons + self.list_report self.list_buttons = self.list_buttons + self.list_report + (button_import,)
path = os.path.dirname(__file__) path = os.path.dirname(__file__)
path = os.path.dirname(path) path = os.path.dirname(path)
self.report_file = os.path.join(path, 'reports', 'users.jrxml') self.report_file = os.path.join(path, 'reports', 'users.jrxml')
def get_bindings(self, row=None): def get_bindings(self, row=None):
...@@ -68,6 +70,7 @@ class Views(BaseView): ...@@ -68,6 +70,7 @@ class Views(BaseView):
api_key_list = ( api_key_list = (
('', _('Tidak ada')), ('', _('Tidak ada')),
('1', _('Buatkan'))) ('1', _('Buatkan')))
group_list = get_group_list() group_list = get_group_list()
return dict(status_list=status_list, return dict(status_list=status_list,
group_list=group_list, group_list=group_list,
...@@ -76,13 +79,16 @@ class Views(BaseView): ...@@ -76,13 +79,16 @@ class Views(BaseView):
company_list=ResCompany.get_list()) company_list=ResCompany.get_list())
@view_config( @view_config(
route_name='user', renderer='templates/table.pt', route_name='user',
renderer='templates/table.pt',
permission='user-view') permission='user-view')
def view_list(self): def view_list(self):
return super(Views, self).view_list() return super(Views, self).view_list()
@view_config( @view_config(
route_name='user-act', renderer='json', permission='user-view') route_name='user-act',
renderer='json',
permission='user-view')
def view_act(self): def view_act(self):
# url_dict = self.req.matchdict # url_dict = self.req.matchdict
# if url_dict['act'] == 'csv': # if url_dict['act'] == 'csv':
...@@ -180,7 +186,8 @@ class Views(BaseView): ...@@ -180,7 +186,8 @@ class Views(BaseView):
return row return row
@view_config( @view_config(
route_name='user-add', renderer='templates/form.pt', route_name='user-add',
renderer='templates/form.pt',
permission='user-view') permission='user-view')
def view_add(self): def view_add(self):
return super(Views, self).view_add() return super(Views, self).view_add()
...@@ -192,19 +199,22 @@ class Views(BaseView): ...@@ -192,19 +199,22 @@ class Views(BaseView):
return d return d
@view_config( @view_config(
route_name='user-edit', renderer='templates/form.pt', route_name='user-edit',
renderer='templates/form.pt',
permission='user-edit') permission='user-edit')
def view_edit(self): def view_edit(self):
return super(Views, self).view_edit() return super(Views, self).view_edit()
@view_config( @view_config(
route_name='user-view', renderer='templates/form.pt', route_name='user-view',
renderer='templates/form.pt',
permission='user-view') permission='user-view')
def view_view(self): def view_view(self):
return super(Views, self).view_view() return super(Views, self).view_view()
@view_config( @view_config(
route_name='user-delete', renderer='templates/form.pt', route_name='user-delete',
renderer='templates/form.pt',
permission='user-edit') permission='user-edit')
def view_delete(self): def view_delete(self):
return super(Views, self).view_delete() return super(Views, self).view_delete()
...@@ -226,6 +236,16 @@ class Views(BaseView): ...@@ -226,6 +236,16 @@ class Views(BaseView):
if self.req.user.company_id: if self.req.user.company_id:
q = q.filter_by(company_id=self.req.user.company_id) q = q.filter_by(company_id=self.req.user.company_id)
return q return q
# Tambah fungsi upload/import
@view_config(
route_name='user-upload',
renderer='templates/form.pt',
permission='user'
)
def view_upload(self):
self.upload_keys = ["email"]
return super().view_upload(exts=(".csv", ".tsv"))
####### #######
......
import colander import colander
import logging
from deform import widget from deform import widget
from pyramid.view import view_config from pyramid.view import view_config
from . import BaseView from . import BaseView, button_import
from ...models import User, DepartemenUser, Departemen, DBSession from ...models import User, DepartemenUser, Departemen, DBSession
from .departemen import departemen_widget, get_departemen_list from .departemen import get_departemen_list
from .user import user_widget, user_select, user_list from .user import user_list
from pyramid.i18n import TranslationStringFactory from pyramid.i18n import TranslationStringFactory
_ = TranslationStringFactory('myapp') _ = TranslationStringFactory('myapp')
log = logging.getLogger(__name__)
@colander.deferred @colander.deferred
def departemen_widget(node, kw): def departemen_widget(node, kw):
values = kw.get('departemen_list', []) values = kw.get('departemen_list', [])
return widget.CheckboxChoiceWidget(values=values, placeholder='Pilih Departemen') return widget.CheckboxChoiceWidget(values=values, multiple=True, placeholder='Pilih Departemen')
class ListSchema(colander.Schema): class ListSchema(colander.Schema):
id = colander.SchemaNode( id = colander.SchemaNode(
...@@ -33,7 +35,7 @@ class ListSchema(colander.Schema): ...@@ -33,7 +35,7 @@ class ListSchema(colander.Schema):
@colander.deferred @colander.deferred
def departemen_checkbox_widget(node, kw): def departemen_checkbox_widget(node, kw):
values = kw.get('departemen_list', []) values = kw.get('departemen_list', [])
return widget.CheckboxChoiceWidget(values=values) return widget.CheckboxChoiceWidget(values=values, multiple=True)
class AddSchema(colander.Schema): class AddSchema(colander.Schema):
user_id = colander.SchemaNode( user_id = colander.SchemaNode(
...@@ -43,7 +45,7 @@ class AddSchema(colander.Schema): ...@@ -43,7 +45,7 @@ class AddSchema(colander.Schema):
title="User", title="User",
) )
departemen_id = colander.SchemaNode( departemen_id = colander.SchemaNode(
colander.Set(), # Tetap menggunakan colander.Set() colander.Set(),
widget=departemen_checkbox_widget, widget=departemen_checkbox_widget,
oid="departemen_id", oid="departemen_id",
title="Departemen", title="Departemen",
...@@ -65,6 +67,7 @@ class Views(BaseView): ...@@ -65,6 +67,7 @@ class Views(BaseView):
self.edit_schema = EditSchema self.edit_schema = EditSchema
self.list_route = 'user-departemen' self.list_route = 'user-departemen'
self.table = DepartemenUser self.table = DepartemenUser
self.list_buttons = self.list_buttons + (button_import,)
def list_join(self, query, **kwargs): def list_join(self, query, **kwargs):
return query.outerjoin(Departemen, Departemen.id == self.table.departemen_id) \ return query.outerjoin(Departemen, Departemen.id == self.table.departemen_id) \
...@@ -81,10 +84,17 @@ class Views(BaseView): ...@@ -81,10 +84,17 @@ class Views(BaseView):
return super().view_act() return super().view_act()
def get_bindings(self, row=None): def get_bindings(self, row=None):
return { bindings = {
"departemen_list": get_departemen_list(), "departemen_list": get_departemen_list(),
"user_list": user_list() "user_list": user_list()
} }
if row and hasattr(row, 'user_id'):
existing_depts = self.get_existing_departemen(row.user_id)
bindings["default_values"] = {
"user_id": row.user_id,
"departemen_id": list(existing_depts)
}
return bindings
@view_config(route_name='user-departemen-add', renderer='templates/form.pt', @view_config(route_name='user-departemen-add', renderer='templates/form.pt',
permission='user-edit') permission='user-edit')
...@@ -105,59 +115,61 @@ class Views(BaseView): ...@@ -105,59 +115,61 @@ class Views(BaseView):
permission='user-edit') permission='user-edit')
def view_edit(self): def view_edit(self):
return super().view_edit() return super().view_edit()
@view_config(route_name='user-departemen-upload',
renderer='templates/form.pt', permission='user-upload')
def view_upload(self):
self.upload_keys = ["user_id"]
return super(Views, self).view_upload(exts=(".csv", ".tsv"))
def save_request(self, values, row=None): def save_request(self, values, row=None):
# Ambil user_id dari values
user_id = values.get("user_id") user_id = values.get("user_id")
if not user_id: if not user_id:
return None # Tidak ada user_id, kembalikan None atau tangani sesuai kebutuhan return None
# Jika ada departemen_id dalam values
if "departemen_id" in values: if "departemen_id" in values:
# Ambil departemen yang sudah ada untuk user ini
existing_departemen = self.get_existing_departemen(user_id)
# Konversi departemen_id dari set ke set of strings, filter None
selected_departemen = set( selected_departemen = set(
str(departemen_id) for departemen_id in values["departemen_id"] str(departemen_id) for departemen_id in values["departemen_id"]
if departemen_id is not None and str(departemen_id) != "None" if departemen_id is not None and str(departemen_id) != "None"
) )
# Batasi ke maksimal dua pilihan
# Departemen yang tidak dipilih lagi (akan dihapus) selected_list = sorted(selected_departemen)[:2] # Ambil dua yang pertama
unused_departemen = existing_departemen - selected_departemen dept1 = int(selected_list[0]) if selected_list else None
dept2 = int(selected_list[1]) if len(selected_list) > 1 else None
# Hapus departemen yang tidak dipilih lagi, pastikan hanya integer yang valid
if unused_departemen: existing_row = DBSession.query(DepartemenUser).filter_by(user_id=user_id).first()
valid_unused = [int(d) for d in unused_departemen if d.isdigit()] if selected_list:
if valid_unused: if existing_row:
DBSession.query(DepartemenUser).filter_by(user_id=user_id) \ # Update jika sudah ada
.filter(DepartemenUser.departemen_id.in_(valid_unused)) \ existing_row.departemen_id = dept1
.delete(synchronize_session=False) existing_row.sub_departemen = dept2
else:
# Departemen baru yang dipilih (akan ditambahkan) # Tambah baru jika belum ada
new_departemen = selected_departemen - existing_departemen new_row = DepartemenUser(
# Tambahkan departemen baru, periksa duplikat sebelum insert
for departemen_id in new_departemen:
if departemen_id.isdigit(): # Pastikan hanya angka yang diproses
# Cek apakah kombinasi user_id dan departemen_id sudah ada
exists = DBSession.query(DepartemenUser).filter_by(
user_id=user_id, user_id=user_id,
departemen_id=int(departemen_id) departemen_id=dept1,
).first() sub_departemen=dept2
if not exists: # Hanya tambahkan jika belum ada )
new_row = DepartemenUser( DBSession.add(new_row)
user_id=user_id, else:
departemen_id=int(departemen_id) # Konversi ke integer # Jika tidak ada pilihan, hapus row yang ada
) if existing_row:
DBSession.add(new_row) DBSession.delete(existing_row)
# Commit semua perubahan
DBSession.flush() DBSession.flush()
return row # Kembalikan row jika ada, atau None jika tidak digunakan return row
def get_existing_departemen(self, user_id): def get_existing_departemen(self, user_id):
# Ambil semua departemen yang sudah ada untuk user tertentu
q = DBSession.query(DepartemenUser).filter_by(user_id=user_id)
# Pastikan hanya mengembalikan string dari departemen_id yang valid
return set(str(row.departemen_id) for row in q if row.departemen_id is not None)
\ No newline at end of file \ No newline at end of file
row = DBSession.query(DepartemenUser).filter_by(user_id=user_id).first()
result = set()
if row:
if row.departemen_id:
result.add(str(row.departemen_id))
if row.sub_departemen:
result.add(str(row.sub_departemen))
return result
def get_values(self, row, istime=False):
d = super(Views, self).get_values(row, istime)
d["departemen_id"] = self.get_existing_departemen(row.user_id)
return d
\ No newline at end of file \ No newline at end of file
...@@ -5,7 +5,7 @@ from opensipkd.tools.buttons import btn_close, btn_delete, btn_view ...@@ -5,7 +5,7 @@ from opensipkd.tools.buttons import btn_close, btn_delete, btn_view
from pyramid.i18n import TranslationStringFactory from pyramid.i18n import TranslationStringFactory
from pyramid.view import view_config from pyramid.view import view_config
from . import BaseView from . import BaseView, button_import # Tombol import
from opensipkd.models import (DBSession, User, ExternalIdentity) from opensipkd.models import (DBSession, User, ExternalIdentity)
_ = TranslationStringFactory('user') _ = TranslationStringFactory('user')
...@@ -38,30 +38,35 @@ class UserExt(BaseView): ...@@ -38,30 +38,35 @@ class UserExt(BaseView):
self.edit_schema = EditSchema self.edit_schema = EditSchema
self.list_schema = ListSchema self.list_schema = ListSchema
self.list_route = "user-ext" self.list_route = "user-ext"
self.list_buttons = (btn_close,) self.list_buttons = (btn_close,) + self.list_report + (button_import,)
self.table = ExternalIdentity self.table = ExternalIdentity
@view_config( @view_config(
route_name='user-ext', renderer='templates/table.pt', route_name='user-ext',
renderer='templates/table.pt',
permission='user-view') permission='user-view')
def view_list(self): def view_list(self):
form = super(UserExt, self).view_list(allow_edit=False, allow_delete=False) form = super(UserExt, self).view_list(allow_edit=False, allow_delete=False)
return form return form
@view_config( @view_config(
route_name='user-ext-view', renderer='templates/form.pt', route_name='user-ext-view',
renderer='templates/form.pt',
permission='user-view') permission='user-view')
def view_view(self): def view_view(self):
return super(UserExt, self).view_view() return super(UserExt, self).view_view()
# Fungsi delete
@view_config( @view_config(
route_name='user-ext-delete', renderer='templates/form.pt', route_name='user-ext-delete',
renderer='templates/form.pt',
permission='user-edit') permission='user-edit')
def view_delete(self): def view_delete(self):
return super(UserExt, self).view_delete() return super(UserExt, self).view_delete()
@view_config( @view_config(
route_name='user-ext-act', renderer='json', permission='user-view') route_name='user-ext-act',
renderer='json', permission='user-view')
def view_act(self): def view_act(self):
return super(UserExt, self).view_act() return super(UserExt, self).view_act()
...@@ -70,3 +75,13 @@ class UserExt(BaseView): ...@@ -70,3 +75,13 @@ class UserExt(BaseView):
def query_id(self): def query_id(self):
return DBSession.query(ExternalIdentity).filter_by(external_id=self.req.matchdict["id"]) return DBSession.query(ExternalIdentity).filter_by(external_id=self.req.matchdict["id"])
# Fungsi upload
@view_config(
route_name='user-ext-upload',
renderer='templates/form.pt',
permission='user-upload'
)
def view_upload(self):
self.upload_keys=["local_user_id"]
return super().view_upload(exts=(".csv", ".tsv"))
\ No newline at end of file \ No newline at end of file
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!