def __init__(self, values):
     self.__dict__.update(dict(zip(self.attrnames, values)))
     #self.local_account = self.clean_account(self.local_account)
     #self.remote_account = self.clean_account(self.remote_account)
     self.start_balance = float(self.start_balance)
     self.transferred_amount = float(self.transferred_amount)
     self.execution_date = str2date(self.execution_date, '%d-%m-%Y')
     self.effective_date = str2date(self.effective_date, '%d-%m-%Y')
Ejemplo n.º 2
0
 def __init__(self, values):
     '''
     Initialize own dict with attributes and coerce values to right type
     '''
     self.__dict__.update(dict(zip(self.attrnames, values)))
     #self.local_account = self.clean_account(self.local_account)
     #self.remote_account = self.clean_account(self.remote_account)
     self.start_balance = float(self.start_balance)
     self.transferred_amount = float(self.transferred_amount)
     self.execution_date = str2date(self.execution_date, '%d-%m-%Y')
     self.effective_date = str2date(self.effective_date, '%d-%m-%Y')
Ejemplo n.º 3
0
 def __init__(self, values):
     '''
     Initialize own dict with attributes and coerce values to right type
     '''
     self.__dict__.update(dict(zip(self.attrnames, values)))
     #self.local_account = self.clean_account(self.local_account)
     #self.remote_account = self.clean_account(self.remote_account)
     self.start_balance = float(self.start_balance)
     self.transferred_amount = float(self.transferred_amount)
     self.execution_date = str2date(self.execution_date, '%d-%m-%Y')
     self.effective_date = str2date(self.effective_date, '%d-%m-%Y')
Ejemplo n.º 4
0
 def __init__(self, values, subno):
     '''
     Initialize own dict with attributes and coerce values to right type
     '''
     if len(self.attrnames) != len(values):
         raise ValueError(
             _('Invalid transaction line: expected %d columns, found %d') %
             (len(self.attrnames), len(values)))
     self.__dict__.update(dict(zip(self.attrnames, values)))
     self.start_balance = float(self.start_balance)
     self.transferred_amount = float(self.transferred_amount)
     self.execution_date = str2date(self.execution_date, '%d-%m-%Y')
     self.value_date = str2date(self.value_date, '%d-%m-%Y')
     self.id = str(subno).zfill(4)
Ejemplo n.º 5
0
 def __init__(self, values, subno):
     '''
     Initialize own dict with attributes and coerce values to right type
     '''
     if len(self.attrnames) != len(values):
         raise ValueError, \
                 _('Invalid transaction line: expected %d columns, found %d') \
                 % (len(self.attrnames), len(values))
     self.__dict__.update(dict(zip(self.attrnames, values)))
     #self.local_account = self.clean_account(self.local_account)
     #self.remote_account = self.clean_account(self.remote_account)
     self.start_balance = float(self.start_balance)
     self.transferred_amount = float(self.transferred_amount)
     self.execution_date = str2date(self.execution_date, '%d-%m-%Y')
     self.value_date = str2date(self.value_date, '%d-%m-%Y')
     self.id = str(subno).zfill(4)
 def __init__(self, msg, *args, **kwargs):
     super(statement, self).__init__(*args, **kwargs)
     self.id = msg.statement_id
     self.local_account = msg.local_account
     self.date = str2date(msg.date, '%d-%m-%Y')
     self.start_balance = self.end_balance = msg.start_balance
     self.import_transaction(msg)
Ejemplo n.º 7
0
 def __init__(self, msg, *args, **kwargs):
     '''
     Set decent start values based on first transaction read
     '''
     super(statement, self).__init__(*args, **kwargs)
     self.id = msg.statement_id
     self.local_account = msg.local_account
     self.date = str2date(msg.date, '%d-%m-%Y')
     self.start_balance = self.end_balance = msg.start_balance
     self.import_transaction(msg)
Ejemplo n.º 8
0
 def __init__(self, msg, *args, **kwargs):
     '''
     Set decent start values based on first transaction read
     '''
     super(statement, self).__init__(*args, **kwargs)
     self.id = msg.statement_id
     self.local_account = msg.local_account
     self.date = str2date(msg.date, '%d-%m-%Y')
     self.start_balance = self.end_balance = msg.start_balance
     self.import_transaction(msg)
