__init__.py 8.37 KB
from ISO8583.ISOErrors import BitNotSet
import transaction
from pyramid_rpc.jsonrpc import jsonrpc_method
# from linkaja.models import Rpc
from opensipkd.waktu import create_now
from opensipkd.string import FixLength
from opensipkd.jsonrpc.exc import (
    JsonRpcInvalidParams,
    JsonRpcBankNotFound,
    JsonRpcBillerNetwork,
    JsonRpcBillNotFound,
    JsonRpcBillAlreadyPaid,
    )
from ...iso8583.tools import iso_to_dict
from ...common import BaseIsoView
from ...models.conf import QConf
from ...models.log_iso import Log
# from opensipkd.iso8583.bjb.pbb.structure import INVOICE_PROFILE
# from opensipkd.iso8583.bjb.pbb.agratek.models import Log


ROUTE = 'rpc'
conf = dict()

TANGGAL = [
    ('Tahun', 4, 'N'),
    ('Bulan', 2, 'N'),
    ('Tanggal', 2, 'N')]


def pbb_response(iso):
    d = iso_to_dict(iso)
    if d[39] == '00':
        pass
    elif d[39] == '55':
        raise JsonRpcBillNotFound()
    elif d[39] == '54':
        raise JsonRpcBillAlreadyPaid()
    else:
        raise JsonRpcBillerNetwork()

    profile = FixLength(INVOICE_PROFILE)
    profile.set_raw(d[62])
    tgl = FixLength(TANGGAL)
    tgl.set_raw(profile['Jatuh Tempo'])
    jatuh_tempo = '-'.join([tgl['Tanggal'], tgl['Bulan'], tgl['Tahun']])
    return dict(
            stan=d[11],
            invoice_id=d[61],
            amount=int(d[4]),
            nama_wp=profile['Nama'].strip(),
            alamat_op=profile['Lokasi'].strip(),
            kelurahan_op=profile['Nama Kelurahan'].strip(),
            kecamatan_op=profile['Nama Kecamatan'].strip(),
            provinsi_op=profile['Nama Propinsi'].strip(),
            luas_tanah=int(profile['Luas Tanah']),
            luas_bangunan=int(profile['Luas Bangunan']),
            jatuh_tempo=jatuh_tempo,
            tagihan=int(profile['Tagihan']),
            denda=int(profile['Denda']),
            total=int(profile['Total Bayar']),
            discount=int(profile['Discount'] or 0))

def webr_response(iso):
    d = iso_to_dict(iso)
    if d[39] == '00':
        pass
    elif d[39] == '55':
        raise JsonRpcBillNotFound()
    elif d[39] == '54':
        raise JsonRpcBillAlreadyPaid()
    else:
        raise JsonRpcBillerNetwork()
    profile = FixLength(INVOICE_PROFILE)
    profile.set_raw(d[62])
    # tgl = FixLength(TANGGAL)
    # tgl.set_raw(profile['Jatuh Tempo'])
    # jatuh_tempo = '-'.join([tgl['Tanggal'], tgl['Bulan'], tgl['Tahun']])
    result = dict(
            stan=d[11],
            invoice_id=d[61],
            amount=int(d[4]),
            )
    result.update(profile.to_dict())
    return result

# dipindah kemasing2 module di job
# def default_response(iso):
#     d = iso_to_dict(iso)
#     if d[39] == '00':
#         pass
#     elif d[39] == '55':
#         raise JsonRpcBillNotFound()
#     elif d[39] == '54':
#         raise JsonRpcBillAlreadyPaid()
#     else:
#         raise JsonRpcBillerNetwork()
#     profile = FixLength(INVOICE_PROFILE)
#     profile.set_raw(d[62])
#     tgl = FixLength(TANGGAL)
#     tgl.set_raw(profile['Jatuh Tempo'])
#     jatuh_tempo = '-'.join([tgl['Tanggal'], tgl['Bulan'], tgl['Tahun']])
#     return dict(
#             stan=d[11],
#             invoice_id=d[61],
#             amount=int(d[4]),
#             # nama_wp=profile['Nama'].strip(),
#             # alamat_op=profile['Lokasi'].strip(),
#             # kelurahan_op=profile['Nama Kelurahan'].strip(),
#             # kecamatan_op=profile['Nama Kecamatan'].strip(),
#             # provinsi_op=profile['Nama Propinsi'].strip(),
#             # luas_tanah=int(profile['Luas Tanah']),
#             # luas_bangunan=int(profile['Luas Bangunan']),
#             # jatuh_tempo=jatuh_tempo,
#             # tagihan=int(profile['Tagihan']),
#             # denda=int(profile['Denda']),
#             # total=int(profile['Total Bayar']),
#             # discount=int(profile['Discount'] or 0)
#     )


