my_nop.py 8.09 KB
import logging
import re
import os
import colander
from deform import widget, FileData, Button
from tangsel.base import has_permission_
from tangsel.base.tools.api import config_pars_rpc_url
from tangsel.base.models import Partner, flush
from tangsel.tools import mem_tmp_store, image_validator, Upload, img_exts
from tangsel.tools.buttons import (
    btn_add, btn_close, btn_save, btn_cancel, btn_delete, btn_recall)
from tangsel.tools.api import send_rpc
from pyramid.view import view_config
from sqlalchemy import or_
from tangsel.pbb.esppt import SPPT_CLASS

from ..models import STATUS_NOP, PartnerNop
from ..views import BaseView

log = logging.getLogger(__name__)
btn_add.title = "Tambah"
btn_close.title = "Tutup"
btn_save.title = "Simpan"
btn_cancel.title = "Batal"
btn_delete.title = 'Hapus'


class ListSchema(colander.Schema):
    id = colander.SchemaNode(
        colander.Integer(),
        title="Action")
    nop_formatted = colander.SchemaNode(
        colander.String(),
        title="NOP")
    thn_awal = colander.SchemaNode(
        colander.String(),
        title="Thn Kepemilikan", width=100)
    thn_akhir = colander.SchemaNode(
        colander.String(),
        title="Penetapan Akhir", width=100)
    dokumen = colander.SchemaNode(
        colander.String(),
        oid="dokumen",
        title="Dokumen"
    )
    status = colander.SchemaNode(
        colander.String(),
        widget=widget.SelectWidget(values=STATUS_NOP)
    )
    # status_text = colander.SchemaNode(
    #     colander.String(),
    #     oid="status_text",
    #     title="Status",
    #     width=100)

    def after_bind(self, schema, kw):
        request = kw.get("request")
        self["dokumen"].url = request.static_url(SPPT_CLASS.files_bukti)


class AddSchema(colander.Schema):
    nop = colander.SchemaNode(
        colander.String(),
        widget=widget.TextInputWidget(mask="99.99-999.999-999.9999.9"),
        oid="nop",
        description="PP.KK-CCC.DDD-BBB.UUUU.J")
    thn_awal = colander.SchemaNode(
        colander.Integer(),
        title="Tahun Kepemilikan",
    )
    # thn_akhir = colander.SchemaNode(
    #     colander.String(),
    #     missing=colander.drop,
    #     title="Tahun Akhir"
    # )
    dokumen = colander.SchemaNode(
        FileData(),
        widget=widget.FileUploadWidget(
            mem_tmp_store,
            accept="application/pdf, image/png, image/jpg, image/jpeg"),
        title="Dokumen",
        validator=image_validator)
    status = colander.SchemaNode(
        colander.Integer(),
        widget=widget.HiddenWidget(readonly=True),
        missing=colander.drop)


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


class Views(BaseView):
    def __init__(self, request):
        super().__init__(request)
        self.list_schema = ListSchema
        self.add_schema = AddSchema
        self.edit_schema = EditSchema
        self.list_route = "esppt-mynop"
        self.table = PartnerNop

    def form_validator(self, form, values):
        exc = colander.Invalid(form, "")

        def err_nop():
            exc["nop"] = "NOP tidak ditemukan"
            raise exc

        def err_nopexists():
            exc["nop"] = "NOP sudah ada"
            raise exc

        def err_partner():
            exc.msg = "Silahkan lakukan pengisian data pribadi"
            raise exc

        nop = re.sub("\D", "", values["nop"])
        values["nop"] = nop

        partner = self.get_partner()
        if not partner:
            err_partner()

        nop_exist = PartnerNop.query().filter(PartnerNop.nop == nop,
                                              PartnerNop.partner_id == partner.id).first()
        if nop_exist:
            err_nopexists()

        if not SPPT_CLASS.rpc_pbb_mirror_url:
            from tangsel.pbb.models import DatObjekPajak
            dop = DatObjekPajak.query_nop(nop).first()
            if not dop:
                err_nop()
            result = dict(dop.__dict__)
            result.pop("_sa_instance_state", None)
        else:
            data = {'where': [
                {
                    "key": "nop",
                    "val": nop},
            ]}
            auth = config_pars_rpc_url("rpc_pbb_mirror.url", "get_nop")
            resp = send_rpc(auth, data)
            if not resp or "error" in resp:
                err_nop()
            result = resp["result"]["data"]["record"][0]
        values.update(result)

        values["partner_id"] = partner.id
        if partner.kode.strip() == result["subjek_pajak_id"].strip():
            values["status"] = 1

    # @view_config(route_name='esppt-nop-edit', renderer='templates/form.pt',
    #              permission='view')
    # def view_edit(self):
    #     self.buttons = (btn_save, btn_cancel)
    #     row = self.query_id().first()
    #     if not row:
    #         return self.id_not_found()
    #     if row.status:
    #         self.ses.flash("Data hanya bisa dilihat", "error")
    #         return self.route_list()
    #     return super().view_edit()

    def before_delete(self, row):
        if (getattr(row, 'status', '') == 1):
            msg = "{} tidak bisa dihapus".format(getattr(row, 'status_text'))
            self.req.session.flash(msg, 'error')
            raise self.route_list()

    def view_view(self):
        request = self.req
        row = self.query_id().first()
        if not row:
            return self.id_not_found()

        bindings = self.get_bindings(row)
        btn_recall = Button('recall', title='Proses Ulang', css_class="btn-info",
                            type="submit")
        button = row.status == 2 and btn_recall or btn_cancel
        form = self.get_form(self.edit_schema, buttons=(button, btn_close),
                             bindings=bindings)
        if request.POST:
            msg = ""
            if "cancel" in request.POST:
                row.status = 2
                flush(row)
                msg = "Berhasil memproses pembatalan"
            elif "recall" in request.POST:
                row.status = 0
                flush(row)
                msg = "Berhasil memasukan ke dalam draft"
            
            return self.route_list(msg=msg)

        form.set_appstruct(self.get_values(row))
        return dict(form=form.render(readonly=True),
                    table=None,
                    scripts=self.form_scripts)

    def list_filter(self, query):
        # todo: integrasi dengan NIK yang sama
        if not has_permission_(self.req, 'esppt-admin'):
            query = query.filter(self.table.create_uid == self.req.user.id)
        return query.order_by(self.table.nop)

    def query_id(self):
        qry = super().query_id()
        return qry.filter(self.table.create_uid == self.req.user.id)

    def save_request(self, values, row=None):
        if "dokumen" in values and values["dokumen"]:
            from webob.compat import cgi_FieldStorage
            dok_type = type(self.req.POST['upload'])
            log.debug(f"Upload Data Type : {dok_type}")
            if dok_type == cgi_FieldStorage:
                folder = SPPT_CLASS.files_bukti
                upload = Upload(folder)
                file_name = upload.save(self.req, 'upload', img_exts)
                log.debug(f"Bukti: {folder}/{file_name}")
                values["dokumen"] = file_name
            else:
                del values["dokumen"]
        if not 'status' in values or not values['status']:
            values.update(dict(status=0))
        row = super().save_request(values, row)
        return row

    def get_partner(self):
        return Partner.query_email(self.req.user.email).first()

    def get_values(self, row, istime=False):
        d = super().get_values(row, istime)
        if "dokumen" in d and d["dokumen"]:
            filename = d["dokumen"]
            url = self.req.static_url(SPPT_CLASS.files_bukti)
            preview_url = os.path.join(url, filename)
            d["dokumen"] = {"uid": filename.split(".")[0],
                            "filename": filename,
                            "preview_url": preview_url
                            }
        return d