ofxtools 1.0.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (99) hide show
  1. docs/conf.py +76 -0
  2. ofxtools/Client.py +1003 -0
  3. ofxtools/Parser.py +262 -0
  4. ofxtools/Types.py +821 -0
  5. ofxtools/__init__.py +6 -0
  6. ofxtools/config/__init__.py +133 -0
  7. ofxtools/config/fi.cfg +4496 -0
  8. ofxtools/config/ofxget_example.cfg +64 -0
  9. ofxtools/header.py +350 -0
  10. ofxtools/lib.py +82 -0
  11. ofxtools/models/__init__.py +35 -0
  12. ofxtools/models/bank/__init__.py +10 -0
  13. ofxtools/models/bank/interxfer.py +90 -0
  14. ofxtools/models/bank/mail.py +77 -0
  15. ofxtools/models/bank/msgsets.py +324 -0
  16. ofxtools/models/bank/recur.py +185 -0
  17. ofxtools/models/bank/stmt.py +341 -0
  18. ofxtools/models/bank/stmtend.py +157 -0
  19. ofxtools/models/bank/stpchk.py +84 -0
  20. ofxtools/models/bank/sync.py +167 -0
  21. ofxtools/models/bank/wire.py +112 -0
  22. ofxtools/models/bank/xfer.py +118 -0
  23. ofxtools/models/base.py +586 -0
  24. ofxtools/models/billpay/__init__.py +7 -0
  25. ofxtools/models/billpay/common.py +166 -0
  26. ofxtools/models/billpay/list.py +89 -0
  27. ofxtools/models/billpay/mail.py +61 -0
  28. ofxtools/models/billpay/msgsets.py +97 -0
  29. ofxtools/models/billpay/pmt.py +109 -0
  30. ofxtools/models/billpay/recur.py +100 -0
  31. ofxtools/models/billpay/sync.py +61 -0
  32. ofxtools/models/common.py +81 -0
  33. ofxtools/models/email.py +170 -0
  34. ofxtools/models/i18n.py +1227 -0
  35. ofxtools/models/invest/__init__.py +7 -0
  36. ofxtools/models/invest/acct.py +61 -0
  37. ofxtools/models/invest/mail.py +48 -0
  38. ofxtools/models/invest/msgsets.py +126 -0
  39. ofxtools/models/invest/openorders.py +162 -0
  40. ofxtools/models/invest/positions.py +86 -0
  41. ofxtools/models/invest/securities.py +277 -0
  42. ofxtools/models/invest/stmt.py +316 -0
  43. ofxtools/models/invest/transactions.py +370 -0
  44. ofxtools/models/ofx.py +129 -0
  45. ofxtools/models/profile.py +169 -0
  46. ofxtools/models/signon.py +292 -0
  47. ofxtools/models/signup.py +397 -0
  48. ofxtools/models/tax1099.py +538 -0
  49. ofxtools/models/wrapperbases.py +72 -0
  50. ofxtools/py.typed +0 -0
  51. ofxtools/scripts/__init__.py +0 -0
  52. ofxtools/scripts/ofxget.py +1560 -0
  53. ofxtools/utils.py +406 -0
  54. ofxtools-1.0.0.dist-info/METADATA +136 -0
  55. ofxtools-1.0.0.dist-info/RECORD +99 -0
  56. ofxtools-1.0.0.dist-info/WHEEL +5 -0
  57. ofxtools-1.0.0.dist-info/entry_points.txt +2 -0
  58. ofxtools-1.0.0.dist-info/licenses/LICENSE +14 -0
  59. ofxtools-1.0.0.dist-info/top_level.txt +3 -0
  60. tests/base.py +543 -0
  61. tests/test_client.py +875 -0
  62. tests/test_header.py +634 -0
  63. tests/test_models_bank_interxfer.py +342 -0
  64. tests/test_models_bank_mail.py +233 -0
  65. tests/test_models_bank_recur.py +630 -0
  66. tests/test_models_bank_stmt.py +856 -0
  67. tests/test_models_bank_stmtend.py +392 -0
  68. tests/test_models_bank_stpchk.py +254 -0
  69. tests/test_models_bank_sync.py +1133 -0
  70. tests/test_models_bank_wire.py +322 -0
  71. tests/test_models_bank_xfer.py +461 -0
  72. tests/test_models_base.py +796 -0
  73. tests/test_models_billpay_common.py +488 -0
  74. tests/test_models_billpay_list.py +413 -0
  75. tests/test_models_billpay_mail.py +186 -0
  76. tests/test_models_billpay_pmt.py +401 -0
  77. tests/test_models_billpay_recur.py +229 -0
  78. tests/test_models_billpay_sync.py +270 -0
  79. tests/test_models_common.py +169 -0
  80. tests/test_models_email.py +393 -0
  81. tests/test_models_i18n.py +52 -0
  82. tests/test_models_invest.py +1301 -0
  83. tests/test_models_invest_oo.py +425 -0
  84. tests/test_models_invest_transactions.py +1227 -0
  85. tests/test_models_msgsets.py +1604 -0
  86. tests/test_models_ofx.py +240 -0
  87. tests/test_models_profile.py +297 -0
  88. tests/test_models_securities.py +642 -0
  89. tests/test_models_signon.py +507 -0
  90. tests/test_models_signup.py +1208 -0
  91. tests/test_ofxget.py +1376 -0
  92. tests/test_parser.py +591 -0
  93. tests/test_spec_bank.py +1154 -0
  94. tests/test_spec_billpay.py +1671 -0
  95. tests/test_spec_invest.py +887 -0
  96. tests/test_spec_signon.py +631 -0
  97. tests/test_spec_tax1099.py +638 -0
  98. tests/test_types.py +677 -0
  99. tests/test_utils.py +96 -0
