tariochbctools 0.35__py2.py3-none-any.whl → 0.37__py2.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.
@@ -1,16 +1,25 @@
1
1
  from datetime import date
2
2
 
3
3
  from beancount.core import amount, prices
4
+ from beancount.core.number import D
4
5
 
5
6
 
6
7
  class PriceLookup:
7
8
  def __init__(self, existing_entries, baseCcy: str):
8
- self.priceMap = prices.build_price_map(existing_entries)
9
+ if existing_entries:
10
+ self.priceMap = prices.build_price_map(existing_entries)
11
+ else:
12
+ self.priceMap = None
9
13
  self.baseCcy = baseCcy
10
14
 
11
15
  def fetchPriceAmount(self, instrument: str, date: date):
12
- price = prices.get_price(self.priceMap, tuple([instrument, self.baseCcy]), date)
13
- return price[1]
16
+ if self.priceMap:
17
+ price = prices.get_price(
18
+ self.priceMap, tuple([instrument, self.baseCcy]), date
19
+ )
20
+ return price[1]
21
+ else:
22
+ return D(1)
14
23
 
15
24
  def fetchPrice(self, instrument: str, date: date):
16
25
  if instrument == self.baseCcy:
File without changes
@@ -0,0 +1,173 @@
1
+ import csv
2
+ from collections.abc import Iterable
3
+ from datetime import date
4
+ from io import StringIO
5
+
6
+ from beancount.core import amount, data
7
+ from beancount.core.number import D
8
+ from beancount.core.position import CostSpec
9
+ from beancount.ingest import importer
10
+ from beancount.ingest.importers.mixins import identifier
11
+ from dateutil.parser import parse
12
+
13
+ from tariochbctools.importers.general.priceLookup import PriceLookup
14
+
15
+
16
+ class Importer(identifier.IdentifyMixin, importer.ImporterProtocol):
17
+ """An importer for Fidelity Netbenefits Activity CSV files."""
18
+
19
+ def __init__(
20
+ self,
21
+ regexps: str | Iterable[str],
22
+ cashAccount: str,
23
+ investmentAccount: str,
24
+ dividendAccount: str,
25
+ taxAccount: str,
26
+ capGainAccount: str,
27
+ symbol: str,
28
+ ignoreTypes: Iterable[str],
29
+ baseCcy: str,
30
+ ):
31
+ identifier.IdentifyMixin.__init__(self, matchers=[("filename", regexps)])
32
+ self.cashAccount = cashAccount
33
+ self.investmentAccount = investmentAccount
34
+ self.dividendAccount = dividendAccount
35
+ self.taxAccount = taxAccount
36
+ self.capGainAccount = capGainAccount
37
+ self.symbol = symbol
38
+ self.ignoreTypes = ignoreTypes
39
+ self.baseCcy = baseCcy
40
+
41
+ def name(self):
42
+ return super().name() + self.cashAccount
43
+
44
+ def file_account(self, file):
45
+ return self.cashAccount
46
+
47
+ def extract(self, file, existing_entries):
48
+ entries = []
49
+
50
+ self.priceLookup = PriceLookup(existing_entries, self.baseCcy)
51
+
52
+ with StringIO(file.contents()) as csvfile:
53
+ reader = csv.DictReader(
54
+ csvfile,
55
+ [
56
+ "Transaction date",
57
+ "Transaction type",
58
+ "Investment name",
59
+ "Shares",
60
+ "Amount",
61
+ ],
62
+ delimiter=",",
63
+ skipinitialspace=True,
64
+ )
65
+ next(reader)
66
+ for row in reader:
67
+ if not row["Transaction type"]:
68
+ break
69
+
70
+ if row["Transaction type"] in self.ignoreTypes:
71
+ continue
72
+
73
+ book_date = parse(row["Transaction date"].strip()).date()
74
+ amt = amount.Amount(D(row["Amount"].replace("$", "")), "USD")
75
+ shares = None
76
+ if row["Shares"] != "-":
77
+ shares = amount.Amount(D(row["Shares"]), self.symbol)
78
+
79
+ metakv = {}
80
+
81
+ if not amt and not shares:
82
+ continue
83
+
84
+ meta = data.new_metadata(file.name, 0, metakv)
85
+ description = row["Transaction type"].strip()
86
+
87
+ if "TAX" in description:
88
+ postings = self.__createDividend(amt, book_date, self.taxAccount)
89
+ elif "DIVIDEND" in description:
90
+ postings = self.__createDividend(
91
+ amt, book_date, self.dividendAccount
92
+ )
93
+ elif "YOU BOUGHT" in description:
94
+ postings = self.__createBuy(amt, shares, book_date)
95
+ elif "YOU SOLD" in description:
96
+ postings = self.__createSell(amt, shares, book_date)
97
+ else:
98
+ postings = [
99
+ data.Posting(self.cashAccount, amt, None, None, None, None),
100
+ ]
101
+
102
+ if shares is not None:
103
+ postings.append(
104
+ data.Posting(
105
+ self.investmentAccount, shares, None, None, None, None
106
+ ),
107
+ )
108
+
109
+ entry = data.Transaction(
110
+ meta,
111
+ book_date,
112
+ "*",
113
+ "",
114
+ description,
115
+ data.EMPTY_SET,
116
+ data.EMPTY_SET,
117
+ postings,
118
+ )
119
+ entries.append(entry)
120
+
121
+ return entries
122
+
123
+ def __createBuy(self, amt: amount, shares: amount, book_date: date):
124
+ price = self.priceLookup.fetchPrice("USD", book_date)
125
+ cost = CostSpec(
126
+ number_per=None,
127
+ number_total=round(-amt.number * price.number, 2),
128
+ currency=self.baseCcy,
129
+ date=None,
130
+ label=None,
131
+ merge=None,
132
+ )
133
+ postings = [
134
+ data.Posting(self.investmentAccount, shares, cost, None, None, None),
135
+ data.Posting(self.cashAccount, amt, None, price, None, None),
136
+ ]
137
+
138
+ return postings
139
+
140
+ def __createSell(self, amt: amount, shares: amount, book_date: date):
141
+ price = self.priceLookup.fetchPrice("USD", book_date)
142
+ cost = CostSpec(
143
+ number_per=None,
144
+ number_total=None,
145
+ currency=None,
146
+ date=None,
147
+ label=None,
148
+ merge=None,
149
+ )
150
+ postings = [
151
+ data.Posting(self.investmentAccount, shares, cost, None, None, None),
152
+ data.Posting(self.cashAccount, amt, None, price, None, None),
153
+ data.Posting(self.capGainAccount, None, None, None, None, None),
154
+ ]
155
+
156
+ return postings
157
+
158
+ def __createDividend(self, amt: amount, book_date: date, incomeAccount: str):
159
+ price = self.priceLookup.fetchPrice("USD", book_date)
160
+ postings = [
161
+ data.Posting(
162
+ self.investmentAccount,
163
+ amount.Amount(D(0), self.symbol),
164
+ None,
165
+ None,
166
+ None,
167
+ None,
168
+ ),
169
+ data.Posting(self.cashAccount, amt, None, price, None, None),
170
+ data.Posting(incomeAccount, None, None, None, None, None),
171
+ ]
172
+
173
+ return postings
@@ -33,7 +33,8 @@ class SwisscardImporter(identifier.IdentifyMixin, importer.ImporterProtocol):
33
33
  book_date = parse(row["Transaction date"].strip(), dayfirst=True).date()