Ejemplo n.º 9
0
 def __init__(self, values, subno):
     '''
     Initialize own dict with attributes and coerce values to right type
     '''
     if (len(self.attrnames) != len(values) and len(self.attrnames) != len(values)+1) :
         raise ValueError, \
                 _('Invalid transaction line: expected %d columns, found '
                   '%d') % (len(self.attrnames), len(values))
     ''' Strip all values except the blob '''
     for (key, val) in zip(self.attrnames, values):
         self.__dict__[key] = key == 'blob' and val or val.strip()
     # for lack of a standardized locale function to parse amounts
     self.local_account = self.local_account.zfill(10)
     self.balance = float(self.balance.replace(',', '.'))
     self.transferred_amount = float(self.transferred_amount.replace(',', '.'))
     self.execution_date = str2date(self.execution_date, '%d/%m/%Y')
     self.value_date = str2date(self.effective_date, '%d/%m/%Y')
     self.effective_date = str2date(self.effective_date, '%d/%m/%Y')
     self.id = str(subno).zfill(4)
Ejemplo n.º 10
0
 def __init__(self, values, subno):
     '''
     Initialize own dict with attributes and coerce values to right type
     '''
     if len(self.attrnames) != len(values):
         raise ValueError(
             _('Invalid transaction line: expected %d columns, found %d')
             % (len(self.attrnames), len(values)))
     self.__dict__.update(dict(zip(self.attrnames, values)))
     # for lack of a standardized locale function to parse amounts
     self.transferred_amount = float(
         re.sub(',', '.', re.sub('\.', '', self.transferred_amount)))
     if self.debcred == 'Debet':
         self.transferred_amount = -self.transferred_amount
     self.execution_date = str2date(self.date, '%d-%m-%Y')
     self.value_date = str2date(self.date, '%d-%m-%Y')
     self.statement_id = ''
     self.id = str(subno).zfill(4)
     # Normalize basic account numbers
     self.remote_account = self.remote_account.replace('.', '').zfill(10)
     self.local_account = self.local_account.replace('.', '').zfill(10)
Ejemplo n.º 11
0
 def __init__(self, values):
     """
     Initialize own dict with attributes and coerce values to right type
     """
     if len(self.attrnames) != len(values):
         raise ValueError, _("Invalid transaction line: expected %d columns, found %d") % (
             len(self.attrnames),
             len(values),
         )
     self.__dict__.update(dict(zip(self.attrnames, values)))
     self.date = str2date(self.date, "%Y%m%d")
     if self.direction == "A":
         self.transferred_amount = -float(self.transferred_amount)
         # payment batch done via clieop
         if (
             self.transfer_type == "VZ"
             and (not self.remote_account or self.remote_account == "0")
             and (not self.message or re.match("^\s*$", self.message))
             and self.remote_owner.startswith("TOTAAL ")
         ):
             self.transfer_type = "PB"
             self.message = self.remote_owner
             self.remove_owner = False
         # payment batch done via sepa
         if (
             self.transfer_type == "VZ"
             and not self.remote_account
             and not self.remote_owner
             and re.match("^Verzamel Eurobetaling .* TOTAAL \d+ POSTEN\s*$", self.message)
         ):
             self.transfer_type = "PB"
     else:
         self.transferred_amount = float(self.transferred_amount)
     self.local_account = self.local_account.zfill(10)
     if self.transfer_type != "DV":
         self.remote_account = self.remote_account.zfill(10)
     else:
         self.remote_account = False
     self.execution_date = self.value_date = self.date
     self.remote_owner = self.remote_owner.rstrip()
     self.message = self.message.rstrip()
     self.genid()
