__init__.py 3.14 KB
from argparse import ArgumentParser
from ISO8583.ISOErrors import (
    BitNotSet,
    InvalidIso8583,
    )
from sqlalchemy import func
from opensipkd.waktu import create_datetime
from opensipkd.iso8583.bjb.models import Log as BaseLog
from ..models import Common
from ..log_models import LogFile
from ..common import (
    BaseApp,
    InvalidSource,
    )


def get_parser():
    pars = ArgumentParser()
    pars.add_argument('conf')
    pars.add_argument('--update-from-id', type=int)
    return pars


def get_option(argv):
    pars = get_parser()
    return pars.parse_args(argv)


class Log(BaseLog, Common):
    pass


class LogApp(BaseApp):
    report_orm = Log  # Override
    iso8583_class = None  # Override, please
    bit3_payment_code = None  # Override, please

    def get_session_for_save(self):  # Override
        return self.rpt_session

    def prepare_query_filter(self):  # Override
        if 'id_awal' in self.conf:
            self.id_awal = self.conf['id_awal']
        else:
            self.last = self.get_last_id(self.conf_name)
            self.id_awal = self.last.as_int() + 1
        self.id_akhir = self.conf.get('id_akhir')

    def get_filter_query(self, q):
        q = q.filter(LogFile.id >= self.id_awal)
        if self.id_akhir:
            return q.filter(LogFile.id <= self.id_akhir)
        return q

    def get_count(self):  # Override
        q = self.rpt_session.query(func.count())
        q = self.get_filter_query(q)
        return q.scalar()

    def get_payment_query(self):  # Override
        q = self.rpt_session.query(LogFile)
        q = self.get_filter_query(q)
        return q.order_by(LogFile.id)

    def get_prefix_log(self):  # Override
        return f'ID {self.log_id}'

    def parse(self, line):  # Override, please
        pass

    def create_data(self, log_file):  # Override
        self.log_id = log_file.id
        d = self.parse(log_file.line)
        waktu = create_datetime(
            int(d['year']), int(d['month']), int(d['day']), int(d['hour']),
            int(d['minute']), int(d['second']), int(int(d['milisecond'])/1000))
        print([d['raw']])
        iso = self.iso8583_class()
        try:
            iso.setIsoContent(d['raw'].encode('utf-8'))
        except InvalidIso8583 as e:
            raise InvalidSource(f'ID {log_file.id} tidak dipahami: {str(e)}')
        except ValueError as e:
            raise InvalidSource(f'ID {log_file.id} tidak dipahami: {str(e)}')
        try:
            if iso.getBit(3) != self.bit3_payment_code:
                raise InvalidSource(f'ID {log_file.id} bukan payment')
        except BitNotSet:
            raise InvalidSource(f'ID {log_file.id} bit 3 tidak ada')
        # Meski key pada dictionary bertipe integer namun Postgres menyimpannya
        # bertipe string. Jadi string-kan dari sekarang agar tidak selalu mode
        # UPDATE saat opsi --update-from-id
        vals = iso.get_values()
        bits = dict()
        for bit, val in vals.items():
            bits[str(bit)] = val
        return dict(
                id=log_file.id, mti=iso.getMTI(), created=waktu,
                bits=bits)

    def get_last_time(self):  # Override
        return str(self.log_id)