@@ -0,0 +1,425 @@
1
+ """Unit tests for models.invest"""
2
+
3
+ # stdlib imports
4
+ import unittest
5
+ from datetime import datetime
6
+ from decimal import Decimal
7
+ from xml.etree.ElementTree import Element, SubElement
8
+
9
+ # test imports
10
+ import base
11
+ import test_models_bank_stmt as bk_stmt
12
+ import test_models_i18n as i18n
13
+ import test_models_securities as securities
14
+
15
+ from ofxtools.models.bank.stmt import INV401KSOURCES
16
+
17
+ # local imports
18
+ from ofxtools.models.base import Aggregate, UnknownTagWarning
19
+ from ofxtools.models.i18n import CURRENCY_CODES
20
+ from ofxtools.models.invest.acct import INVSUBACCTS
21
+ from ofxtools.models.invest.openorders import (
22
+ INVOOLIST,
23
+ OO,
24
+ OOBUYDEBT,
25
+ OOBUYMF,
26
+ OOBUYOPT,
27
+ OOBUYOTHER,
28
+ OOBUYSTOCK,
29
+ OOSELLDEBT,
30
+ OOSELLMF,
31
+ OOSELLOPT,
32
+ OOSELLOTHER,
33
+ OOSELLSTOCK,
34
+ SWITCHMF,
35
+ UNITTYPES,
36
+ )
37
+ from ofxtools.models.invest.transactions import (
38
+ BUYTYPES,
39
+ OPTBUYTYPES,
40
+ OPTSELLTYPES,
41
+ SELLTYPES,
42
+ )
43
+ from ofxtools.utils import UTC, classproperty
44
+
45
+
46
+ class OoTestCase(unittest.TestCase, base.TestAggregate):
47
+ __test__ = True
48
+
49
+ requiredElements = [
50
+ "FITID",
51
+ "SECID",
52
+ "DTPLACED",
53
+ "UNITS",
54
+ "SUBACCT",
55
+ "DURATION",
56
+ "RESTRICTION",
57
+ ]
58
+ optionalElements = [
59
+ "SRVRTID",
60
+ "MINUNITS",
61
+ "LIMITPRICE",
62
+ "STOPPRICE",
63
+ "MEMO",
64
+ "CURRENCY",
65
+ "INV401KSOURCE",
66
+ ]
67
+ oneOfs = {
68
+ "SUBACCT": INVSUBACCTS,
69
+ "DURATION": ("DAY", "GOODTILCANCEL", "IMMEDIATE"),
70
+ "RESTRICTION": ("ALLORNONE", "MINUNITS", "NONE"),
71
+ "CURSYM": CURRENCY_CODES,
72
+ "INV401KSOURCE": INV401KSOURCES,
73
+ }
74
+
75
+ @classproperty
76
+ @classmethod
77
+ def etree(cls):
78
+ root = Element("OO")
79
+ SubElement(root, "FITID").text = "1001"
80
+ SubElement(root, "SRVRTID").text = "2002"
81
+ root.append(securities.SecidTestCase.etree)
82
+ SubElement(root, "DTPLACED").text = "20040701000000.000[+0:UTC]"
83
+ SubElement(root, "UNITS").text = "150"
84
+ SubElement(root, "SUBACCT").text = "CASH"
85
+ SubElement(root, "DURATION").text = "GOODTILCANCEL"
86
+ SubElement(root, "RESTRICTION").text = "ALLORNONE"
87
+ SubElement(root, "MINUNITS").text = "100"
88
+ SubElement(root, "LIMITPRICE").text = "10.50"
89
+ SubElement(root, "STOPPRICE").text = "10.00"
90
+ SubElement(root, "MEMO").text = "Open Order"
91
+ root.append(i18n.CurrencyTestCase.etree)
92
+ SubElement(root, "INV401KSOURCE").text = "PROFITSHARING"
93
+ return root
94
+
95
+ @classproperty
96
+ @classmethod
97
+ def aggregate(cls):
98
+ return OO(
99
+ fitid="1001",
100
+ srvrtid="2002",
101
+ secid=securities.SecidTestCase.aggregate,
102
+ dtplaced=datetime(2004, 7, 1, tzinfo=UTC),
103
+ units=Decimal("150"),
104
+ subacct="CASH",
105
+ duration="GOODTILCANCEL",
106
+ restriction="ALLORNONE",
107
+ minunits=Decimal("100"),
108
+ limitprice=Decimal("10.50"),
109
+ stopprice=Decimal("10.00"),
110
+ memo="Open Order",
111
+ currency=i18n.CurrencyTestCase.aggregate,
112
+ inv401ksource="PROFITSHARING",
113
+ )
114
+
115
+ def testPropertyAliases(cls):
116
+ instance = Aggregate.from_etree(cls.etree)
117
+ cls.assertEqual(instance.uniqueid, instance.secid.uniqueid)
118
+ cls.assertEqual(instance.uniqueidtype, instance.secid.uniqueidtype)
119
+ # cls.assertEqual(instance.heldinacct, instance.invpos.heldinacct)
120
+ # cls.assertEqual(instance.postype, instance.invpos.postype)
121
+ # cls.assertEqual(instance.units, instance.invpos.units)
122
+ # cls.assertEqual(instance.unitprice, instance.invpos.unitprice)
123
+ # cls.assertEqual(instance.mktval, instance.invpos.mktval)
124
+ # cls.assertEqual(instance.dtpriceasof, instance.invpos.dtpriceasof)
125
+ cls.assertEqual(instance.cursym, instance.currency.cursym)
126
+ cls.assertEqual(instance.currate, instance.currency.currate)
127
+
128
+
129
+ class OobuydebtTestCase(unittest.TestCase, base.TestAggregate):
130
+ __test__ = True
131
+
132
+ requiredElements = ["OO", "AUCTION"]
133
+ optionalElements = ["DTAUCTION"]
134
+
135
+ @classproperty
136
+ @classmethod
137
+ def etree(cls):
138
+ root = Element("OOBUYDEBT")
139
+ root.append(OoTestCase.etree)
140
+ SubElement(root, "AUCTION").text = "N"
141
+ SubElement(root, "DTAUCTION").text = "20120109000000.000[+0:UTC]"
142
+ return root
143
+
144
+ @classproperty
145
+ @classmethod
146
+ def aggregate(cls):
147
+ return OOBUYDEBT(
148
+ oo=OoTestCase.aggregate,
149
+ auction=False,
150
+ dtauction=datetime(2012, 1, 9, tzinfo=UTC),
151
+ )
152
+
153
+
154
+ class OobuymfTestCase(unittest.TestCase, base.TestAggregate):
155
+ __test__ = True
156
+
157
+ requiredElements = ["OO", "BUYTYPE", "UNITTYPE"]
158
+ oneOfs = {"BUYTYPE": BUYTYPES, "UNITTYPE": UNITTYPES}
159
+
160
+ @classproperty
161
+ @classmethod
162
+ def etree(cls):
163
+ root = Element("OOBUYMF")
164
+ root.append(OoTestCase.etree)
165
+ SubElement(root, "BUYTYPE").text = "BUY"
166
+ SubElement(root, "UNITTYPE").text = "SHARES"
167
+ return root
168
+
169
+ @classproperty
170
+ @classmethod
171
+ def aggregate(cls):
172
+ return OOBUYMF(oo=OoTestCase.aggregate, buytype="BUY", unittype="SHARES")
173
+
174
+
175
+ class OobuyoptTestCase(unittest.TestCase, base.TestAggregate):
176
+ __test__ = True
177
+
178
+ requiredElements = ["OO", "OPTBUYTYPE"]
179
+ oneOfs = {"OPTBUYTYPE": OPTBUYTYPES}
180
+
181
+ @classproperty
182
+ @classmethod
183
+ def etree(cls):
184
+ root = Element("OOBUYOPT")
185
+ root.append(OoTestCase.etree)
186
+ SubElement(root, "OPTBUYTYPE").text = "BUYTOOPEN"
187
+ return root
188
+
189
+ @classproperty
190
+ @classmethod
191
+ def aggregate(cls):
192
+ return OOBUYOPT(oo=OoTestCase.aggregate, optbuytype="BUYTOOPEN")
193
+
194
+
195
+ class OobuyotherTestCase(unittest.TestCase, base.TestAggregate):
196
+ __test__ = True
197
+
198
+ requiredElements = ["OO", "UNITTYPE"]
199
+ oneOfs = {"UNITTYPE": UNITTYPES}
200
+
201
+ @classproperty
202
+ @classmethod
203
+ def etree(cls):
204
+ root = Element("OOBUYOTHER")
205
+ root.append(OoTestCase.etree)
206
+ SubElement(root, "UNITTYPE").text = "SHARES"
207
+ return root
208
+
209
+ @classproperty
210
+ @classmethod
211
+ def aggregate(cls):
212
+ return OOBUYOTHER(oo=OoTestCase.aggregate, unittype="SHARES")
213
+
214
+
215
+ class OobuystockTestCase(unittest.TestCase, base.TestAggregate):
216
+ __test__ = True
217
+
218
+ requiredElements = ["OO", "BUYTYPE"]
219
+ oneOfs = {"BUYTYPE": BUYTYPES}
220
+
221
+ @classproperty
222
+ @classmethod
223
+ def etree(cls):
224
+ root = Element("OOBUYSTOCK")
225
+ oo = OoTestCase.etree
226
+ root.append(oo)
227
+ SubElement(root, "BUYTYPE").text = "BUYTOCOVER"
228
+ return root
229
+
230
+ @classproperty
231
+ @classmethod
232
+ def aggregate(cls):
233
+ return OOBUYSTOCK(oo=OoTestCase.aggregate, buytype="BUYTOCOVER")
234
+
235
+
236
+ class OoselldebtTestCase(unittest.TestCase, base.TestAggregate):
237
+ __test__ = True
238
+
239
+ requiredElements = ["OO"]
240
+
241
+ @classproperty
242
+ @classmethod
243
+ def etree(cls):
244
+ root = Element("OOSELLDEBT")
245
+ root.append(OoTestCase.etree)
246
+ return root
247
+
248
+ @classproperty
249
+ @classmethod
250
+ def aggregate(cls):
251
+ return OOSELLDEBT(oo=OoTestCase.aggregate)
252
+
253
+
254
+ class OosellmfTestCase(unittest.TestCase, base.TestAggregate):
255
+ __test__ = True
256
+
257
+ requiredElements = ["OO", "SELLTYPE", "UNITTYPE", "SELLALL"]
258
+ oneOfs = {"SELLTYPE": SELLTYPES, "UNITTYPE": UNITTYPES}
259
+
260
+ @classproperty
261
+ @classmethod
262
+ def etree(cls):
263
+ root = Element("OOSELLMF")
264
+ root.append(OoTestCase.etree)
265
+ SubElement(root, "SELLTYPE").text = "SELLSHORT"
266
+ SubElement(root, "UNITTYPE").text = "SHARES"
267
+ SubElement(root, "SELLALL").text = "Y"
268
+ return root
269
+
270
+ @classproperty
271
+ @classmethod
272
+ def aggregate(cls):
273
+ return OOSELLMF(
274
+ oo=OoTestCase.aggregate,
275
+ selltype="SELLSHORT",
276
+ unittype="SHARES",
277
+ sellall=True,
278
+ )
279
+
280
+
281
+ class OoselloptTestCase(unittest.TestCase, base.TestAggregate):
282
+ __test__ = True
283
+
284
+ requiredElements = ["OO", "OPTSELLTYPE"]
285
+ oneOfs = {"OPTSELLTYPE": OPTSELLTYPES}
286
+
287
+ @classproperty
288
+ @classmethod
289
+ def etree(cls):
290
+ root = Element("OOSELLOPT")
291
+ root.append(OoTestCase.etree)
292
+ SubElement(root, "OPTSELLTYPE").text = "SELLTOCLOSE"
293
+ return root
294
+
295
+ @classproperty
296
+ @classmethod
297
+ def aggregate(cls):
298
+ return OOSELLOPT(oo=OoTestCase.aggregate, optselltype="SELLTOCLOSE")
299
+
300
+
301
+ class OosellotherTestCase(unittest.TestCase, base.TestAggregate):
302
+ __test__ = True
303
+
304
+ requiredElements = ["OO", "UNITTYPE"]
305
+ oneOfs = {"UNITTYPE": UNITTYPES}
306
+
307
+ @classproperty
308
+ @classmethod
309
+ def etree(cls):
310
+ root = Element("OOSELLOTHER")
311
+ root.append(OoTestCase.etree)
312
+ SubElement(root, "UNITTYPE").text = "SHARES"
313
+ return root
314
+
315
+ @classproperty
316
+ @classmethod
317
+ def aggregate(cls):
318
+ return OOSELLOTHER(oo=OoTestCase.aggregate, unittype="SHARES")
319
+
320
+
321
+ class OosellstockTestCase(unittest.TestCase, base.TestAggregate):
322
+ __test__ = True
323
+
324
+ requiredElements = ["OO", "SELLTYPE"]
325
+ oneOfs = {"SELLTYPE": SELLTYPES}
326
+
327
+ @classproperty
328
+ @classmethod
329
+ def etree(cls):
330
+ root = Element("OOSELLSTOCK")
331
+ root.append(OoTestCase.etree)
332
+ SubElement(root, "SELLTYPE").text = "SELLSHORT"
333
+ return root
334
+
335
+ @classproperty
336
+ @classmethod
337
+ def aggregate(cls):
338
+ return OOSELLSTOCK(oo=OoTestCase.aggregate, selltype="SELLSHORT")
339
+
340
+
341
+ class SwitchmfTestCase(unittest.TestCase, base.TestAggregate):
342
+ __test__ = True
343
+
344
+ requiredElements = ["OO", "SECID", "UNITTYPE", "SWITCHALL"]
345
+ oneOfs = {"UNITTYPE": UNITTYPES}
346
+
347
+ @classproperty
348
+ @classmethod
349
+ def etree(cls):
350
+ root = Element("SWITCHMF")
351
+ root.append(OoTestCase.etree)
352
+ root.append(securities.SecidTestCase.etree)
353
+ SubElement(root, "UNITTYPE").text = "SHARES"
354
+ SubElement(root, "SWITCHALL").text = "Y"
355
+ return root
356
+
357
+ @classproperty
358
+ @classmethod
359
+ def aggregate(cls):
360
+ return SWITCHMF(
361
+ oo=OoTestCase.aggregate,
362
+ secid=securities.SecidTestCase.aggregate,
363
+ unittype="SHARES",
364
+ switchall=True,
365
+ )
366
+
367
+
368
+ class InvoolistTestCase(unittest.TestCase, base.TestAggregate):
369
+ __test__ = True
370
+
371
+ @classproperty
372
+ @classmethod
373
+ def etree(cls):
374
+ root = Element("INVOOLIST")
375
+ for oo in (
376
+ "Oobuydebt",
377
+ "Oobuymf",
378
+ "Oobuyopt",
379
+ "Oobuyother",
380
+ "Oobuystock",
381
+ "Ooselldebt",
382
+ "Oosellmf",
383
+ "Oosellopt",
384
+ "Oosellother",
385
+ "Oosellstock",
386
+ "Switchmf",
387
+ ):
388
+ testCase = f"{oo}TestCase"
389
+ elem = globals()[testCase].etree
390
+ root.append(elem)
391
+ return root
392
+
393
+ def testListAggregates(self):
394
+ # INVOOLIST may only contain
395
+ # ['OOBUYDEBT', 'OOBUYMF', 'OOBUYOPT', 'OOBUYOTHER',
396
+ # 'OOBUYSTOCK', 'OOSELLDEBT', 'OOSELLMF', 'OOSELLOPT',
397
+ # 'OOSELLOTHER', 'OOSELLSTOCK', 'SWITCHMF', ]
398
+ listaggregates = INVOOLIST.listaggregates
399
+ self.assertEqual(len(listaggregates), 11)
400
+ root = self.etree
401
+ root.append(bk_stmt.StmttrnTestCase.etree)
402
+
403
+ with self.assertWarns(UnknownTagWarning):
404
+ Aggregate.from_etree(root)
405
+
406
+ @classproperty
407
+ @classmethod
408
+ def aggregate(cls):
409
+ return INVOOLIST(
410
+ OobuydebtTestCase.aggregate,
411
+ OobuymfTestCase.aggregate,
412
+ OobuyoptTestCase.aggregate,
413
+ OobuyotherTestCase.aggregate,
414
+ OobuystockTestCase.aggregate,
415
+ OoselldebtTestCase.aggregate,
416
+ OosellmfTestCase.aggregate,
417
+ OoselloptTestCase.aggregate,
418
+ OosellotherTestCase.aggregate,
419
+ OosellstockTestCase.aggregate,
420
+ SwitchmfTestCase.aggregate,
421
+ )
422
+
423
+
424
+ if __name__ == "__main__":
425
+ unittest.main()