Ejemplo n.º 12
0
 def __init__(self, values):
     '''
     Initialize own dict with attributes and coerce values to right type
     '''
     if len(self.attrnames) != len(values):
         raise ValueError, \
                 _('Invalid transaction line: expected %d columns, found %d') \
                 % (len(self.attrnames), len(values))
     self.__dict__.update(dict(zip(self.attrnames, values)))
     self.date = str2date(self.date, '%Y%m%d')
     if self.direction == 'A':
         self.transferred_amount = -float(self.transferred_amount)
         #payment batch done via clieop
         if (self.transfer_type == 'VZ'
                 and (not self.remote_account or self.remote_account == '0')
                 and (not self.message or re.match('^\s*$', self.message))
                 and self.remote_owner.startswith('TOTAAL ')):
             self.transfer_type = 'PB'
             self.message = self.remote_owner
             self.remove_owner = False
         #payment batch done via sepa
         if self.transfer_type == 'VZ'\
                 and not self.remote_account\
                 and not self.remote_owner\
                 and re.match(
                     '^Verzamel Eurobetaling .* TOTAAL \d+ POSTEN\s*$',
                     self.message):
             self.transfer_type = 'PB'
     else:
         self.transferred_amount = float(self.transferred_amount)
     self.local_account = self.local_account.zfill(10)
     if self.transfer_type != 'DV':
         self.remote_account = self.remote_account.zfill(10)
     else:
         self.remote_account = False
     self.execution_date = self.value_date = self.date
     self.remote_owner = self.remote_owner.rstrip()
     self.message = self.message.rstrip()
     self.genid()
Ejemplo n.º 13
0
    def parse_message(self):
        """
        Parse the message as sent by the bank. Most messages are composed
        of chunks of 32 characters, but there are exceptions.
        """
        if self.transfer_type == "VZ":
            # Credit bank costs (interest) gets a special treatment.
            if self.remote_owner.startswith("RC AFREK.  REK. "):
                self.transfer_type = "DV"

        if self.transfer_type == "DV":
            # Bank costs.
            # Title of action is in remote_owner, message contains additional
            # info
            self.reference = self.remote_owner.rstrip()
            parts = [self.message[i : i + 32].rstrip() for i in range(0, len(self.message), 32)]
            if len(parts) > 3:
                self.reference = parts[-1]
                self.message = "\n".join(parts[:-1])
            else:
                self.message = "\n".join(parts)
            self.remote_owner = ""

        elif self.transfer_type == "BA":
            # Payment through bank terminal
            # Id of terminal and some owner info is part of message
            if self.execution_date < str2date("20091130", "%Y%m%d"):
                parts = self.remote_owner.split(">")
            else:
                parts = self.remote_owner.split(">\\")
            self.remote_owner = " ".join(parts[0].split()[1:])
            if len(parts) > 1 and len(parts[1]) > 2:
                self.remote_owner_city = parts[1]
            self.message = self.refold_message(self.message)
            self.reference = "%s %s" % (self.remote_owner, " ".join(self.message.split()[2:4]))

        elif self.transfer_type == "IC":
            # Direct debit - remote_owner containts reference, while
            # remote_owner is part of the message, most often as
            # first part of the message.
            # Sometimes this misfires, as with the tax office collecting road
            # taxes, but then a once-only manual correction is sufficient.
            parts = [self.message[i : i + 32].rstrip() for i in range(0, len(self.message), 32)]
            self.reference = self.remote_owner

            if not parts:
                return

            if self.reference.startswith("KN: "):
                self.reference = self.reference[4:]
                if parts[0] == self.reference:
                    parts = parts[1:]
            # The tax administration office seems to be the notorious exception
            # to the rule
            if parts[-1] == "BELASTINGDIENST":
                self.remote_owner = parts[-1].capitalize()
                parts = parts[:-1]
            else:
                self.remote_owner = parts[0]
                parts = parts[1:]
            # Leave the message, to assist in manual correction of misfires
            self.message = "\n".join(parts)

        elif self.transfer_type == "GM":
            # Cash withdrawal from a bank terminal
            # Structured remote_owner message containing bank info and location
            if self.remote_owner.startswith("OPL. CHIPKNIP"):
                # Transferring cash to debit card
                self.remote_account = self.local_account
                self.message = "%s: %s" % (self.remote_owner, self.message)
            else:
                if self.execution_date < str2date("20091130", "%Y%m%d"):
                    parts = self.remote_owner.split(">")
                else:
                    parts = self.remote_owner.split(">\\")
                if len(parts) > 1:
                    self.reference = " ".join([x.rstrip() for x in parts])
                else:
                    self.reference = "ING BANK NV %s" % parts[0].split("  ")[0]
            self.remote_owner = ""

        elif self.transfer_type == "GT":
            # Normal transaction, but remote_owner can contain city, depending
            # on length of total. As there is no clear pattern, leave it as
            # is.
            self.message = self.refold_message(self.message)

        else:
            # Final default: reconstruct message from chopped fixed length
            # message parts.
            self.message = self.refold_message(self.message)
