Beispiel #1
0
class MSGSETLIST(Aggregate):
    """OFX section 7.2"""

    signonmsgset = ListAggregate(SIGNONMSGSET)
    signupmsgset = ListAggregate(SIGNUPMSGSET)
    bankmsgset = ListAggregate(BANKMSGSET)
    creditcardmsgset = ListAggregate(CREDITCARDMSGSET)
    invstmtmsgset = ListAggregate(INVSTMTMSGSET)
    interxfermsgset = ListAggregate(INTERXFERMSGSET)
    wirexfermsgset = ListAggregate(WIREXFERMSGSET)
    billpaymsgset = ListAggregate(BILLPAYMSGSET)
    emailmsgset = ListAggregate(EMAILMSGSET)
    seclistmsgset = ListAggregate(SECLISTMSGSET)
    #  presdirmsgset = ListAggregate(PRESDIRMSGSET)
    presdirmsgset = Unsupported()
    #  presdlvmsgset = ListAggregate(PRESDLVMSGSET)
    presdlvmsgset = Unsupported()
    profmsgset = ListAggregate(PROFMSGSET)
    tax1099msgset = ListAggregate(TAX1099MSGSET)

    @classmethod
    def validate_args(cls, *args, **kwargs):
        #  "[MSGSETLIST contents] One or more message set aggregates"
        if len(args) == 0:
            msg = "{} must contain at least one item"
            raise ValueError(msg.format(cls.__name__))

        super().validate_args(*args, **kwargs)
Beispiel #2
0
class CREDITCARDMSGSETV1(Aggregate):
    """OFX section 11.13.3"""

    msgsetcore = SubAggregate(MSGSETCORE, required=True)
    closingavail = Bool(required=True)
    pendingavail = Bool()
    imageprof = Unsupported()
Beispiel #3
0
class STMTTRN(Aggregate, Origcurrency):
    """OFX section 11.4.3"""

    trntype = OneOf(*TRNTYPES, required=True)
    dtposted = DateTime(required=True)
    dtuser = DateTime()
    dtavail = DateTime()
    trnamt = Decimal(required=True)
    fitid = String(255, required=True)
    correctfitid = String(255)
    correctaction = OneOf("REPLACE", "DELETE")
    srvrtid = String(10)
    checknum = String(12)
    refnum = String(32)
    sic = Integer()
    payeeid = String(12)
    name = NagString(32)
    payee = SubAggregate(PAYEE)
    extdname = String(100)
    bankacctto = SubAggregate(BANKACCTTO)
    ccacctto = SubAggregate(CCACCTTO)
    memo = String(255)
    imagedata = Unsupported()
    currency = SubAggregate(CURRENCY)
    origcurrency = SubAggregate(ORIGCURRENCY)
    inv401ksource = OneOf(*INV401KSOURCES)

    optionalMutexes = [
        ["name", "payee"],
        ["ccacctto", "bankacctto"],
        ["currency", "origcurrency"],
    ]
Beispiel #4
0
class CCSTMTRS(Aggregate):
    """OFX section 11.4.3.2"""

    curdef = OneOf(*CURRENCY_CODES, required=True)
    ccacctfrom = SubAggregate(CCACCTFROM, required=True)
    banktranlist = SubAggregate(BANKTRANLIST)
    banktranlistp = Unsupported()
    ledgerbal = SubAggregate(LEDGERBAL, required=True)
    availbal = SubAggregate(AVAILBAL)
    cashadvbalamt = Decimal()
    intratepurch = Decimal()
    intratecash = Decimal()
    intratexfer = Decimal()
    rewardinfo = SubAggregate(REWARDINFO)
    ballist = SubAggregate(BALLIST)
    mktginfo = String(360)

    @property
    def account(self):
        return self.ccacctfrom

    @property
    def transactions(self):
        return self.banktranlist

    @property
    def balance(self):
        return self.ledgerbal
