my_sppt.py 12.3 KB
import logging
import os
from datetime import datetime

import colander
from deform import widget, FileData
from tangsel.base import has_permission_
from tangsel.base.widgets import widget_os
from tangsel.base.models import Partner, DBSession
# from tangsel.pbb.models.tools import get_esppt_folder
from tangsel.pbb.esppt import SPPT_CLASS
from tangsel.pbb.esppt.models.es_log import PROSES_STATUS
from tangsel.tools import thousand, mem_tmp_store, number_only
from tangsel.tools.pbb import FixNop
from pyramid.view import view_config
from datatables import ColumnDT
from sqlalchemy import and_, or_, func

from ..models import LogEsppt, PartnerNop
from ..tools import get_sppt
from ..views import BaseView
from tangsel.tools.buttons import btn_add, btn_close, btn_save, btn_cancel, btn_recall
log = logging.getLogger(__name__)

btn_recall.title = "Pengajuan Ulang"
btn_recall.css_class = "btn-success"


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")
    tahun = colander.SchemaNode(
        colander.String(),
        widget=widget.TextInputWidget(mask='9999'),
        title="Tahun Pajak")


class ListSchema(colander.Schema):
    id = colander.SchemaNode(
        colander.Integer(),
        title="Action",
        global_search=False)
    nop = colander.SchemaNode(
        colander.String(),
        global_search=False,
        title="NOP")
    tahun = colander.SchemaNode(
        colander.String(),
        aligned="text-center",
        title="Tahun",
        searchable=True,
        search_method="ilike",
        global_search=False)
    nm_wp_sppt = colander.SchemaNode(
        colander.String(),
        title="Nama WP")
    # pbb_yg_harus_dibayar_sppt = colander.SchemaNode(
    #     colander.String(),
    #     thousand={"separator": "."},
    #     title="Ketetapan",
    #     searchable=True,
    #     search_method="yadcf_range_number",
    #     global_search=False)
    siklus_sppt = colander.SchemaNode(
        colander.String(),
        global_search=False,
        title="Siklus")
    file_name = colander.SchemaNode(
        colander.String(),
        title="Link")
    nama = colander.SchemaNode(
        colander.String(),
        title="Nama",
        field=Partner.nama,
    )
    status = colander.SchemaNode(
        colander.Integer(),
        widget=widget.SelectWidget(values=PROSES_STATUS),
        visible=False,
        searchable=True,
        search_method="numeric",
        global_search=False,
    )
    status_text = colander.SchemaNode(
        colander.String(),
        title="Status Text",
        global_search=False,
        width=100)

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