Ejemplo n.º 14
0
    def parse_message(self):
        '''
        Parse structured message parts into appropriate attributes
        '''
        if self.transfer_type == 'ACC':
            # Accept Giro - structured message payment
            # First part of message is redundant information - strip it
            msg = self.message[self.message.index('navraagnr.'):]
            self.message = ' '.join(msg.split())

        elif self.transfer_type == 'BEA':
            # Payment through payment terminal
            # Remote owner is part of message, while remote_owner is set
            # to the intermediate party, which we don't need.
            self.remote_owner = self.message[:23].rstrip()
            self.remote_owner_city = self.message[23:31].rstrip()
            self.message = self.message[31:]

        elif self.transfer_type == 'BTL':
            # International transfers.
            # Remote party is encoded in message, including bank costs
            parts = self.message.split('  ')
            last = False
            for part in parts:
                if part.startswith('bedrag. '):
                    # The ordered transferred amount
                    currency, amount = part.split('. ')[1].split()
                    if self.remote_currency != currency.upper():
                        self.error_message = (
                            'Remote currency in message differs from '
                            'transaction.')
                    else:
                        self.local_amount = float(amount)
                elif part.startswith('koers. '):
                    # The currency rate used
                    self.exchange_rate = float(part.split('. ')[1])
                elif part.startswith('transfer prov. '):
                    # The provision taken by the bank
                    # Note that the amount must be negated to get the right
                    # direction
                    currency, costs = part.split('. ')[1].split()
                    self.provision_costs = -float(costs)
                    self.provision_costs_currency = currency.upper()
                    self.provision_costs_description = 'Transfer costs'
                elif part.startswith('aan. '):
                    # The remote owner
                    self.remote_owner = part.replace('aan. ', '').rstrip()
                    last = True
                elif last:
                    # Last parts are address lines
                    address = part.rstrip()
                    iso, pc, city = postalcode.split(address)
                    if pc and city:
                        self.remote_owner_postalcode = pc
                        self.remote_owner_city = city.strip()
                        self.remote_owner_country_code = iso
                    else:
                        self.remote_owner_address.append(address)

        elif self.transfer_type == 'DIV':
            # A diverse transfer. Message can be anything, but has some
            # structure
            ptr = self.message.find(self.reference)
            if ptr > 0:
                address = self.message[:ptr].rstrip().split('  ')
                length = len(address)
                if length >= 1:
                    self.remote_owner = address[0]
                if length >= 2:
                    self.remote_owner_address.append(address[1])
                if length >= 3:
                    self.remote_owner_city = address[2]
                self.message = self.message[ptr:].rstrip()
            if self.message.find('transactiedatum') >= 0:
                rest = self.message.split('transactiedatum')
                if rest[1].startswith('* '):
                    self.execution_date = str2date(rest[1][2:], '%d-%m-%Y')
                else:
                    self.execution_date = str2date(rest[1][2:], '%d %m %Y')
                self.message = rest[0].rstrip()

        elif self.transfer_type == 'IDB':
            # Payment by iDeal transaction
            # Remote owner can be part of message, while remote_owner can be
            # set to the intermediate party, which we don't need.
            parts = self.message.split('  ')
            # Second part: structured id, date & time
            subparts = parts[1].split()
            datestr = '-'.join(subparts[1:4])
            timestr = ':'.join(subparts[4:])
            parts[1] = ' '.join([subparts[0], datestr, timestr])
            # Only replace reference when redundant
            if self.reference == parts[0]:
                if parts[2]:
                    self.reference = ' '.join([parts[2], datestr, timestr])
                else:
                    self.reference += ' '.join([datestr, timestr])
            # Optional fourth path contains remote owners name
            if len(parts) > 3 and parts[-1].find(self.remote_owner) < 0:
                self.remote_owner = parts[-1].rstrip()
                parts = parts[:-1]
            self.message = ' '.join(parts)