Beispiel #5
0
class CCCLOSING(Aggregate):
    """OFX Section 11.5.4.2"""

    fitid = String(255, required=True)
    dtopen = DateTime()
    dtclose = DateTime(required=True)
    dtnext = DateTime()
    balopen = Decimal()
    balclose = Decimal(required=True)
    intytd = Decimal()
    dtpmtdue = DateTime()
    minpmtdue = Decimal()
    pastdueamt = Decimal()
    latefeeamt = Decimal()
    finchg = Decimal()
    intratepurch = Decimal()
    intratecash = Decimal()
    intratexfer = Decimal()
    payandcredit = Decimal()
    purandadv = Decimal()
    debadj = Decimal()
    creditlimit = Decimal()
    cashadvcreditlimit = Decimal()
    dtpoststart = DateTime(required=True)
    dtpostend = DateTime(required=True)
    autopay = Bool()
    lastpmtinfo = SubAggregate(LASTPMTINFO)
    rewardinfo = SubAggregate(REWARDINFO)
    mktginfo = String(360)
    imagedata = Unsupported()
    currency = SubAggregate(CURRENCY)
    origcurrency = SubAggregate(ORIGCURRENCY)
Beispiel #6
0
class BANKMSGSETV1(ElementList):
    """OFX section 11.13.2.1"""

    msgsetcore = SubAggregate(MSGSETCORE, required=True)
    invalidaccttype = ListElement(OneOf(*ACCTTYPES))
    closingavail = Bool(required=True)
    pendingavail = Bool()
    xferprof = SubAggregate(XFERPROF)
    stpchkprof = SubAggregate(STPCHKPROF)
    emailprof = SubAggregate(EMAILPROF, required=True)
    imageprof = Unsupported()
Beispiel #7
0
class INVSTMTMSGSETV1(Aggregate):
    """OFX section 13.7.1.1"""

    msgsetcore = SubAggregate(MSGSETCORE, required=True)
    trandnld = Bool(required=True)
    oodnld = Bool(required=True)
    posdnld = Bool(required=True)
    baldnld = Bool(required=True)
    canemail = Bool(required=True)
    inv401kdnld = Bool()
    closingavail = Bool()
    imageprof = Unsupported()
Beispiel #8
0
class TESTAGGREGATE(Aggregate):
    metadata = String(32, required=True)
    option00 = Bool()
    option01 = Bool()
    option10 = Bool()
    option11 = Bool()
    req00 = Bool()
    req01 = Bool()
    req10 = Bool()
    req11 = Bool()
    testsubaggregate = SubAggregate(TESTSUBAGGREGATE)
    dontuse = Unsupported()

    optionalMutexes = [["option00", "option01"], ["option10", "option11"]]
    requiredMutexes = [["req00", "req01"], ["req10", "req11"]]
Beispiel #9
0
class SONRQ(Aggregate):
    """ OFX section 2.5.1.2 """

    dtclient = DateTime(required=True)
    userid = String(32)
    userpass = String(171)
    userkey = String(64)
    accesstoken = String(1000)
    genuserkey = Bool()
    language = OneOf(*LANG_CODES, required=True)
    fi = SubAggregate(FI)
    sesscookie = String(1000)
    appid = String(5, required=True)
    appver = String(4, required=True)
    appkey = String(10000)
    clientuid = String(36)
    usercred1 = String(171)
    usercred2 = String(171)
    authtoken = String(171)
    accesskey = String(1000)
    mfachallengea = ListAggregate(MFACHALLENGEA)
    ofxextension = Unsupported()

    @classmethod
    def validate_args(cls, *args, **kwargs):
        #  "Either <USERID> and <USERPASS> or <USERKEY>, but not both"
        userid = kwargs.get("userid", None)
        userpass = kwargs.get("userpass", None)
        userkey = kwargs.get("userkey", None)
        try:
            assert (userid and userpass) or userkey
            assert not ((userid or userpass) and userkey)
        except AssertionError:
            msg = ("{} must contain either <USERID> and <USERPASS> "
                   "or <USERKEY>, but not both")
            raise ValueError(msg.format(cls.__name__))

        super().validate_args(*args, **kwargs)
Beispiel #10
0
class SONRS(Aggregate):
    """ OFX section 2.5.1.3 """

    status = SubAggregate(STATUS, required=True)
    dtserver = DateTime(required=True)
    userkey = String(64)
    tskeyexpire = DateTime()
    language = OneOf(*LANG_CODES, required=True)
    dtprofup = DateTime()
    dtacctup = DateTime()
    fi = SubAggregate(FI)
    sesscookie = String(1000)
    accesskey = String(1000)
    ofxextension = Unsupported()

    # Human-friendly attribute aliases
    @property
    def org(self):
        return self.fi.org

    @property
    def fid(self):
        return self.fi.fid
Beispiel #11
0
 def instance(self):
     return Unsupported()