34
34
  amt = amount.Amount(-D(row["Amount"]), row["Currency"])
35
35
  metakv = {
36
- "category": row["Category"],
36
+ "merchant": row["Merchant Category"],
37
+ "category": row["Registered Category"],
37
38
  }
38
39
  meta = data.new_metadata(file.name, 0, metakv)
39
40
  description = row["Description"].strip()
@@ -1,6 +1,7 @@
1
1
  """A plugin that verifies that on each transaction, all the "portfolios" have
2
2
  the same weight.
3
3
  """
4
+
4
5
  import collections
5
6
  from collections import defaultdict
6
7
  from decimal import Decimal
@@ -1,6 +1,7 @@
1
1
  """A plugin that inserts an additional price to the base rate by applying
2
2
  fx rate to a price.
3
3
  """
4
+
4
5
  from beancount.core import amount, data, prices
5
6
 
6
7
  __plugins__ = ["generate"]
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: tariochbctools
3
- Version: 0.35
3
+ Version: 0.37
4
4
  Summary: Importers, plugins and price fetchers for Beancount
5
5
  Home-page: https://github.com/tarioch/beancounttools/
6
6
  Author: Patrick Ruckstuhl
@@ -19,7 +19,7 @@ Classifier: Topic :: Office/Business :: Financial :: Investment
19
19
  Classifier: License :: OSI Approved :: MIT License