Ejemplo n.º 15
0
def str2date(str):
    dt = convert.str2date(str, '%Y-%m-%d')
    return datetime.date(dt.year, dt.month, dt.day)
Ejemplo n.º 16
0
def str2date(str):
    dt = convert.str2date(str, '%Y-%m-%d')
    return datetime.date(dt.year, dt.month, dt.day)
Ejemplo n.º 17
0
    def parse_message(self):
        '''
        Parse structured message parts into appropriate attributes
        '''
        if self.transfer_type == 'ACC':
            # Accept Giro - structured message payment
            # First part of message is redundant information - strip it
            msg = self.message[self.message.index('navraagnr.'):]
            self.message = ' '.join(msg.split())

        elif self.transfer_type == 'BEA':
            # Payment through payment terminal
            # Remote owner is part of message, while remote_owner is set 
            # to the intermediate party, which we don't need.
            self.remote_owner = self.message[:23].rstrip()
            self.remote_owner_city = self.message[23:31].rstrip()
            self.message = self.message[31:]

        elif self.transfer_type == 'BTL':
            # International transfers.
            # Remote party is encoded in message, including bank costs
            parts = self.message.split('  ')
            last = False
            for part in parts:
                if part.startswith('bedrag. '):
                    # The ordered transferred amount
                    currency, amount = part.split('. ')[1].split()
                    if self.remote_currency != currency.upper():
                        self.error_message = \
                          'Remote currency in message differs from transaction.'
                    else:
                        self.local_amount = float(amount)
                elif part.startswith('koers. '):
                    # The currency rate used
                    self.exchange_rate = float(part.split('. ')[1])
                elif part.startswith('transfer prov. '):
                    # The provision taken by the bank
                    # Note that the amount must be negated to get the right
                    # direction
                    currency, costs = part.split('. ')[1].split()
                    self.provision_costs = -float(costs)
                    self.provision_costs_currency = currency.upper()
                    self.provision_costs_description = 'Transfer costs'
                elif part.startswith('aan. '):
                    # The remote owner
                    self.remote_owner = part.replace('aan. ', '').rstrip()
                    last = True
                elif last:
                    # Last parts are address lines
                    address = part.rstrip()
                    iso, pc, city = postalcode.split(address)
                    if pc and city:
                        self.remote_owner_postalcode = pc
                        self.remote_owner_city = city.strip()
                        self.remote_owner_country_code = iso
                    else:
                        self.remote_owner_address.append(address)

        elif self.transfer_type == 'DIV':
            # A diverse transfer. Message can be anything, but has some
            # structure
            ptr = self.message.find(self.reference)
            if ptr > 0:
                address = self.message[:ptr].rstrip().split('  ')
                length = len(address)
                if length >= 1:
                    self.remote_owner = address[0]
                if length >= 2:
                    self.remote_owner_address.append(address[1])
                if length >= 3:
                    self.remote_owner_city = address[2]
                self.message = self.message[ptr:].rstrip()
            if self.message.find('transactiedatum') >= 0:
                rest = self.message.split('transactiedatum')
                if rest[1].startswith('* '):
                    self.execution_date = str2date(rest[1][2:], '%d-%m-%Y')
                else:
                    self.execution_date = str2date(rest[1][2:], '%d %m %Y')
                self.message = rest[0].rstrip()

        elif self.transfer_type == 'IDB':
            # Payment by iDeal transaction
            # Remote owner can be part of message, while remote_owner can be
            # set to the intermediate party, which we don't need.
            parts = self.message.split('  ')
            # Second part: structured id, date & time
            subparts = parts[1].split()
            datestr = '-'.join(subparts[1:4])
            timestr = ':'.join(subparts[4:])
            parts[1] = ' '.join([subparts[0], datestr, timestr])
            # Only replace reference when redundant
            if self.reference == parts[0]:
                if parts[2]:
                    self.reference = ' '.join([parts[2], datestr, timestr])
                else:
                    self.reference += ' '.join([datestr, timestr])
            # Optional fourth path contains remote owners name
            if len(parts) > 3 and parts[-1].find(self.remote_owner) < 0:
                self.remote_owner = parts[-1].rstrip()
                parts = parts[:-1]
            self.message = ' '.join(parts)