Beispiel #12
0
class OFX(Aggregate):
    """OFX Section 2.4.3"""

    signonmsgsrqv1 = SubAggregate(SIGNONMSGSRQV1)
    signonmsgsrsv1 = SubAggregate(SIGNONMSGSRSV1)
    signupmsgsrqv1 = SubAggregate(SIGNUPMSGSRQV1)
    signupmsgsrsv1 = SubAggregate(SIGNUPMSGSRSV1)
    bankmsgsrqv1 = SubAggregate(BANKMSGSRQV1)
    bankmsgsrsv1 = SubAggregate(BANKMSGSRSV1)
    creditcardmsgsrqv1 = SubAggregate(CREDITCARDMSGSRQV1)
    creditcardmsgsrsv1 = SubAggregate(CREDITCARDMSGSRSV1)
    invstmtmsgsrqv1 = SubAggregate(INVSTMTMSGSRQV1)
    invstmtmsgsrsv1 = SubAggregate(INVSTMTMSGSRSV1)
    interxfermsgsrqv1 = SubAggregate(INTERXFERMSGSRQV1)
    interxfermsgsrsv1 = SubAggregate(INTERXFERMSGSRSV1)
    wirexfermsgsrqv1 = SubAggregate(WIREXFERMSGSRQV1)
    wirexfermsgsrsv1 = SubAggregate(WIREXFERMSGSRSV1)
    billpaymsgsrqv1 = SubAggregate(BILLPAYMSGSRQV1)
    billpaymsgsrsv1 = SubAggregate(BILLPAYMSGSRSV1)
    emailmsgsrqv1 = SubAggregate(EMAILMSGSRQV1)
    emailmsgsrsv1 = SubAggregate(EMAILMSGSRSV1)
    seclistmsgsrqv1 = SubAggregate(SECLISTMSGSRQV1)
    seclistmsgsrsv1 = SubAggregate(SECLISTMSGSRSV1)
    presdirmsgsrqv1 = Unsupported()
    presdirmsgsrsv1 = Unsupported()
    presdlvmsgsrqv1 = Unsupported()
    presdlvmsgsrsv1 = Unsupported()
    profmsgsrqv1 = SubAggregate(PROFMSGSRQV1)
    profmsgsrsv1 = SubAggregate(PROFMSGSRSV1)

    loanmsgsrqv1 = Unsupported()
    loanmsgsrsv1 = Unsupported()
    tax1098msgsrqv1 = Unsupported()
    tax1098msgsrsv1 = Unsupported()
    tax1099msgsrqv1 = SubAggregate(TAX1099MSGSRQV1)
    tax1099msgsrsv1 = SubAggregate(TAX1099MSGSRSV1)
    taxw2msgsrqv1 = Unsupported()
    taxw2msgsrsv1 = Unsupported()
    tax1095msgsrqv1 = Unsupported()
    tax1095msgsrsv1 = Unsupported()

    requiredMutexes = [["signonmsgsrqv1", "signonmsgsrsv1"]]

    @classmethod
    def validate_args(cls, *args, **kwargs):
        # Don't allow mixed *RQ and *RS in the same OFX
        if not all_equal(key[-7:] for key in kwargs):
            msg = f"{cls.__name__}: mixed *MSGRQV1 and *MSGSRSV1 are invalid"
            raise ValueError(msg)

        super().validate_args(*args, **kwargs)

    def __repr__(self):
        s = "<{} ".format(self.__class__.__name__)
        signon = self.signon
        if signon.fi is not None:
            s += f"fid='{signon.fi.fid}' org='{signon.fi.org}' "
        s += f"len(statements)={len(self.statements)} "
        s += f"len(securities)={len(self.securities)}>"
        return s

    # Human-friendly attribute aliases
    @property
    def signon(self):
        if self.signonmsgsrqv1 is not None:
            return self.signonmsgsrqv1.sonrq
        else:
            assert self.signonmsgsrsv1 is not None
            return self.signonmsgsrsv1.sonrs

    @property
    def securities(self):
        seclist = []
        msgs = getattr(self, "seclistmsgsrsv1", None)
        if msgs:
            seclist = msgs.securities
        return seclist

    @property
    def statements(self):
        stmts = []
        for msgs in (
            "bankmsgsrqv1",
            "creditcardmsgsrqv1",
            "invstmtmsgsrqv1",
            "bankmsgsrsv1",
            "creditcardmsgsrsv1",
            "invstmtmsgsrsv1",
        ):
            msg = getattr(self, msgs, None)
            if msg:
                stmts.extend(msg.statements)
        return stmts