20
20
  Description-Content-Type: text/x-rst; charset=UTF-8
21
21
  License-File: LICENSE.txt
22
- Requires-Dist: beancount
22
+ Requires-Dist: beancount <3,>=2
23
23
  Requires-Dist: bitstampclient
24
24
  Requires-Dist: mt-940
25
25
  Requires-Dist: pyyaml
@@ -11,11 +11,13 @@ tariochbctools/importers/cembrastatement/importer.py,sha256=fqfJxcU1SDiyyV3iDvfv
11
11
  tariochbctools/importers/general/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
12
12
  tariochbctools/importers/general/mailAdapterImporter.py,sha256=B6r9ycPY1ZiWFPNnl2-h73OgMZAMaq_QSdURW6gxR3c,1805
13
13
  tariochbctools/importers/general/mt940importer.py,sha256=gLE77YhMaQdHE3nDg344eLh-hSofGKHTW5O_h6kmUdM,2102
14
- tariochbctools/importers/general/priceLookup.py,sha256=k0HikFeQcP83CvCwTT3Clpi640VAAGKohU1PQ-3Vi9w,621
14
+ tariochbctools/importers/general/priceLookup.py,sha256=2nqDcSHC2BMmfSaJtgdmZKNejvTglmAj4oMqOf-SLXg,839
15
15
  tariochbctools/importers/ibkr/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
16
16
  tariochbctools/importers/ibkr/importer.py,sha256=ie8LjnIpok8bWGGItxfin_aBSyqe5DXpGSdg3kcNID0,8616
17
17
  tariochbctools/importers/neon/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
18
18
  tariochbctools/importers/neon/importer.py,sha256=SNG6podG1PI3gABy6eYfv1-mRnPwRjK-j5_GoNz2-Wc,2547
19
+ tariochbctools/importers/netbenefits/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
20
+ tariochbctools/importers/netbenefits/importer.py,sha256=V1C9t9LU09osxBDOz-V8DL4LxhtnuhLRj6WV_idxrTM,5816
19
21
  tariochbctools/importers/nordigen/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
20
22
  tariochbctools/importers/nordigen/importer.py,sha256=pHRs1WyvNmb_zIUsq1O6tcUq2xMDt7AFpIbok4R1B9A,3633
21
23
  tariochbctools/importers/nordigen/nordigen_config.py,sha256=jT4vgEKc35qgXqF8_bRbXLHUrkgsSDKHfhDbEw5OXD4,4903
@@ -29,7 +31,7 @@ tariochbctools/importers/revolut/importer.py,sha256=TUjTnvvnYgc0j4z86KIohoMmw13U
29
31
  tariochbctools/importers/schedule/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
30
32
  tariochbctools/importers/schedule/importer.py,sha256=g1q7NwGzwkj25LknOguf3b7iJ0v4JXET01a8N3cWu2U,1526
31
33
  tariochbctools/importers/swisscard/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
32
- tariochbctools/importers/swisscard/importer.py,sha256=hEmRv3ADr9A8akGMAdZTEriFKLPJTql8LQNkFE0ZyfA,1795
34
+ tariochbctools/importers/swisscard/importer.py,sha256=CTJOJMe_QRPzGPPvkhHe4S0aqzBXbPCrkpcFGqOTrz8,1864
33
35
  tariochbctools/importers/transferwise/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