Ejemplo n.º 18
0
    def parse_message(self):
        '''
        Parse the message as sent by the bank. Most messages are composed
        of chunks of 32 characters, but there are exceptions.
        '''
        if self.transfer_type == 'VZ':
            # Credit bank costs (interest) gets a special treatment.
            if self.remote_owner.startswith('RC AFREK.  REK. '):
                self.transfer_type = 'DV'

        if self.transfer_type == 'DV':
            # Bank costs.
            # Title of action is in remote_owner, message contains additional
            # info
            self.reference = self.remote_owner.rstrip()
            parts = [
                self.message[i:i + 32].rstrip()
                for i in range(0, len(self.message), 32)
            ]
            if len(parts) > 3:
                self.reference = parts[-1]
                self.message = '\n'.join(parts[:-1])
            else:
                self.message = '\n'.join(parts)
            self.remote_owner = ''

        elif self.transfer_type == 'BA':
            # Payment through bank terminal
            # Id of terminal and some owner info is part of message
            if self.execution_date < str2date('20091130', '%Y%m%d'):
                parts = self.remote_owner.split('>')
            else:
                parts = self.remote_owner.split('>\\')
            self.remote_owner = ' '.join(parts[0].split()[1:])
            if len(parts) > 1 and len(parts[1]) > 2:
                self.remote_owner_city = parts[1]
            self.message = self.refold_message(self.message)
            self.reference = '%s %s' % (self.remote_owner, ' '.join(
                self.message.split()[2:4]))

        elif self.transfer_type == 'IC':
            # Direct debit - remote_owner containts reference, while
            # remote_owner is part of the message, most often as
            # first part of the message.
            # Sometimes this misfires, as with the tax office collecting road
            # taxes, but then a once-only manual correction is sufficient.
            parts = [
                self.message[i:i + 32].rstrip()
                for i in range(0, len(self.message), 32)
            ]
            self.reference = self.remote_owner

            if not parts:
                return

            if self.reference.startswith('KN: '):
                self.reference = self.reference[4:]
                if parts[0] == self.reference:
                    parts = parts[1:]
            # The tax administration office seems to be the notorious exception
            # to the rule
            if parts[-1] == 'BELASTINGDIENST':
                self.remote_owner = parts[-1].capitalize()
                parts = parts[:-1]
            else:
                self.remote_owner = parts[0]
                parts = parts[1:]
            # Leave the message, to assist in manual correction of misfires
            self.message = '\n'.join(parts)

        elif self.transfer_type == 'GM':
            # Cash withdrawal from a bank terminal
            # Structured remote_owner message containing bank info and location
            if self.remote_owner.startswith('OPL. CHIPKNIP'):
                # Transferring cash to debit card
                self.remote_account = self.local_account
                self.message = '%s: %s' % (self.remote_owner, self.message)
            else:
                if self.execution_date < str2date('20091130', '%Y%m%d'):
                    parts = self.remote_owner.split('>')
                else:
                    parts = self.remote_owner.split('>\\')
                if len(parts) > 1:
                    self.reference = ' '.join([x.rstrip() for x in parts])
                else:
                    self.reference = 'ING BANK NV %s' % parts[0].split('  ')[0]
            self.remote_owner = ''

        elif self.transfer_type == 'GT':
            # Normal transaction, but remote_owner can contain city, depending
            # on length of total. As there is no clear pattern, leave it as
            # is.
            self.message = self.refold_message(self.message)

        else:
            # Final default: reconstruct message from chopped fixed length
            # message parts.
            self.message = self.refold_message(self.message)