__init__.py 12.8 KB
import base64
import json
import re
from time import sleep

import requests
from opensipkd.base import get_settings
from opensipkd.pasar.models import PartnerProduk, H2hArInvoiceDet

from ..vendor import VendorClass

import logging

log = logging.getLogger(__name__)
import urllib3

urllib3.disable_warnings()

timeout = 20
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 = 'test_mid' in settings and settings['test_mid'] or None
        self.key = 'test_key' in settings and settings['test_key'] or None
        self.url = 'test_url' in settings and settings['test_url'] or None
        key = ":".join([self.mid, self.key]).encode()
        self.auth = base64.b64encode(key).decode()

    def get_headers(self):
        return {'Authorization': 'Bearer {key}'.format(key=self.auth)}

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

    def _inquiry(self):
        if self.v_produk_kd[:3] == 'PLN' and self.v_produk_kd != 'PLNPASCA':
            params = dict(
                number=self.id_pel
            )
            url = self.get_url('/prepaid/pln/inquiry')
        else:
            params = dict(
                denom=self.v_produk_kd,
                number=self.id_pel
            )
            url = self.get_url('/postpaid/inquiry')

        self.request = params
        log.info("Inquiry Request: url: %s params %s" % (url, params))
        self.save_log("inquiry")
        try:
            resp = requests.get(url, params=params, verify=False,
                                headers=self.get_headers(), timeout=timeout)
        except:
            return

        if not resp:
            return

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

        self.response = result
        log.info("Inquiry Response: %s" % self.response)
        if resp.status_code == 200:
            self.status = 1  # sukses
            data = "data" in result and result["data"] or None
            return self.pars_data(data)
        else:
            return


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

    def payment(self):
        #Jika kategory bukan e-pulsa Call Inquiry First
        parsd = None
        if self.vendor_produk.produk.kategori.kode != "e-pulsa":
            parsd = self._inquiry()
            if not parsd:
                return self.set_failed()

        params = dict(
            data=dict(
                denom=self.v_produk_kd,
                number=self.id_pel
            )
        )
        self.request = params
        log.info("Payment Request: %s" % self.request)
        self.save_log("payment")
        if not parsd:
            parsd = self.get_price()

        url = self.get_url("/prepaid/purchase")
        try:
            resp = requests.post(url, data=json.dumps(params), verify=False,
                                 headers=self.get_headers(), timeout=timeout)
        except:
            resp = None

        if resp is None:
            return self.set_pending(parsd, typ="payment")
            # todo: dibuat seolah menjadi belum di transaksikan
            # todo: membuat cron untuk melakukan pengecekan transaksi
        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)
            return self.set_pending(parsd, typ="payment")

        # odeo mengembalikan result dalam bentuk status
        # 0200 ok
        # 0400 bad request
        # 0401 auth error
        if resp.status_code == 200 and type(result) is dict:  # 0200
            data = "data" in result and result["data"] or {}
            if not data:
                self.status = 0
                return self.set_pending(parsd, typ="payment")

            self.vend_inv_no = "order_id" in data and data["order_id"] or self.vend_inv_no
            self.amt_buy = "price" in data and data["price"] or self.amt_buy
            if "rc" in data:
                if data["rc"] == "13":  # Gagal
                    return self.set_failed(parsd, typ="payment")
                elif data["rc"] == "67":  # Gagal Double
                    return self.set_failed(parsd, typ="payment")
                elif data["rc"] == "68":  # Pending
                    return self.set_pending(parsd, typ="payment")
            else:
                self.serial_number = 'serial_number' in data and data["serial_numner"] \
                                     or self.serial_number
            return self.set_success(parsd, typ="payment")
        elif resp.status_code == 400:
            data = "data" in result and result["data"] or None
            message = ""
            if data and "errors" in data:
                msg = data["errors"][0]
                pos = msg.find("Sisa saldo")
                message = pos > -1 and msg[:pos] or msg

            pos = message.find("SN: ")
            sn = ""
            if pos > -1:
                sn_spl = message[pos:].split(" ")
                sn = len(sn_spl) > 1 and sn_spl[1] or ""
            parsd["serial_number"] = sn
            return self.set_failed(parsd, message=message, typ="payment")
        elif resp.status_code == 401:
            return self.set_failed(parsd, typ="payment")

    def advice(self):
        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=timeout)
        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)
            return self.set_success(parsd,"payment")
        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

    def pars_data(self, data):
        result = dict()
        if not data:
            return result

        if "subscriber_id" in data and data["subscriber_id"]:
            result['id_pel'] = data["subscriber_id"]
        if "name" in data and data["name"]:
            result['nama'] = data["name"]
        if "subscriber_name" in data and data["subscriber_name"]:
            result['nama'] = data["subscriber_name"]

        rincian = {}
        if "tariff" in data and data["tariff"]:
            rincian['tarif'] = data["tariff"]
        if "number" in data:
            rincian['no_meter'] = data["number"]
        if "power" in data:
            rincian['power'] = data["power"]

        if self.v_produk_kd[:3] == "PLN" and self.v_produk_kd != "PLNPASCA":
            harga = "price" in data and data["price"] or 0
            pokok = harga and int(re.sub("\D","", self.v_produk_kd))*1000 or 0
            admin = int(self.vendor_produk.produk.harga)
            rincian["pokok"] = pokok
            rincian["admin"] = admin
            rincian["denda"] = 0
            rincian["total"] = pokok+admin
            rincian["token"] = "token" in data and data["token"] or ""
        elif self.v_produk_kd == "PLNPASCA":
            if 'tarif' in rincian and rincian['tarif']:
                p = rincian['tarif'].split('/')
                if len(p)>1:
                    rincian["power"] = p[1][:-2]
            if "subscriber_id" in data and data["subscriber_id"]:
                rincian['no_meter'] = data["subscriber_id"]

        i = 1

        inquiries = 'inquiries' in data and data['inquiries'] \
                    or 'inquiry' in data and data['inquiry'] or {}
        if not inquiries:
            result["jml_data"] = 1
            result["rincian"] = rincian
            return result

        inquirieses = type(inquiries) is list and inquiries or [inquiries]
        pokok = denda = admin = 0
        period = meter = ""
        jml_period = 0
        i = 0
        for inquiries in inquirieses:
            if "base_price" in inquiries:
                pokok += int(inquiries["base_price"])
            if "fine" in inquiries:
                denda += int(inquiries["fine"])
            if "admin" in inquiries:
                admin += int(inquiries["admin"])
            if "admin_fee" in inquiries:
                admin += int(inquiries["admin_fee"])

            if "coll_fee" in inquiries:
                if "coll_fee" in rincian:
                    rincian['coll_fee'] += int(inquiries["coll_fee"])
                else:
                    rincian['coll_fee'] = int(inquiries["coll_fee"])

            if "bill_rest" in inquiries:
                if "bill_rest" in rincian:
                    rincian['bill_rest'] += int(inquiries["bill_rest"])
                else:
                    rincian['bill_rest'] = int(inquiries["bill_rest"])

            if "period" in inquiries:
                period += " " + inquiries["period"]

            if "meter_changes" in inquiries:
                if "meter" in rincian:
                    rincian['meter'] += inquiries["meter_changes"]
                else:
                    rincian['meter'] = inquiries["meter_changes"]

            if "usages" in inquiries:
                if "penggunaan" in rincian:
                    rincian['penggunaan'] += inquiries["usages"]
                else:
                    rincian['penggunaan'] = inquiries["usages"]

            if "installment" in inquiries:
                if "installment" in rincian:
                    rincian['installment'] += " " + inquiries["installment"]
                else:
                    rincian['installment'] = inquiries["installment"]
            if "platform" in inquiries:
                if "platform" in rincian:
                    rincian['platform'] += " " + inquiries["platform"]
                else:
                    rincian['platform'] = inquiries["platform"]

            if "due_date" in inquiries:
                if "jth_tempo" in rincian:
                    rincian['jth_tempo'] += " " + inquiries["due_date"]
                else:
                    rincian['jth_tempo'] = inquiries["due_date"]

            if "branch_code" in inquiries:
                rincian['cabang'] = inquiries["branch_code"]

            if "branch_name" in inquiries:
                rincian['nm_cabang'] = inquiries["branch_name"]

            if "month_counts" in inquiries:
                rincian['jml_bulan'] = inquiries["month_counts"]

            if "participant_counts" in inquiries:
                rincian['anggota'] = inquiries["participant_counts"]

            i += 1

        self.amt_buy = data["total"]
        rincian["pokok"] = pokok
        rincian["denda"] = denda
        admin = int(self.vendor_produk.produk.harga * i)
        rincian["admin"] = admin
        rincian["total"] = pokok+denda+admin

        rincian["period"] = period
        if not 'jml_bulan' in rincian:
            rincian["jml_bulan"] = i

        result["subtotal"] = rincian["total"]
        product_id = self.invoice_det.produk.id
        if hasattr(self.invoice_det, "customer_id"):
            partner_id = self.invoice_det.customer_id
        else:
            partner_id = self.invoice_det.h2h_ar_invoice.customer_id
        discount = PartnerProduk.get_discount(partner_id, product_id)
        self.discount = discount * i
        result["discount"] = self.discount
        # self.amt_sell = result["total"]
        result['rincian'] = rincian
        return result

    # def payment(self):
    #     url = "{}/payment".format(self.url)
    #     return HTTPFound(url)