Skip to content

Commit 3978913

Browse files
Merge branch 'master' into feat/transactions
2 parents 878dbf8 + 5d8042d commit 3978913

5 files changed

+161
-17
lines changed

.gitignore

+4-1
Original file line numberDiff line numberDiff line change
@@ -141,4 +141,7 @@ cython_debug/
141141
.idea/**
142142

143143
# VSCode
144-
.vscode/**
144+
.vscode/**
145+
146+
# uv
147+
uv.lock

pytr/event.py

+3
Original file line numberDiff line numberDiff line change
@@ -44,8 +44,10 @@ class PPEventType(EventType):
4444
"PAYMENT_INBOUND_APPLE_PAY": PPEventType.DEPOSIT,
4545
"PAYMENT_INBOUND_GOOGLE_PAY": PPEventType.DEPOSIT,
4646
"PAYMENT_INBOUND_SEPA_DIRECT_DEBIT": PPEventType.DEPOSIT,
47+
"PAYMENT_INBOUND_CREDIT_CARD": PPEventType.DEPOSIT,
4748
"card_refund": PPEventType.DEPOSIT,
4849
"card_successful_oct": PPEventType.DEPOSIT,
50+
"card_tr_refund": PPEventType.DEPOSIT,
4951
# Dividends
5052
"CREDIT": PPEventType.DIVIDEND,
5153
"ssp_corporate_action_invoice_cash": PPEventType.DIVIDEND,
@@ -141,6 +143,7 @@ def _parse_type_dependent_params(
141143
taxes = cls._parse_taxes(event_dict)
142144

143145
elif event_type in [PPEventType.DEPOSIT, PPEventType.REMOVAL]:
146+
shares, fees = cls._parse_shares_and_fees(event_dict)
144147
note = cls._parse_card_note(event_dict)
145148

146149
return fees, isin, note, shares, taxes

pytr/portfolio.py

+2-16
Original file line numberDiff line numberDiff line change
@@ -9,14 +9,10 @@ def __init__(self, tr):
99

1010
async def portfolio_loop(self):
1111
recv = 0
12-
# await self.tr.portfolio()
13-
# recv += 1
1412
await self.tr.compact_portfolio()
1513
recv += 1
1614
await self.tr.cash()
1715
recv += 1
18-
# await self.tr.available_cash_for_payout()
19-
# recv += 1
2016

2117
while recv > 0:
2218
subscription_id, subscription, response = await self.tr.recv()
@@ -30,9 +26,6 @@ async def portfolio_loop(self):
3026
elif subscription["type"] == "cash":
3127
recv -= 1
3228
self.cash = response
33-
# elif subscription['type'] == 'availableCashForPayout':
34-
# recv -= 1
35-
# self.payoutCash = response
3629
else:
3730
print(f"unmatched subscription of type '{subscription['type']}':\n{preview(response)}")
3831

@@ -51,8 +44,7 @@ async def portfolio_loop(self):
5144

5245
if subscription["type"] == "instrument":
5346
await self.tr.unsubscribe(subscription_id)
54-
pos = subscriptions[subscription_id]
55-
subscriptions.pop(subscription_id, None)
47+
pos = subscriptions.pop(subscription_id)
5648
pos["name"] = response["shortName"]
5749
pos["exchangeIds"] = response["exchangeIds"]
5850
else:
@@ -73,8 +65,7 @@ async def portfolio_loop(self):
7365

7466
if subscription["type"] == "ticker":
7567
await self.tr.unsubscribe(subscription_id)
76-
pos = subscriptions[subscription_id]
77-
subscriptions.pop(subscription_id, None)
68+
pos = subscriptions.pop(subscription_id)
7869
pos["netValue"] = float(response["last"]["price"]) * float(pos["netSize"])
7970
else:
8071
print(f"unmatched subscription of type '{subscription['type']}':\n{preview(response)}")
@@ -94,18 +85,13 @@ def portfolio_to_csv(self, output_path):
9485
print(f"Wrote {len(csv_lines) + 1} lines to {output_path}")
9586

9687
def overview(self):
97-
# for x in ['netValue', 'unrealisedProfit', 'unrealisedProfitPercent', 'unrealisedCost']:
98-
# print(f'{x:24}: {self.portfolio[x]:>10.2f}')
99-
# print()
100-
10188
print(
10289
"Name ISIN avgCost * quantity = buyCost -> netValue diff %-diff"
10390
)
10491
totalBuyCost = 0.0
10592
totalNetValue = 0.0
10693
positions = self.portfolio["positions"]
10794
for pos in sorted(positions, key=lambda x: x["netSize"], reverse=True):
108-
# pos['netValue'] = 0 # TODO: Update the value from each Stock request
10995
buyCost = float(pos["averageBuyIn"]) * float(pos["netSize"])
11096
diff = float(pos["netValue"]) - buyCost
11197
if buyCost == 0:

tests/sample_credit_card_deposit.json

+141
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,141 @@
1+
{
2+
"id": "5b04b073-c06f-4ab1-bd01-de51b56162dc",
3+
"timestamp": "2022-08-27T05:06:30.471+0000",
4+
"title": "Einzahlung",
5+
"icon": "logos/bank_mastercard/v2",
6+
"badge": null,
7+
"subtitle": null,
8+
"amount": {
9+
"currency": "EUR",
10+
"value": 1000.0,
11+
"fractionDigits": 2
12+
},
13+
"subAmount": null,
14+
"status": "EXECUTED",
15+
"action": {
16+
"type": "timelineDetail",
17+
"payload": "5b04b073-c06f-4ab1-bd01-de51b56162dc"
18+
},
19+
"eventType": "PAYMENT_INBOUND_CREDIT_CARD",
20+
"cashAccountNumber": null,
21+
"hidden": false,
22+
"deleted": false,
23+
"source": "timelineTransaction",
24+
"details": {
25+
"id": "5b04b073-c06f-4ab1-bd01-de51b56162dc",
26+
"sections": [
27+
{
28+
"title": "Du hast 1.000,00 € über Kreditkarte hinzugefügt",
29+
"data": {
30+
"icon": "logos/bank_mastercard/v2",
31+
"subtitleText": null,
32+
"timestamp": "2022-08-27T05:06:30.471+0000",
33+
"status": "executed"
34+
},
35+
"action": null,
36+
"type": "header"
37+
},
38+
{
39+
"title": "Übersicht",
40+
"data": [
41+
{
42+
"title": "Status",
43+
"detail": {
44+
"text": "Completed",
45+
"functionalStyle": "EXECUTED",
46+
"type": "status"
47+
},
48+
"style": "plain"
49+
},
50+
{
51+
"title": "Zahlung",
52+
"detail": {
53+
"text": "·· 7431",
54+
"icon": "logos/bank_mastercard/v2",
55+
"type": "iconWithText"
56+
},
57+
"style": "plain"
58+
}
59+
],
60+
"action": null,
61+
"type": "table"
62+
},
63+
{
64+
"title": "Transaktion",
65+
"data": [
66+
{
67+
"title": "Gebühr",
68+
"detail": {
69+
"text": "7,00 €",
70+
"trend": null,
71+
"action": null,
72+
"displayValue": null,
73+
"type": "text"
74+
},
75+
"style": "plain"
76+
},
77+
{
78+
"title": "Betrag",
79+
"detail": {
80+
"text": "1.000,00 €",
81+
"trend": null,
82+
"action": null,
83+
"displayValue": null,
84+
"type": "text"
85+
},
86+
"style": "highlighted"
87+
}
88+
],
89+
"action": null,
90+
"type": "table"
91+
},
92+
{
93+
"title": "Dokumente",
94+
"data": [
95+
{
96+
"title": "Abrechnung Einzahlung",
97+
"detail": "27.08.2022",
98+
"action": {
99+
"type": "browserModal",
100+
"payload": "https://traderepublic-data-production.s3.eu-central-1.amazonaws.com/timeline/postbox/2022/8/27/51850145/pb16615767906502642694118463234.pdf?REDACTED"
101+
},
102+
"id": "4f6f159f-08f1-4573-9b69-2418d57ca37a",
103+
"postboxType": "PAYMENT_INBOUND_INVOICE",
104+
"local_filepath": "out/Abrechnung Einzahlung/2022-08-27 Abrechnung Einzahlung - Einzahlung.pdf"
105+
}
106+
],
107+
"action": null,
108+
"type": "documents"
109+
},
110+
{
111+
"title": "",
112+
"data": [
113+
{
114+
"title": "",
115+
"detail": {
116+
"icon": "",
117+
"action": {
118+
"type": "customerSupportChat",
119+
"payload": {
120+
"contextParams": {
121+
"chat_flow_key": "NHC_0024_deposit_report_an_issue",
122+
"timelineEventId": "5b04b073-c06f-4ab1-bd01-de51b56162dc",
123+
"createdAt": "2022-08-27T05:06:30.505105Z",
124+
"amount": "1000.000000"
125+
},
126+
"contextCategory": "NHC"
127+
}
128+
},
129+
"style": "highlighted",
130+
"type": "listItemAvatarDefault"
131+
},
132+
"style": "plain"
133+
}
134+
],
135+
"action": null,
136+
"type": "table"
137+
}
138+
]
139+
},
140+
"has_docs": true
141+
}

tests/test_event_csv_formatter.py

+11
Original file line numberDiff line numberDiff line change
@@ -38,3 +38,14 @@ def test_buy():
3838

3939
# Assert that the output is not an empty string
4040
assert csv_output == "2024-02-20;Kauf;-3.002,8;Euro Stoxx 50 EUR (Dist);IE00B4K6B022;60;-1;\n"
41+
42+
43+
def test_credit_card_deposit() -> None:
44+
with open("tests/sample_credit_card_deposit.json") as file:
45+
sample_data = json.load(file)
46+
47+
event = Event.from_dict(sample_data)
48+
formatter = EventCsvFormatter(lang="en")
49+
csv_output = formatter.format(event)
50+
51+
assert csv_output == "2022-08-27;Deposit;1,000;Einzahlung;;;-7;\n"

0 commit comments

Comments
 (0)