common.py 5.41 KB
import sys
from datetime import (
    datetime,
    date,
    )
from configparser import ConfigParser
from argparse import ArgumentParser


help_tgl_bayar = 'digunakan --payment'
help_amount = 'digunakan --payment dan --reversal'
help_ntb = 'digunakan --payment dan --reversal'
help_stan = 'digunakan --payment dan --reversal'
help_host = 'nama host saat menjadi daemon'


def date_from_str(s):
    d, m, y = s.split('-')
    return date(int(y), int(m), int(d))


def get_option(argv):
    pars = ArgumentParser()
    pars.add_argument('conf')
    pars.add_argument('--invoice-id', required=True)
    pars.add_argument('--payment', action='store_true')
    pars.add_argument('--tgl-bayar', help=help_tgl_bayar)
    pars.add_argument('--reversal', action='store_true')
    pars.add_argument('--amount', help=help_amount)
    pars.add_argument('--ntb', help=help_ntb)
    pars.add_argument('--stan', help=help_stan)
    pars.add_argument('--host', help=help_host)
    return pars.parse_args(argv)


def get_module_object(name):
    module_obj = __import__(name)
    sub_obj = None
    for sub in name.split('.')[1:]:
        if sub_obj:
            sub_obj = getattr(sub_obj, sub)
        else:
            sub_obj = getattr(module_obj, sub)
    return sub_obj


def show_dict(d, margin=2):
    s_margin = ' ' * margin
    keys = list(d.keys())
    keys.sort()
    for key in keys:
        s_key = str(key).rjust(3)
        val = d[key]
        print('{}{}: {}'.format(s_margin, s_key, [val]))


def show_fix_length(f, margin=4):
    s_margin = ' ' * margin
    for key, x, y in f.struct:
        val = f[key]
        print('{}{}: {}'.format(s_margin, key, [val]))


def ack_message(iso):
    if iso.ack_message:
        print(iso.ack_message)


class App:
    def __init__(self, argv=sys.argv):
        self.option = get_option(argv[1:])
        self.invoice_id = self.option.invoice_id
        self.conf = ConfigParser()
        self.conf.read(self.option.conf)
        self.module_conf = dict(self.conf['main'])
        if self.option.host:
            self.module_conf['name'] = self.option.host
        self.invoice_profile = {}

    def set_conf(self, name, func):
        if self.conf.has_option('main', name):
            self.module_conf[name] = func(self.conf.get('main', name))

    def doc_from_iso(self, iso):
        return self.Doc(from_iso=iso, conf=self.module_conf)

    def get_tgl_bayar(self):
        if self.option.tgl_bayar:
            return date_from_str(self.option.tgl_bayar)
        return datetime.now()

    def run(self):
        module_name = self.conf.get('main', 'module')
        module = get_module_object(module_name)
        module.init(self.module_conf)
        self.Doc = module.Doc
        if self.option.reversal:
            self.reversal()
        else:
            inq_response = self.inquiry()
            if inq_response.getBit(39) == '00' and self.option.payment:
                self.payment(inq_response)

    def inquiry(self):
        tgl_bayar = self.get_tgl_bayar()
        inq_request = self.Doc()
        inq_request.set_inquiry_request(tgl_bayar)
        inq_request.set_invoice_id(self.invoice_id)
        self.show('Bank kirim inquiry request', inq_request)
        inq_response = self.doc_from_iso(inq_request)
        inq_response.process()
        ack_message(inq_response)
        self.show('Pemda kirim inquiry response', inq_response)
        return inq_response

    def payment(self, inq_response):
        tgl_bayar = self.get_tgl_bayar()
        if self.option.ntb:
            ntb = self.option.ntb
        else:
            ntb = datetime.now().strftime('%y%m%d%H%M%S')
        if self.option.amount:
            amount = self.option.amount
        else:
            amount = inq_response.get_amount()
        pay_request = self.Doc()
        pay_request.set_payment_request(tgl_bayar)
        pay_request.set_invoice_id(self.invoice_id)
        pay_request.set_amount(amount)
        pay_request.set_ntb(ntb)
        if self.option.stan:
            pay_request.set_stan(self.option.stan)
        self.show('Bank kirim payment request', pay_request)
        pay_response = self.doc_from_iso(pay_request)
        pay_response.process()
        ack_message(pay_response)
        self.show('Pemda kirim payment response', pay_response)
        if pay_response.getBit(39) == '00':
            print('NTP: {}'.format(pay_response.get_ntp()))
        return pay_response

    def reversal(self):
        rev_request = self.Doc()
        rev_request.set_reversal_request()
        rev_request.set_invoice_id(self.invoice_id)
        rev_request.set_ntb(self.option.ntb or '')
        if self.option.stan:
            rev_request.set_stan(self.option.stan)
        if self.option.amount:
            rev_request.set_amount(self.option.amount)
        self.show('Bank kirim reversal request', rev_request)
        rev_response = self.doc_from_iso(rev_request)
        rev_response.process()
        ack_message(rev_response)
        self.show('Pemda kirim reversal response', rev_response)
        return rev_response

    def show(self, label, iso):
        print(label)
        print('  MTI {}'.format(iso.getMTI()))
        show_dict(iso.get_values())
        if iso.is_response():
            for key, value in self.invoice_profile.items():
                try:
                    profile = getattr(iso, value)
                except AttributeError:
                    continue
                print('  Bit {}'.format(key))
                show_fix_length(profile, 4)