Exemple #1
0
    def instantiate(self):
        """ """
        if not hasattr(self, '_root'):
            raise ValueError('Must first call parse() to have data to instantiate')
        # SECLIST - list of description of securities referenced by
        # INVSTMT (investment account statement)
        seclist = self.find('SECLISTMSGSRSV1/SECLIST')
        if seclist is not None:
            self.securities = [
                sec.instantiate()
                for sec in seclist
            ]
            DBSession.add_all(self.securities)
        else:
            self.securities = []

        # TRNRS - transaction response, which is the main section
        # containing account statements
        #
        # N.B. This iteration method doesn't preserve the original
        # ordering of the statements within the OFX response
        self.statements = []
        for stmtClass in (BankStatement, CreditCardStatement, InvestmentStatement):
            tagname = stmtClass._tagName
            for trnrs in self.findall('*/%sTRNRS' % tagname):
                # *STMTTRNRS may have no *STMTRS (in case of error).
                # Don't blow up; skip silently.
                stmtrs = trnrs.find('%sRS' % tagname)
                if stmtrs is not None:
                    stmt = stmtClass(stmtrs)
                    self.statements.append(stmt)
Exemple #2
0
    def instantiate(self, **extra_attrs):
        """
        Create an instance of a SQLAlchemy model class corresponding to
        my OFX tag, with attributes given by my contained OFX elements.

        If an instance that matches the given primary key signature has
        already been given, return that instead of creating a new one.
        """
        self.extra_attributes = extra_attrs
        # SECID needs to instantiate as SECINFO
        if self.tag == 'SECID':
            SubClass = models.SECINFO
        else:
            SubClass = getattr(models, self.tag)
        self._preflatten()
        self.attributes = self._flatten()
        self._postflatten()
        self.attributes.update(self.extra_attributes)
        self.extra_attributes = {}

        try:
            fingerprint = SubClass._fingerprint(**self.attributes)
            instance = DBSession.query(SubClass).filter_by(**fingerprint).one()
        except NoResultFound:
            instance = SubClass(**self.attributes)
            DBSession.add(instance)

        return instance
Exemple #3
0
 def __init__(self, stmtrs):
     """ Initialize with *STMTRS Element """
     self.currency = stmtrs.find('CURDEF').text
     acctfrom = stmtrs.find(self._acctTag)
     self.account = acctfrom.instantiate()
     DBSession.add(self.account)
     self.transactions = []
     self.other_balances =[]
     self._init(stmtrs)
Exemple #4
0
    def _init(self, stmtrs):
        # BANKTRANLIST
        tranlist = stmtrs.find('BANKTRANLIST')
        if tranlist is not None:
            self.transactions = TransactionList(self.account, tranlist)
            DBSession.add_all(self.transactions)

        # LEDGERBAL - mandatory
        ledgerbal = stmtrs.find('LEDGERBAL')
        self.ledgerbal = ledgerbal.instantiate(acctfrom=self.account)
        DBSession.add(self.ledgerbal)

        # AVAILBAL
        availbal = stmtrs.find('AVAILBAL')
        if availbal is not None:
            self.availbal = availbal.instantiate(acctfrom=self.account)
            DBSession.add(self.availbal)
        else:
            self.availbal = None

        ballist = stmtrs.find('BALLIST')
        if ballist:
            self.other_balances = [bal.instantiate() for bal in ballist]
            DBSession.add_all(self.other_balances)

        # Unsupported subaggregates
        for tag in ('MKTGINFO', ):
            child = stmtrs.find(tag)
            if child:
                stmtrs.remove
Exemple #5
0
    def _init(self, invstmtrs):
        dtasof = invstmtrs.find('DTASOF').text
        self.datetime = ofxtools.types.DateTime().convert(dtasof)

        # INVTRANLIST
        tranlist = invstmtrs.find('INVTRANLIST')
        if tranlist is not None:
            self.transactions = TransactionList(self.account, tranlist)
            DBSession.add_all(self.transactions)

        # INVPOSLIST
        poslist = invstmtrs.find('INVPOSLIST')
        if poslist is not None:
            # FIs can list multiple INVPOS lots per security, so we
            # can't just naively instantiate what they give us or we'll
            # violate uniqueness constraints on the PKs.
            # Instead we need to manually tally up the units and instantiate
            # only a single INVPOS lot per security
            positions = {}
            for pos in poslist:
                secid = pos.find('.//SECID')
                uniqueid = secid.find('UNIQUEID')
                uniqueidtype = secid.find('UNIQUEIDTYPE')
                units = pos.find('./INVPOS/UNITS')
                seckey = (uniqueid.text, uniqueidtype.text)
                position = positions.get(seckey, None)
                if position is None:
                    positions[seckey] = (pos, Decimal(units.text))
                else:
                    positions[seckey] = (position[0],
                                         position[1] + Decimal(units.text)
                                        )
            self.positions = [pos.instantiate(
                units=units, acctfrom=self.account,
                dtasof=self.datetime) \
                for pos, units in positions.values()]
            DBSession.add_all(self.positions)
        else:
            self.positions = []

        # INVBAL
        invbal = invstmtrs.find('INVBAL')
        if invbal is not None:
            # First strip off BALLIST & process it
            ballist = invbal.find('BALLIST')
            if ballist is not None:
                invbal.remove(ballist)
                self.other_balances = [
                    bal.instantiate(acctfrom=self.account, dtasof=self.datetime,
                                   ) for bal in ballist
                ]
                DBSession.add_all(self.other_balances)
            # Now we can flatten the rest of INVBAL
            self.balances = invbal.instantiate(
                acctfrom=self.account, dtasof=self.datetime,
            )
            DBSession.add(self.balances)
        else:
            self.balances = []

        # Unsupported subaggregates
        for tag in ('INVOOLIST', 'INV401K', 'INV401KBAL', 'MKTGINFO'):
            child = invstmtrs.find(tag)
            if child is not None:
                invstmtrs.remove