class BANKACCTINFO(Aggregate): """ OFX section 8.5.3 """ bankacctfrom = SubAggregate(BANKACCTFROM) svcstatus = OneOf(*SVCSTATUSES) suptxdl = Unsupported() xfersrc = Unsupported() xferdest = Unsupported()
class MSGSETLIST(Aggregate): """ OFX section 7.2 """ signonmsgset = ListItem(SIGNONMSGSET) signupmsgset = ListItem(SIGNUPMSGSET) profmsgset = ListItem(PROFMSGSET) bankmsgset = ListItem(BANKMSGSET) creditcardmsgset = ListItem(CREDITCARDMSGSET) interxfermsgset = ListItem(INTERXFERMSGSET) wirexfermsgset = ListItem(WIREXFERMSGSET) invstmtmsgset = ListItem(INVSTMTMSGSET) seclistmsgset = ListItem(SECLISTMSGSET) billpaymsgset = ListItem(BILLPAYMSGSET) # presdirmsgset = ListItem(PRESDIRMSGSET) presdirmsgset = Unsupported() # presdlvmsgset = ListItem(PRESDLVMSGSET) presdlvmsgset = Unsupported() tax1099msgset = ListItem(TAX1099MSGSET) # tax1099msgset = Unsupported() @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)
class BANKMSGSETV1(Aggregate): """ OFX section 11.13.2.1 """ msgsetcore = SubAggregate(MSGSETCORE, required=True) invalidaccttype = OneOf(*ACCTTYPES) closingavail = Bool(required=True) pendingavail = Bool() xferprof = Unsupported() stopchkprof = Unsupported() emailprof = SubAggregate(EMAILPROF, required=True) imageprof = Unsupported()
class OFX(Aggregate): """ """ signonmsgsrqv1 = SubAggregate(SIGNONMSGSRQV1) signonmsgsrsv1 = SubAggregate(SIGNONMSGSRSV1) bankmsgsrqv1 = SubAggregate(BANKMSGSRQV1) bankmsgsrsv1 = SubAggregate(BANKMSGSRSV1) creditcardmsgsrqv1 = SubAggregate(CREDITCARDMSGSRQV1) creditcardmsgsrsv1 = SubAggregate(CREDITCARDMSGSRSV1) invstmtmsgsrqv1 = SubAggregate(INVSTMTMSGSRQV1) invstmtmsgsrsv1 = SubAggregate(INVSTMTMSGSRSV1) seclistmsg1rqv1 = SubAggregate(SECLISTMSGSRQV1) seclistmsgsrsv1 = SubAggregate(SECLISTMSGSRSV1) profmsgsrqv1 = SubAggregate(PROFMSGSRQV1) profmsgsrsv1 = SubAggregate(PROFMSGSRSV1) signupmsgsrsv1 = Unsupported() emailmsgsrsv1 = Unsupported() loanmsgsrsv1 = Unsupported() presdirmsgsrsv1 = Unsupported() presdlvmsgsrsv1 = Unsupported() tax1098msgsrsv1 = Unsupported() tax1099msgsrsv1 = Unsupported() taxw2msgsrsv1 = Unsupported() tax1095msgsrsv1 = Unsupported() def __repr__(self): s = "<%s fid='%s' org='%s' dtserver='%s' len(statements)=%d len(securities)=%d>" return s % ( self.__class__.__name__, self.sonrs.fi.fid, self.sonrs.fi.org, str(self.sonrs.dtserver), len(self.statements), len(self.securities), ) # Human-friendly attribute aliases @property def sonrs(self): return self.signonmsgsrsv1.sonrs @property def securities(self): seclist = [] attr = getattr(self, 'seclistmsgsrsv1', None) if attr: seclist = self.seclistmsgsrsv1.seclist return seclist @property def statements(self): """ """ stmts = [] for msgs in ('bankmsgsrsv1', 'creditcardmsgsrsv1', 'invstmtmsgsrsv1'): msg = getattr(self, msgs, None) if msg: stmts.extend(msg.statements) return stmts
class SECLISTTRNRQ(Aggregate): """ OFX section 13.8.2.1 """ trnuid = String(36, required=True) cltcookie = String(32) tan = String(80) ofxextension = Unsupported() seclisttrq = SubAggregate(SECLISTRQ)
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)
class BILLPAYMSGSETV1(Aggregate): """ OFX section 12.11.2 """ msgsetcore = SubAggregate(MSGSETCORE, required=True) dayswith = Integer(3, required=True) dfltdaystopay = Integer(3, required=True) xferdayswith = Integer(3, required=True) xferdfltdaystopay = Integer(3, required=True) # FIXME # Need to define an Aggregate subclass that support multiple repeated # Elements (not just SubAggregates, like List) for PROCDAYSOFF. procdaysoff = Unsupported() procendtm = Time(required=True) modelwnd = Integer(3, required=True) postprocwnd = Integer(3, required=True) stsviamods = Bool(required=True) pmtbyaddr = Bool(required=True) pmtbyxfer = Bool(required=True) pmtbypayeeid = Bool(required=True) canaddpayee = Bool(required=True) hasextdpmt = Bool(required=True) canmodpmts = Bool(required=True) canmodmdls = Bool(required=True) difffirstpmt = Bool(required=True) difflastpmt = Bool(required=True) billpubcontext = Bool()
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 = String(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"), ]
class INVSTMTRS(Aggregate): """ OFX section 13.9.2.1 """ dtasof = DateTime(required=True) curdef = OneOf(*CURRENCY_CODES, required=True) invacctfrom = SubAggregate(INVACCTFROM, required=True) invtranlist = SubAggregate(INVTRANLIST) invposlist = SubAggregate(INVPOSLIST) invbal = SubAggregate(INVBAL) # FIXME - definiing INVOOLIST blows up Aggregate.to_etree() invoolist = SubAggregate(INVOOLIST) # invoolist = Unsupported() mktginfo = String(360) inv401k = Unsupported() inv401kbal = SubAggregate(INV401KBAL) @property def account(self): return self.invacctfrom @property def transactions(self): return self.invtranlist @property def positions(self): return self.invposlist @property def balances(self): return self.invbal
class SONRS(Aggregate): """ OFX section 2.5.1.6 """ 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() @staticmethod def groom(elem): """ Remove proprietary tags e.g. INTU.XXX """ # Keep input free of side effects elem = deepcopy(elem) for child in set(elem): if "." in child.tag: elem.remove(child) return super(SONRS, SONRS).groom(elem) # Human-friendly attribute aliases @property def org(self): return self.fi.org @property def fid(self): return self.fi.fid
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
class CREDITCARDMSGSETV1(Aggregate): """ OFX section 11.13.3 """ msgsetcore = SubAggregate(MSGSETCORE, required=True) closingavail = Bool(required=True) pendingavail = Bool() imageprof = Unsupported()
class INVSTMTTRNRQ(Aggregate): """ OFX section 13.9.1.1 """ trnuid = String(36, required=True) clientcookie = String(32) tan = String(80) ofxextension = Unsupported() invstmtrq = SubAggregate(INVSTMTRQ)
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()
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()
class STPCHKPROF(Aggregate): """ OFX section 11.13.2.3 """ # FIXME # Need to define an Aggregate subclass that support multiple repeated # Elements (not just SubAggregates, like List) for PROCDAYSOFF. procdaysoff = Unsupported() procendtm = Time(required=True) canuserange = Bool(required=True) canusedesc = Bool(required=True) stpchkfee = Decimal(required=True)
class BILLPAYMSGSRQV1(List): """ OFX section 12.11.1.1 """ pmttrnrq = ListItem(PMTTRNRQ) recpmttrnrq = ListItem(RECPMTTRNRQ) # payeetrnrq = ListItem(PAYEETRNRQ) payeetrnrq = Unsupported() pmtinqtrnrq = ListItem(PMTINQTRNRQ) pmtmailtrnrq = ListItem(PMTMAILTRNRQ) pmtsyncrq = ListItem(PMTSYNCRQ) recpmtsyncrq = ListItem(RECPMTSYNCRQ)
class BILLPAYMSGSRSV1(List): """ OFX section 12.11.1.2 """ pmttrnrs = ListItem(PMTTRNRS) recpmttrnrs = ListItem(RECPMTTRNRS) # payeetrnrs = ListItem(PAYEETRNRS) payeetrnrs = Unsupported() pmtinqtrnrs = ListItem(PMTINQTRNRS) pmtmailtrns = ListItem(PMTMAILTRNRS) pmtsyncrs = ListItem(PMTSYNCRS) recpmtsyncrs = ListItem(RECPMTSYNCRS)
class WIREXFERMSGSETV1(Aggregate): """ OFX section 11.13.5 """ msgsetcore = SubAggregate(MSGSETCORE, required=True) # FIXME # Need to define an Aggregate subclass that support multiple repeated # Elements (not just SubAggregates, like List) for PROCDAYSOFF. procdaysoff = Unsupported() procendtm = Time(required=True) cansched = Bool(required=True) domxferfee = Decimal(required=True) intlxferfee = Decimal(required=True)
class SONRQ(Aggregate): """ OFX section 2.5.1.5 """ 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) mfachallengeanswer = Unsupported() ofxextension = Unsupported()
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"]]
class XFERPROF(Aggregate): """ OFX section 11.13.2.2 """ # FIXME # Need to define an Aggregate subclass that support multiple repeated # Elements (not just SubAggregates, like List) for PROCDAYSOFF. procdaysoff = Unsupported() procendtm = Time(required=True) cansched = Bool(required=True) canrecur = Bool(required=True) canmodxfer = Bool(required=True) canmodmdls = Bool(required=True) modelwnd = Integer(3, required=True) dayswith = Integer(3, required=True) dfltdaystopay = Integer(3, required=True)
class SONRS(Aggregate): """ OFX section 2.5.1.6 """ 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
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 = ListItem(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)
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 = Unsupported() billpaymsgsrsv1 = Unsupported() 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 = Unsupported() tax1099msgsrsv1 = Unsupported() 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 = "{}: mixed *MSGRQV1 and *MSGSRSV1 are invalide" raise ValueError(msg.format(cls.__name__)) super().validate_args(*args, **kwargs) # optionalMutexes = [ # ("signupmsgsrqv1", "signupmsgsrsv1"), # ("bankmsgsrqv1", "bankmsgsrsv1"), # ("creditcardmsgsrqv1", "creditcardmsgsrsv1"), # ("invstmtmsgsrqv1", "invstmtmsgsrsv1"), # ("interxfermsgsrqv1", "interxfermsgsrsv1"), # ("wirexfermsgsrqv1", "wirexfermsgsrsv1"), # # ("billpaymsgsrqv1", "billpaymsgsrsv1"), # ("emailmsgsrqv1", "emailmsgsrsv1"), # ("seclistmsgsrqv1", "seclistmsgsrsv1"), # # ("presdirmsgsrqv1", "presdirmsgsrsv1"), # # ("presdlmsgsrqv1", "presdlmsgsrsv1"), # ("profmsgsrqv1", "profmsgsrsv1"), # # ("loanmsgsrqv1", "loanmsgsrsv1"), # # ("tax1098msgsrqv1", "tax1098msgsrsv1"), # # ("tax1099msgsrqv1", "tax1099msgsrsv1"), # # ("taxw2msgsrqv1", "taxw2msgsrsv1"), # # ("tax1095msgsrqv1", "tax1095msgsrsv1"), # ("signupmsgsrqv1", "bankmsgsrsv1"), # ("signupmsgsrqv1", "creditcardmsgsrsv1"), # ("signupmsgsrqv1", "invstmtmsgsrsv1"), # ("signupmsgsrqv1", "interxfermsgsrsv1"), # ("signupmsgsrqv1", "wirexfermsgsrsv1"), # ("signupmsgsrqv1", "billpaymsgsrsv1"), # ("signupmsgsrqv1", "emailmsgsrsv1"), # ("signupmsgsrqv1", "seclistmsgsrsv1"), # ("signupmsgsrqv1", "presdirmsgsrsv1"), # ("signupmsgsrqv1", "presdlmsgsrsv1"), # ("signupmsgsrqv1", "profmsgsrsv1"), # ("signupmsgsrqv1", "loanmsgsrsv1"), # ("signupmsgsrqv1", "tax1098msgsrsv1"), # ("signupmsgsrqv1", "tax1099msgsrsv1"), # ("signupmsgsrqv1", "taxw2msgsrsv1"), # ("signupmsgsrqv1", "tax1095msgsrsv1"), # ("signupmsgsrsv1", "bankmsgsrqv1"), # ("signupmsgsrsv1", "creditcardmsgsrqv1"), # ("signupmsgsrsv1", "invstmtmsgsrqv1"), # ("signupmsgsrsv1", "interxfermsgsrqv1"), # ("signupmsgsrsv1", "wirexfermsgsrqv1"), # ("signupmsgsrsv1", "billpaymsgsrqv1"), # ("signupmsgsrsv1", "emailmsgsrqv1"), # ("signupmsgsrsv1", "seclistmsgsrqv1"), # ("signupmsgsrsv1", "presdirmsgsrqv1"), # ("signupmsgsrsv1", "presdlmsgsrqv1"), # ("signupmsgsrsv1", "profmsgsrqv1"), # ("signupmsgsrsv1", "loanmsgsrqv1"), # ("signupmsgsrsv1", "tax1098msgsrqv1"), # ("signupmsgsrsv1", "tax1099msgsrqv1"), # ("signupmsgsrsv1", "taxw2msgsrqv1"), # ("signupmsgsrsv1", "tax1095msgsrqv1"), # ] def __repr__(self): s = "<{} ".format(self.__class__.__name__) if self.sonrs.fi is not None: s += "fid='{}' org='{}' ".format( self.sonrs.fi.fid or "", self.sonrs.fi.org or "" ) s += "dtserver='{}' len(statements)={} len(securities)={}>".format( str(self.sonrs.dtserver), len(self.statements), len(self.securities) ) return s # Human-friendly attribute aliases @property def sonrs(self): 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 ("bankmsgsrsv1", "creditcardmsgsrsv1", "invstmtmsgsrsv1"): msg = getattr(self, msgs, None) if msg: stmts.extend(msg.statements) return stmts
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
def instance(self): return Unsupported()