class SVCCHG(Aggregate): """OFX section 8.6.1.2""" bankacctfrom = SubAggregate(BANKACCTFROM) ccacctfrom = SubAggregate(CCACCTFROM) invacctfrom = SubAggregate(INVACCTFROM) bankacctto = SubAggregate(BANKACCTTO) ccacctto = SubAggregate(CCACCTTO) invacctto = SubAggregate(INVACCTTO) requiredMutexes = [ ["bankacctfrom", "ccacctfrom", "invacctfrom"], ["bankacctto", "ccacctto", "invacctto"], ]
class STOCKINFO(Aggregate): """OFX Section 13.8.5.6""" secinfo = SubAggregate(SECINFO, required=True) stocktype = OneOf("COMMON", "PREFERRED", "CONVERTIBLE", "OTHER") yld = Decimal() dtyieldasof = DateTime() typedesc = String(32) assetclass = OneOf(*ASSETCLASSES) fiassetclass = String(32) @staticmethod def groom(elem): """ Rename all Elements tagged YIELD (reserved Python keyword) to YLD """ # Keep input free of side effects elem = deepcopy(elem) yld = elem.find("./YIELD") if yld is not None: logger.debug("Renaming <YIELD> to <YLD>") yld.tag = "YLD" return super(STOCKINFO, STOCKINFO).groom(elem) @staticmethod def ungroom(elem): """ Rename YLD back to YIELD """ # Keep input free of side effects elem = deepcopy(elem) yld = elem.find("./YLD") if yld is not None: logger.debug("Renaming <YLD> to <YIELD>") yld.tag = "YIELD" return super(STOCKINFO, STOCKINFO).ungroom(elem)
class MSGSETCORE(ElementList): """ OFX section 7.2.1 """ ver = Integer(required=True) url = String(255, required=True) ofxsec = OneOf("NONE", "TYPE1", required=True) transpsec = Bool(required=True) signonrealm = String(32, required=True) language = ListElement(OneOf(*LANG_CODES)) syncmode = OneOf("FULL", "LITE", required=True) refreshsupt = Bool() respfileer = Bool(required=True) spname = String(32) ofxextension = SubAggregate(OFXEXTENSION) @classmethod def validate_args(cls, *args, **kwargs): if len(args) == 0: msg = "{} must contain at least one item" raise ValueError(msg.format(cls.__name__)) super().validate_args(*args, **kwargs)
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)
class BILLPAYMSGSETV1(ElementList): """ 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) procdaysoff = ListElement(OneOf(*DAYS)) 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 CONTRIBSECURITY(Aggregate): """ OFX section 13.9.3 """ secid = SubAggregate(SECID, required=True) pretaxcontribpct = Decimal() pretaxcontribamt = Decimal() aftertaxcontribpct = Decimal() aftertaxcontribamt = Decimal() matchcontribpct = Decimal() matchcontribamt = Decimal() profitsharingcontribpct = Decimal() profitsharingcontribamt = Decimal() rollovercontribpct = Decimal() rollovercontribamt = Decimal() othervestpct = Decimal() othervestamt = Decimal() othernonvestpct = Decimal() othernonvestamt = Decimal() @classmethod def validate_args(cls, *args, **kwargs): """ Specify either <xxxPCT> or <xxxAMT>. The new contributions to each security are either all specified by a percentage of contributions or by a fixed dollar amount, but not both. At least one source must be provided. """ if not all_equal(key[-3:] for key in kwargs if key != "secid"): msg = "{}: mixed *PCT and *AMT are invalid" raise ValueError(msg.format(cls.__name__)) if len(kwargs) < 2: msg = "{}: at least one source must be provided" raise ValueError(msg.format(cls.__name__)) super().validate_args(*args, **kwargs)
class MFACHALLENGETRNRS(TrnRs): """ OFX Section 2.5.4.2 """ mfachallengers = SubAggregate(MFACHALLENGERS, required=True)
class CHALLENGETRNRS(TrnRs): """ OFX Section 2.5.3.2 """ challengers = SubAggregate(CHALLENGERS, required=True)
class MFACHALLENGETRNRQ(TrnRq): """ OFX Section 2.5.4.1 """ mfachallengerq = SubAggregate(MFACHALLENGERQ, required=True)
class INV401KSUMMARY(Aggregate): """ OFX section 13.9.3 """ yeartodate = SubAggregate(YEARTODATE, required=True) inceptodate = SubAggregate(INCEPTODATE) periodtodate = SubAggregate(PERIODTODATE)
class CHALLENGETRNRQ(TrnRq): """ OFX Section 2.5.3.1 """ challengerq = SubAggregate(CHALLENGERQ, required=True)
class BANKMSGSET(Aggregate): """OFX section 7.3""" bankmsgsetv1 = SubAggregate(BANKMSGSETV1, required=True)
class STMTTRNRQ(TrnRq): """OFX section 11.4.2.1""" stmtrq = SubAggregate(STMTRQ, required=True)
class TAX1099TRNRS(TrnRs): """OFX tax extensions section 2.2.4""" tax1099rs = SubAggregate(TAX1099RS)
class TAX1099MSGSET(Aggregate): """OFX tax extensions section 2.1""" tax1099msgsetv1 = SubAggregate(TAX1099MSGSETV1, required=True)
class PROFMSGSET(Aggregate): """OFX section 7.3""" profmsgsetv1 = SubAggregate(PROFMSGSETV1, required=True)
class TAX1099TRNRQ(TrnRq): """OFX tax extensions section 2.2.3""" tax1099rq = SubAggregate(TAX1099RQ, required=True)
class PROFMSGSETV1(Aggregate): """OFX section 7.3""" msgsetcore = SubAggregate(MSGSETCORE, required=True)
class PROFTRNRQ(TrnRq): """OFX section 7.1.5""" profrq = SubAggregate(PROFRQ, required=True)
class CCSTMTTRNRQ(TrnRq): """OFX section 11.4.3.1""" ccstmtrq = SubAggregate(CCSTMTRQ, required=True)
class SIGNONMSGSETV1(Aggregate): """ OFX section 2.5.5 """ msgsetcore = SubAggregate(MSGSETCORE, required=True)
class INTERXFERMSGSET(Aggregate): """OFX section 11.13.4""" interxfermsgsetv1 = SubAggregate(INTERXFERMSGSETV1, required=True)
class SIGNONMSGSET(Aggregate): """ OFX section 2.5.5 """ signonmsgsetv1 = SubAggregate(SIGNONMSGSETV1, required=True)
class STPCHKTRNRQ(TrnRq): """OFX section 11.6.1.1""" stpchkrq = SubAggregate(STPCHKRQ, required=True)
class CREDITCARDMSGSET(Aggregate): """OFX section 11.13.3""" creditcardmsgsetv1 = SubAggregate(CREDITCARDMSGSETV1, required=True)
class INVSTMTTRNRQ(TrnRq): """ OFX section 13.9.1.1 """ invstmtrq = SubAggregate(INVSTMTRQ, required=True)
class WIREXFERMSGSET(Aggregate): """OFX section 11.13.5""" wirexfermsgsetv1 = SubAggregate(WIREXFERMSGSETV1, required=True)
class PINCHTRNRQ(TrnRq): """ OFX Section 2.5.2.1 """ pinchrq = SubAggregate(PINCHRQ, required=True)
class STPCHKTRNRS(TrnRs): """OFX section 11.6.1.2""" stpchkrs = SubAggregate(STPCHKRS)
class PINCHTRNRS(TrnRs): """ OFX Section 2.5.2.2 """ pinchrs = SubAggregate(PINCHRS, required=True)