class EditSchema(colander.Schema):
    nop = colander.SchemaNode(
        colander.String(),
        missing=colander.drop,
        oid="nop")
    thn_pajak_sppt = colander.SchemaNode(
        colander.String(),
        missing=colander.drop,
        title="Tahun Pajak",
    )
    nm_wp_sppt = colander.SchemaNode(
        colander.String(),
        widget=widget.TextInputWidget(readonly=True),
        missing=colander.drop,
        title="Nama WP"
    )
    jln_wp_sppt = colander.SchemaNode(
        colander.String(),
        widget=widget.TextInputWidget(readonly=True),
        missing=colander.drop,
        title="Alamat"
    )
    blok_kav_no_wp = colander.MappingSchema(
        colander.String(),
        widget=widget_os.BlokKavNoWidget(readonly=True),
        missing=colander.drop,
        title="Blok/Kav/No"
    )
    kelurahan_wp_sppt = colander.SchemaNode(
        colander.String(),
        widget=widget.TextInputWidget(readonly=True),
        missing=colander.drop,
        title="Kelurahan"
    )
    kota_wp_sppt = colander.SchemaNode(
        colander.String(),
        widget=widget.TextInputWidget(readonly=True),
        missing=colander.drop,
        title="Kota"
    )
    kd_pos_wp_sppt = colander.SchemaNode(
        colander.String(),
        widget=widget.TextInputWidget(readonly=True),
        missing=colander.drop,
        title="Kode POS"
    )

    luas_bumi_sppt = colander.SchemaNode(
        colander.String(),
        missing=colander.drop,
        title="Luas Bumi",
        aligned="text-right"

    )
    luas_bng_sppt = colander.SchemaNode(
        colander.String(),
        missing=colander.drop,
        title="Luas Bangunan",
        aligned="text-right"

    )
    njop_bumi_sppt = colander.SchemaNode(
        colander.String(),
        missing=colander.drop,
        title="NJOP Bumi",
        aligned="text-right"

    )
    njop_bng_sppt = colander.SchemaNode(
        colander.String(),
        missing=colander.drop,
        title="NJOP Bangunan",
        aligned="text-right"

    )
    njop = colander.SchemaNode(
        colander.String(),
        missing=colander.drop,
        title="NJOP",
        aligned="text-right"

    )

    pbb_yg_harus_dibayar_sppt = colander.SchemaNode(
        colander.String(),
        missing=colander.drop,
        title="Ketetapan",
        aligned="text-right"

    )
    tgl_jatuh_tempo_sppt = colander.SchemaNode(
        colander.String(),
        missing=colander.drop,
        title="Jatuh Tempo",
        aligned="text-center"

    )
    status = colander.SchemaNode(
        colander.String(),
        missing=colander.drop,
        title="Status"
    )
    file_name = colander.SchemaNode(
        FileData(),
        widget=widget.FileUploadWidget(tmpstore=mem_tmp_store),
        missing=colander.drop,
        title="e-SPPT"
    )


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-mysppt"
        self.table = LogEsppt
        self.filter_columns = False
        self.allow_edit = False
        self.allow_add=False
        self.allow_delete = False

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

        def err_nop():
            exc["nop"] = '''NOP tidak ditemukan atau belum disetujui <br> 
                            silakan lakukan registrasi di <a href='%s'>myNOP</a> ''' \
                                % self.req.route_url("esppt-mynop-add")
            raise exc

        year = datetime.now().year

        def err_tahun():
            exc["tahun"] = f"Tahun antara 2013 s.d {year}"
            raise exc

        def err_found():
            exc.msg = f"NOP {value['nop']} Tahun {value['tahun']} sudah ada"
            raise exc

        nop = number_only(value["nop"])
        tahun = number_only(value["tahun"])
        partner_nop = PartnerNop.query().filter(PartnerNop.nop == nop, PartnerNop.status==1).first()
        if not partner_nop:
            err_nop()

        if int(tahun)>year:
            err_tahun()
        if 2013 < int(tahun) > year:
            err_tahun()

      
        nop = FixNop(nop)
        sppt_log = LogEsppt.query(). \
            filter(self.table.tahun == tahun,
                   self.table.kd_propinsi == nop["kd_propinsi"],
                   self.table.kd_dati2 == nop["kd_dati2"],
                   self.table.kd_kecamatan == nop["kd_kecamatan"],
                   self.table.kd_kelurahan == nop["kd_kelurahan"],
                   self.table.kd_blok == nop["kd_blok"],
                   self.table.no_urut == nop["no_urut"],
                   self.table.kd_jns_op == nop["kd_jns_op"]
                   ).first()
        if sppt_log:
            err_found()
        value.update(nop.to_dict())
        value["siklus_sppt"] = 0
        value["status"] = -1
        if int(tahun) < year:
            value["status"] = 4
        

    def list_join(self, query):
        return query.outerjoin(Partner, Partner.id == LogEsppt.partner_id)

    def list_filter(self, query):
        if not has_permission_(self.req, 'esppt-admin'):
            partner = self.get_partner()
            partner_id = partner and partner.id or 0
            partner_nop = self.db_session.query(PartnerNop.nop).filter(
                PartnerNop.status == 1,
                PartnerNop.partner_id == partner_id)
            nop_filters = []
            for d in partner_nop:
                nop = FixNop(d[0])
                nop_filters.append(
                    and_(self.table.kd_propinsi == nop["kd_propinsi"],
                         self.table.kd_dati2 == nop["kd_dati2"],
                         self.table.kd_kecamatan == nop["kd_kecamatan"],
                         self.table.kd_kelurahan == nop["kd_kelurahan"],
                         self.table.kd_blok == nop["kd_blok"],
                         self.table.no_urut == nop["no_urut"],
                         self.table.kd_jns_op == nop["kd_jns_op"])
                )
            # todo: integrasi dengan NIK yang sama
            if not nop_filters:
                return query.filter(self.table.kd_propinsi == '00')

            query = query.filter(or_(*nop_filters))
        return query.order_by(self.table.nop, self.table.tahun, self.table.siklus_sppt)

    def view_act(self):
        result = super().view_act()
        if self.req.matchdict["act"] == "grid":
            if "data" in result:
                for r in result["data"]:
                    if r["status"] == 1:
                        r["file_name"] = ""

        return result

    # def next_act(self):
    #     url_dict = self.req.matchdict
    #     if url_dict['act'] == 'createpdf_draft':
    #         from tangsel.pbb.esppt.scripts.utils import proses_sppt_log, flush
    #         from tangsel.pbb.esppt.views.gen_sppt import create_pdf
    #         import transaction
    #         from tangsel.base import get_params
    #         proses_sppt_log()

    # @view_config(route_name='esppt-mysppt-add', renderer='templates/form.pt',
    #              permission='view')
    # def view_add(self):
    #     self.buttons = (btn_save, btn_cancel)
    #     return super().view_add()

    # @view_config(route_name='esppt-mysppt-view', renderer='templates/form.pt',
    #              permission='view')
    # def view_view(self):
    #     self.buttons = (btn_recall, btn_close,)
    #     return super().view_view()

    def query_id(self):
        qry = super().query_id()
        return self.list_filter(qry)

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

    def next_view(self, form, **kwargs):
        if 'recall' in self.req.POST:
            values = dict(status=-1)
            if self.save(values, self.req.user, **kwargs):
                return self.route_list(msg="Berhasil pengajuan ulang.")
        return self.route_list()

    def nop_from_dict(self, d):
        nop = FixNop("")
        nop.from_dict(d)
        return nop.get_formatted()

    def save_request(self, values, row=None):
        # log.debug(values)
        partner = self.get_partner()
        values['partner_id'] = partner.id
        values['destination'] = partner.email
        return super().save_request(values, row)

    def get_values(self, row, istime=False):
        values = get_sppt(row.nop, row.tahun)
        if not values:
            return
            # self.id_not_found()

        values["nop"] = self.nop_from_dict(values)
        values["blok_kav_no_wp"] = "|".join(
            [values.get("blok_kav_no_wp_sppt", '-'), values.get("rt_wp_sppt", '000'),
             values.get("rw_wp_sppt", '000')])
        status_bayar = int(values.get("status_pembayaran_sppt", 0))
        values["status"] = status_bayar and "Lunas" or "Terhutang"
        values["njop"] = \
            values.get("njop_bumi_sppt", 0) + values.get("njop_bng_sppt", 0)
        for k, v in values.items():
            if type(v) in [float, int]:
                values[k] = thousand(v)
        values["kd_pos_wp_sppt"] = values.get("kd_pos_wp_sppt", "")
        if row.file_name:
            filename = row.file_name
            url = self.req.static_url(SPPT_CLASS.files_final)
            preview_url = os.path.join(url, filename)
            values["file_name"] = {"uid": filename.split(".")[0],
                                   "filename": filename,
                                   "preview_url": preview_url
                                   }

        return values