pbb.py 8.05 KB
import base64
import json
import logging
from datetime import datetime
import requests
import urllib3
from opensipkd.base import get_settings
from opensipkd.base.tools import get_random_number
from opensipkd.base.tools.api import JsonRpcBillAllreadyPaidError, JsonRpcBillNotFoundError
from pyramid_rpc.jsonrpc import JsonRpcError
from ..vendor import VendorClass

log = logging.getLogger(__name__)
urllib3.disable_warnings()


class Vendor(VendorClass):
    def __init__(self, vendor_produk, invoice_det):
        VendorClass.__init__(self, vendor_produk, invoice_det=invoice_det)
        # id_pel, customer_id, cust_trx, row
        settings = get_settings()
        self.mid = 'tangselpjk_mid' in settings and settings['tangselpjk_mid'] or None
        self.key = 'tangselpjk_key' in settings and settings['tangselpjk_key'] or None
        self.url = 'tangselpjk_url' in settings and settings['tangselpjk_url'] or None
        key = ":".join([self.mid, self.key]).encode()
        self.auth = base64.b64encode(key).decode()
        self.inq_url = '{0}/pbbJson/inq'.format(self.url)
        self.pay_url = '{0}/pbbJson/pay'.format(self.url)

    def get_headers(self):
        return {'Content-Type': 'application/json'}

    def get_url(self, url=None):
        return url and self.url + url or self.url

    def inquiry_field(self):
        kini = datetime.now()
        date_settlement = kini.strftime("%m%d")
        nop = self.id_pel[:18]
        tahun = self.id_pel[-4:]

        return \
            {
                "noRef": get_random_number(6),
                "dateSettlement": date_settlement,
                "merchantType": "6014",
                "accountCurrency": "360",
                "terminalId": "02W001",
                "terminalName": "Mobile POS Tangsel",
                "terminalLoc": "Tangerang Selatan",
                "nop": nop,
                "tahunPajak": tahun,

            }

    def inquiry_error(self, resp):
        code = int(resp["responseCode"])
        message = resp["responseDesc"]
        return dict(code=code, message=message)

    def response_field(self):
        resp = self.response
        if resp["responseCode"] == "00":
            pokok = int(resp["tagihan"] or '0')
            denda = int(resp["denda"] or '0')
            disc_biller = int(resp["diskon"] or '0')
            sub_total = pokok + denda - disc_biller

            result = self.get_price(sub_total)
            admin = int(self.vendor_produk.produk.harga)
            # todo: cek kembali harga apakah wajar atau tidak
            #  adm_biller = int(resp["diskon"] or '0')
            #  jika harga admin biller > dari admin
            #  if self.amt_buy < sub_total+adm_biller:
            #     raise
            #  if admin < adm_biller:
            #     admin = adm_biller

            rincian = dict(
                pokok=pokok,
                denda=denda,
                discount=disc_biller,
                subtotal=sub_total,
                admin=admin,
                total=sub_total+admin,
                # code=resp["responseCode"],
                # message=resp["responseDesc"],
                nama=resp["nama"],
                alamat=resp["lokasi"],
                kelurahaan=resp["kelurahaan"],
                kecamatan=resp["kecamatan"],
                provinsi=resp["provinsi"],
                luas_bumi=int(resp["luasTanah"]),
                luas_bng=int(resp["luasBangunan"]),
                jatuh_tempo=resp["tanggalJatuhTempo"],
            )
            result.update(dict(rincian=rincian))
            return result

        else:
            return self.inquiry_error(resp)

    def _inquiry(self):
        if not self.v_produk_kd or not self.id_pel:
            return self.set_response(message='Parameter tidak lengkap')

        self.request = self.inquiry_field()
        log.info("Inquiry Request: url: {} params {}".format(self.inq_url, self.request))
        self.save_log("inquiry")
        params = json.dumps(self.request)
        log.info(params)
        try:
            resp = requests.post(self.inq_url, data=params,
                                 verify=False,
                                 headers=self.get_headers(),
                                 timeout=20)
        except:
            log.info("Biller Error")
            return

        if not resp:
            log.info("No Response From Biller")
            return

        try:
            result = json.loads(resp.text)
        except:
            result = resp.text

        self.response = result
        log.info("Inquiry Response: %s" % self.response)
        return resp

    def inquiry(self):
        resp = self._inquiry()
        if resp is None:
            return self.set_failed(typ="inquiry")

        if resp.status_code == 200:
            parsd = self.response_field()
            return self.set_success(parsd, typ="inquiry")
        else:
            return self.set_failed(typ="inquiry")

    def payment(self):
        resp = self._inquiry()
        if resp is None:
            return self.set_failed()

        if self.response["responseCode"] != "00":
            return self.inquiry_error(self.response)

        params = json.dumps(self.response)
        log.info("Payment url: {} params: {}".format(self.pay_url, params))
        try:
            resp = requests.post(self.pay_url, data=params, verify=False,
                                 headers=self.get_headers(), timeout=15)
        except:
            resp = None

        if resp is None:
            self.status = 0
            return self.set_pending()
        try:
            result = json.loads(resp.text)
            self.response = result
            log.info("Payment Response: %s" % self.response)
        except:
            result = resp.text
            self.response = result
            log.info("Payment Response: %s" % self.response)
            self.status = 0
            return self.set_pending()

        if resp.status_code == 200:
            self.status = 1  # sukses
            parsd = self.response_field()

            self.serial_number = 'ntb' in result and result["ntb"].strip() \
                                 or self.serial_number
            parsd["rincian"].update(dict(
                ntb=self.serial_number,
                ntp='ntp' in result and result["ntp"].strip() or ''))
            return self.set_success(parsd)

        else:
            self.status = 0
            return self.set_pending()

    def advice(self):
        raise JsonRpcError(message="Not Implemented")
        # if not self.v_produk_kd or not self.id_pel or not self.invoice_det:
        #     return dict(code=9999,
        #                 message='Parameter tidak lengkap')
        #
        # if self.kategori == 'e-payment':
        #     order_id = self.invoice_det.vend_inv_no
        #     url = self.get_url('/order/{order_id}'.format(order_id=order_id))
        #     params = None
        #     self.request = url
        # else:
        #     params = dict(
        #         data=dict(
        #             denom=self.v_produk_kd,
        #             number=self.id_pel
        #         )
        #     )
        #     self.request = params
        #     url = self.get_url('/prepaid/purchase-get')
        #
        # self.save_log("advice")
        # try:
        #     resp = requests.get(url, params=params, verify=False,
        #                         headers=self.get_headers(), timeout=15)
        # except:
        #     return self.set_response()
        #
        # try:
        #     result = json.loads(resp.text)
        # except:
        #     result = resp.text
        #
        # self.response = result
        # if resp.ok:
        #     self.status = 1  # sukses
        #     data = "data" in result and result["data"] or None
        #     parsd = self.pars_data(data)
        #
        # elif resp.status_code == 400:
        #     self.status = -3
        #     parsd = dict(code=resp.status_code,
        #                  message=resp.text)
        # else:
        #     self.status = -4
        #     parsd = dict(code=500,
        #                  message="Other Error")
        #
        # self.save_log('advice')
        # return parsd