class View(BaseIsoView):
    def __init__(self, request):
        super().__init__(request)
        self.qconf = QConf(request.dbsession)

    def get_name(self):  # Override
        return 'rpc'

    def get_allowed_ip(self):  # Override
        row = self.qconf.get('rpc allowed ip')
        return row.as_list()

    def get_iso_conf_name(self):  # Override
        return self.qconf.get_value('rpc to iso8583')

    def create_web_log(self, method, p):
        # todo ini hanya untuk linkaja sepertinya gak perlu disini
        conn = self.get_connection()
        iso_func = getattr(conn.job, method)
        p['db_session'] = self.request.dbsession

        iso_req = p and iso_func(p) or iso_func()
        stan = iso_req.get_stan()

        web_log = Rpc(
                ip=self.request.client_addr, conf_name=self.get_name(),
                merchant='-', terminal='-', trx_type=method[:3],
                msisdn='-', acc_no=p['invoice_id'], stan=stan,
                trx_date=create_now())
        with transaction.manager:
            self.request.dbsession.add(web_log)
            self.request.dbsession.flush()
            self.request.dbsession.expunge_all()
        return web_log, iso_req, conn

    def create_iso_log(self, iso, web_log=None):
        conf = self.get_iso_conf()
        iso_log = Log(
            mti=iso.getMTI(),
            rpc_id=web_log and web_log.id or None,
            ip=conf['ip'],
            conf_name=conf['name'])
        for bit in iso.get_bit_definition():
            try:
                value = iso.getBit(bit)
            except BitNotSet:
                continue
            bit_str = str(bit).zfill(3)
            field = 'bit_' + bit_str
            setattr(iso_log, field, value)
        with transaction.manager:
            self.request.dbsession.add(iso_log)
            self.request.dbsession.flush()
            self.request.dbsession.expunge_all()

        return iso_log

    def get_response(self, rpc_method, p=dict(), iso_method=None):
        self.log_receive(rpc_method, p)
        method = iso_method or rpc_method
        conn = self.get_connection()
        print(conn.job)
        iso_func = getattr(conn.job, method)
        p['db_session'] = self.request.dbsession
        #On get request
        # web_log, iso_req, conn = self.create_web_log(method, p) # ini hanya untuk linkaja????
        iso_req = p and iso_func(p) or iso_func()
        stan = iso_req.get_stan()
        # before send request
        self.create_iso_log(iso_req) #web_log
        iso_resp = self.send_iso(conn, iso_req)
        #after get
        self.create_iso_log(iso_resp) # web_log
        data = conn.job.web_response(iso_resp)
        # xxxx
        # from opensipkd.iso8583.bjb.pbb.structure import INQUIRY_CODE as pbb_inquiry
        # from opensipkd.iso8583.bjb.pbb.structure import PAYMENT_CODE as pbb_payment
        # from opensipkd.iso8583.bjb.webr.structure import INQUIRY_CODE as webr_inquiry
        # from opensipkd.iso8583.bjb.webr.structure import PAYMENT_CODE as webr_payment

        # if iso_resp.getBit(3) in [pbb_inquiry, pbb_payment]:
        #     data = pbb_response(iso_resp)
        # elif iso_resp.getBit(3) in [webr_inquiry, webr_payment]:
        #     data = webr_response(iso_resp)
        # else:
        #     data = default_response(iso_resp)

        # data={"stan": stan}
        r = dict(code=0, message='OK', data=data)
        self.log_send(r)
        return r

    def not_found_error(self, hostname):  # Override
        msg = f'Host {hostname} tidak ditemukan di konfigurasi'
        return JsonRpcBankNotFound(message=msg)

    def not_running_error(self, hostname):  # Override
        msg = f'Host {hostname} belum terhubung'
        return JsonRpcBankNotFound(message=msg)

    def timeout_error(self):  # override
        return JsonRpcBillerNetwork(message='Timeout')

    def log_receive(self, method, p):
        msg = f'{method} {p}'
        super().log_receive(msg)

    @jsonrpc_method(endpoint=ROUTE)
    def echo(self, p):
        self.validate()
        return self.get_response('echo', iso_method='echo_request')

    @jsonrpc_method(endpoint=ROUTE)
    def inquiry(self, p):
        self.validate()
        return self.get_response('inquiry', p)

    @jsonrpc_method(endpoint=ROUTE)
    def payment(self, p):
        self.validate()
        return self.get_response('payment', p)

    @jsonrpc_method(endpoint=ROUTE)
    def reversal(self, p):
        self.validate()
        return self.get_response('reversal', p)


# Dipanggil read_conf.py
def init(cfg):
    conf.update(cfg)


def includeme(config):
    config.add_jsonrpc_endpoint('rpc', '/rpc')
    config.scan('.')