parsial.py 8.3 KB
import logging
import os
import colander
from deform import widget, FileData
from tangsel.tools import mem_tmp_store, number_only
from deform import ValidationFailure, widget
from tangsel.base.models import flush
# from tangsel.pbb.tools import WIDGET_NOP
from tangsel.pbb.esppt import SPPT_CLASS
from tangsel.tools import number_only
from tangsel.tools.buttons import btn_cancel, btn_proses
from tangsel.tools.pbb import FixNop
from ..models import Partner, LogEsppt, PartnerNop
from ..models.es_log import Passphrase
from ..tools import get_data
from . import BaseView
from .my_sppt import ListSchema, btn_close
# , list_column

log = logging.getLogger(__name__)
btn_proses.title = "Proses"


class AddSchema(colander.Schema):
    nop = colander.SchemaNode(
        colander.String(),
        # widget=WIDGET_NOP,
        oid="nop")
    tahun = colander.SchemaNode(
        colander.String(),
        title="Tahun SPPT",
        oid="tahun")
    # nm_wp_sppt = colander.SchemaNode(
    #     colander.String(),
    #     title="Nama WP")
    # siklus_sppt = colander.SchemaNode(
    #     colander.String(),
    #     global_search=False,
    #     title="Siklus")
    # file_name = colander.SchemaNode(
    #     colander.String(),
    #     title="Link")
    
    # password = colander.SchemaNode(
    #     colander.String(),
    #     title="Passphrase",
    #     oid="password")


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

    def after_bind(self, schema, kw):
        log.debug(schema)
        log.debug(kw)
        schema["nop"].widget = widget.TextInputWidget(readonly=True)
        schema["nop"].missing = colander.drop
        schema["tahun"].widget = widget.TextInputWidget(readonly=True)
        schema["tahun"].missing = colander.drop
        schema["file_name"] = colander.SchemaNode(
            FileData(),
            widget=widget.FileUploadWidget(tmpstore=mem_tmp_store),
            missing=colander.drop,
            title="e-SPPT"
        )
        del schema["status_text"]


SESS_ADD_FAILED = 'Tambah proses gagal'
SESS_EDIT_FAILED = 'Edit proses gagal'


def get_pbb_data(method, data):
    resp = get_data(method, data)
    if resp:
        return resp
    raise Exception("Gagal mendapatkan data dari server")


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


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

    # def list_filter(self, query, **kwargs):
    #     return query.filter(self.table.status != 1)

    def next_edit(self, form, **kwargs):
        row = kwargs.get("row")
        request = self.req
        resources = form.get_widget_resources()
        if row.status != 1 and "proses" in self.req.POST:
            controls = request.POST.items()
            try:
                controls = form.validate(controls)
            except ValidationFailure as e:
                log.debug(f"Edit Error: {str(e.error)}")
                log.debug(f"Edit Data: {e.cstruct}")
                values = self.get_values(row)
                form.set_appstruct(values)
                return dict(form=form.render(),
                            table=None,
                            scripts=self.form_scripts, css=resources["css"],
                            js=resources["js"])
            row.status = 0
            flush(row)
            self.ses.flash('Data Sudah masuk kedalam antrian kembali')
        return self.route_list()

    # @view_config(route_name='esppt-parsial-edit',
    #              renderer='templates/form.pt',
    #              permission='esppt-tetap')
    def view_edit(self):
        self.buttons = (btn_proses, btn_cancel)
        return super().view_edit()

    def get_values(self, row, istime=False):
        v = super().get_values(row, istime)
        v["nop"] = row.nop
        v["status_text"] = row.status_text
        if row.file_name:
            filename=row.file_name
            url=self.req.static_url(SPPT_CLASS.files_final)
            preview_url=os.path.join(url, filename)
            v["file_name"]={"uid": filename.split(".")[0],
                                 "filename": filename,
                                 "preview_url": preview_url
                                 }
        v["nama"]=row.partner and row.partner.nama or ""
        return v

    def esppt_parsial_add(self):
        btn_proses.type = "submit"
        self.buttons = (btn_proses, btn_cancel)
        return super().view_add()

    def form_response(self, form, values, msg):
        self.ses.flash(msg, "error")
        form.set_appstruct(values)
        return dict(form=form.render())

    def get_sppt(self, values):
        if SPPT_CLASS.mirror_url:
            data = {
                'where': [
                    {
                        "key": "nop",
                        "val": values["nop"]},
                    {
                        "key": "thn_pajak_sppt",
                        "val": values["tahun"]
                    }
                ]}
            try:
                resp = get_pbb_data("get_sppt", data)
            except Exception as e:
                msg = str(e)
                raise Exception(msg)

            return resp["record"][0]
        else:
            from tangsel.pbb.models import Sppt
            sppt = Sppt.get_by_nop(values["nop"]). \
                filter_by(thn_pajak_sppt=values["tahun"]).first()
            if not sppt:
                raise Exception("Data tidak ada")
            sppt = dict(sppt.__dict__)
            sppt.pop("_sa_instance_state", None)
            return sppt

    def next_add(self, form, **kwargs):
        if self.req.POST:
            if "proses" in self.req.POST:
                controls = self.req.POST.items()
                try:
                    c = form.validate(controls)
                except ValidationFailure as e:
                    return self.form_response(form, e.cstruct, str(e))

                values = dict(c)
                try:
                    sppt = self.get_sppt(values)
                    destination = self.get_destination(values)
                except Exception as e:
                    return self.form_response(form, values, str(e))

                values["destination"] = destination
                values["siklus_sppt"] = sppt["siklus_sppt"]
                self.save_request(values)
                msg = "Berhasil Tambah Data"
                return self.route_list(msg)

    def get_destination(self, values):
        values["nop"] = number_only(values["nop"])
        data = {
            'where': [
                {
                    "key": "nop",
                    "val": values["nop"]},
            ]}
        try:
            resp = get_pbb_data("get_nop", data)
        except Exception as msg:
            raise Exception(str(msg))

        objek = resp["record"][0]
        msg = "Data tidak ada"
        if objek:
            subjek_pajak_id = objek["subjek_pajak_id"]
            log.debug(f"NOP to be executed: {values['nop']}")
            partner_nop = PartnerNop.query().filter(
                PartnerNop.nop == values["nop"],
                PartnerNop.status == 1).first()
            if partner_nop:
                partner = Partner.query_id(partner_nop.partner_id).first()
                if partner and partner.email:
                    return partner.email

            msg = f"NIK {subjek_pajak_id} tidak ditemukan di data wajib pajak"
        raise Exception(msg)

    def save_request(self, values, row=None):
        row = LogEsppt.query_nop(values['nop']). \
            filter_by(status=0,
                      siklus_sppt=values["siklus_sppt"]). \
            first()
        nop = FixNop(values["nop"])
        values.update(nop.to_dict())
        if not row:
            self.save(values, self.req.user)

        passphrase = Passphrase.query().first()
        if not passphrase:
            passphrase = Passphrase()

        passphrase.password = values["password"]
        flush(passphrase)
        LogEsppt.query().filter(LogEsppt.status < 0).update(
            {LogEsppt.status: 0})