34
36
  tariochbctools/importers/transferwise/importer.py,sha256=czCUtcfOA9XlsP3HKN8DZ7wTDMTllitJXKdr019GJoI,6089
35
37
  tariochbctools/importers/truelayer/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -41,13 +43,13 @@ tariochbctools/importers/zak/importer.py,sha256=9HyFhsavUHLAlO1Pi3eJ7qlNmPsmKzC0
41
43
  tariochbctools/importers/zkb/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
42
44
  tariochbctools/importers/zkb/importer.py,sha256=yrUck3DL2uyuliw0OTBGqBLYl8WBHxgTNnmaG_vA68o,1421
43
45
  tariochbctools/plugins/__init__.py,sha256=DSZtoTVosmExbFmMlHVrZAxKewEILDZlGh_7-uWcc_w,26
44
- tariochbctools/plugins/check_portfolio_sum.py,sha256=bIAZRq7u0Up61siQVvfrBj8-ug7qKtd1IA85aOeTUQM,2339
45
- tariochbctools/plugins/generate_base_ccy_prices.py,sha256=CpT7A3UPZMHU6z-__uEueAMvzJcDO3LKyVEiYdyl1oI,1235
46
+ tariochbctools/plugins/check_portfolio_sum.py,sha256=naJ2j6BFpQhJhT2c-gfjyIdcYe0l_ZzpdlqgwrsIv2g,2340
47
+ tariochbctools/plugins/generate_base_ccy_prices.py,sha256=Phw314qox3jpNgC5-GcnmyYcLkMkrd8xsWS-wYwdj6o,1236
46
48
  tariochbctools/plugins/prices/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
47
49
  tariochbctools/plugins/prices/ibkr.py,sha256=9OwaZvI55bCj7H80K2iLZVsGLpuCyaoCnyuTS9e1_-c,1294
48
- tariochbctools-0.35.dist-info/LICENSE.txt,sha256=VR2hkz3p9Sw4hSXc7S5iZTOXGeV4h-i8AO_q0zEmtkE,1074
49
- tariochbctools-0.35.dist-info/METADATA,sha256=TcLqHPm29SiSYfIGP72tRGKa2Dha1MGDOOHtVdrA1J0,2103
50
- tariochbctools-0.35.dist-info/WHEEL,sha256=DZajD4pwLWue70CAfc7YaxT1wLUciNBvN_TTcvXpltE,110
51
- tariochbctools-0.35.dist-info/entry_points.txt,sha256=9xrCCY1wx2zCIsQUOWZelLHDmHw9Oc-ZBAKUIY9lKTA,88
52
- tariochbctools-0.35.dist-info/top_level.txt,sha256=CiA_NepCI6zDNsaORA55zmpuJFSnTvLESraIL13xiOQ,15
53
- tariochbctools-0.35.dist-info/RECORD,,
50
+ tariochbctools-0.37.dist-info/LICENSE.txt,sha256=VR2hkz3p9Sw4hSXc7S5iZTOXGeV4h-i8AO_q0zEmtkE,1074
51
+ tariochbctools-0.37.dist-info/METADATA,sha256=m2PiA0wx0xM-qtsTiJVZVtvk4G8fQCcc2l2eqaTeKUE,2110
52
+ tariochbctools-0.37.dist-info/WHEEL,sha256=0XQbNV6JE5ziJsWjIU8TRRv0N6SohNonLWgP86g5fiI,109
53
+ tariochbctools-0.37.dist-info/entry_points.txt,sha256=9xrCCY1wx2zCIsQUOWZelLHDmHw9Oc-ZBAKUIY9lKTA,88
54
+ tariochbctools-0.37.dist-info/top_level.txt,sha256=CiA_NepCI6zDNsaORA55zmpuJFSnTvLESraIL13xiOQ,15
55
+ tariochbctools-0.37.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: bdist_wheel (0.43.0)
2
+ Generator: setuptools (70.2.0)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py2-none-any
5
5
  Tag: py3-none-any