user_dep.py 6.08 KB
import colander
from deform import widget
from pyramid.view import view_config
from . import BaseView
from ...models import User, DepartemenUser, Departemen, DBSession
from .departemen import departemen_widget, get_departemen_list
from .user import user_widget, user_select, user_list
from pyramid.i18n import TranslationStringFactory

_ = TranslationStringFactory('myapp')

@colander.deferred
def departemen_widget(node, kw):
    values = kw.get('departemen_list', [])
    return widget.CheckboxChoiceWidget(values=values, placeholder='Pilih Departemen')

class ListSchema(colander.Schema):
    id = colander.SchemaNode(
        colander.Integer(),
        title="Action"
    )
    user_name = colander.SchemaNode(
        colander.String(),
        field=User.user_name,
        title="User"
    )
    departemen_name = colander.SchemaNode(
        colander.String(),
        field=Departemen.nama,
        title="Departemen"
    )

@colander.deferred
def departemen_checkbox_widget(node, kw):
    values = kw.get('departemen_list', [])
    return widget.CheckboxChoiceWidget(values=values)

class AddSchema(colander.Schema):
    user_id = colander.SchemaNode(
        colander.Integer(),
        widget=widget.SelectWidget(values=User.get_list()),
        oid="user_id",
        title="User",
    )
    departemen_id = colander.SchemaNode(
        colander.Set(),  # Tetap menggunakan colander.Set()
        widget=departemen_checkbox_widget,
        oid="departemen_id",
        title="Departemen",
    )

class EditSchema(AddSchema):
    id = colander.SchemaNode(
        colander.String(),
        missing=colander.drop,
        widget=widget.HiddenWidget(readonly=True)
    )

class Views(BaseView):
    def __init__(self, request):
        super().__init__(request)
        self.request = request
        self.list_schema = ListSchema
        self.add_schema = AddSchema
        self.edit_schema = EditSchema
        self.list_route = 'user-departemen'
        self.table = DepartemenUser

    def list_join(self, query, **kwargs):
        return query.outerjoin(Departemen, Departemen.id == self.table.departemen_id) \
            .outerjoin(User, User.id == self.table.user_id)

    @view_config(route_name='user-departemen', renderer='templates/table.pt',
                 permission='user-view')
    def view_list(self, **kwargs):
        return super().view_list(**kwargs)

    @view_config(route_name='user-departemen-act', renderer='json',
                 permission='user-view')
    def view_act(self):
        return super().view_act()

    def get_bindings(self, row=None):
        return {
            "departemen_list": get_departemen_list(),
            "user_list": user_list()
        }

    @view_config(route_name='user-departemen-add', renderer='templates/form.pt',
                 permission='user-edit')
    def view_add(self):
        return super().view_add()

    @view_config(route_name='user-departemen-view', renderer='templates/form.pt',
                 permission='user-view')
    def view_view(self):
        return super().view_view()

    @view_config(route_name='user-departemen-delete', renderer='templates/form.pt',
                 permission='user-edit')
    def view_delete(self):
        return super().view_delete()

    @view_config(route_name='user-departemen-edit', renderer='templates/form.pt',
                 permission='user-edit')
    def view_edit(self):
        return super().view_edit()

    def save_request(self, values, row=None):
        # Ambil user_id dari values
        user_id = values.get("user_id")
        if not user_id:
            return None  # Tidak ada user_id, kembalikan None atau tangani sesuai kebutuhan

        # Jika ada departemen_id dalam 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(
                str(departemen_id) for departemen_id in values["departemen_id"]
                if departemen_id is not None and str(departemen_id) != "None"
            )

            # Departemen yang tidak dipilih lagi (akan dihapus)
            unused_departemen = existing_departemen - selected_departemen

            # Hapus departemen yang tidak dipilih lagi, pastikan hanya integer yang valid
            if unused_departemen:
                valid_unused = [int(d) for d in unused_departemen if d.isdigit()]
                if valid_unused:
                    DBSession.query(DepartemenUser).filter_by(user_id=user_id) \
                        .filter(DepartemenUser.departemen_id.in_(valid_unused)) \
                        .delete(synchronize_session=False)

            # Departemen baru yang dipilih (akan ditambahkan)
            new_departemen = selected_departemen - existing_departemen

            # 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,
                        departemen_id=int(departemen_id)
                    ).first()
                    if not exists:  # Hanya tambahkan jika belum ada
                        new_row = DepartemenUser(
                            user_id=user_id,
                            departemen_id=int(departemen_id)  # Konversi ke integer
                        )
                        DBSession.add(new_row)

        # Commit semua perubahan
        DBSession.flush()
        return row  # Kembalikan row jika ada, atau None jika tidak digunakan

    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)