diff --git a/pytr/event.py b/pytr/event.py index a923403..8d8fffe 100644 --- a/pytr/event.py +++ b/pytr/event.py @@ -40,8 +40,8 @@ class PPEventType(EventType): SWAP = "SWAP" TAXES = "TAXES" TAX_REFUND = "TAX_REFUND" - TRANSFER_IN = "TRANSFER_IN" # Currently not mapped to - TRANSFER_OUT = "TRANSFER_OUT" # Currently not mapped to + TRANSFER_IN = "TRANSFER_IN" + TRANSFER_OUT = "TRANSFER_OUT" tr_event_type_mapping = { @@ -107,6 +107,9 @@ class PPEventType(EventType): "Sparplan ausgeführt": ConditionalEventType.TRADE_INVOICE, "Stop-Sell-Order": ConditionalEventType.TRADE_INVOICE, "Verkaufsorder": ConditionalEventType.TRADE_INVOICE, + # Transfers + "Aktien erhalten": PPEventType.TRANSFER_IN, + "Aktien übertragen": PPEventType.TRANSFER_OUT, } title_event_type_mapping = { @@ -156,6 +159,9 @@ class PPEventType(EventType): "Stop-Sell-Order": ConditionalEventType.TRADE_INVOICE, "Verkaufsorder": ConditionalEventType.TRADE_INVOICE, "Wertlos": ConditionalEventType.TRADE_INVOICE, + # Transfers + "Aktien erhalten": PPEventType.TRANSFER_IN, + "Aktien übertragen": PPEventType.TRANSFER_OUT, } events_known_ignored = [ @@ -335,7 +341,7 @@ def from_dict(cls, event_dict: Dict[Any, Any]): event_type = timeline_legacy_migrated_events_title_type_mapping.get(title) if event_type is None: event_type = timeline_legacy_migrated_events_subtitle_type_mapping.get(subtitle) - if event_type is None: + if event_type is None and subtitle != "Wertpapiertransfer": for item in event_dict.get("details", {}).get("sections", []): ititle = item.get("title", "") if ititle.startswith("Du hast "): @@ -379,6 +385,18 @@ def from_dict(cls, event_dict: Dict[Any, Any]): event_type = title_event_type_mapping.get(title, None) if event_type is None: event_type = subtitle_event_type_mapping.get(subtitle, None) + # Handle "Wertpapiertransfer" which can be either TRANSFER_IN or TRANSFER_OUT + if event_type is None and subtitle == "Wertpapiertransfer" and sections: + for item in sections: + ititle = item.get("title") + if ititle is None: + continue + if "Aktien erhalten" in ititle or "erhalten" in ititle: + event_type = PPEventType.TRANSFER_IN + break + elif "Aktien gesendet" in ititle or "gesendet" in ititle: + event_type = PPEventType.TRANSFER_OUT + break if event_type == ConditionalEventType.PRIVATE_MARKETS_ORDER and subtitle == "Vorabpauschale": event_type = PPEventType.TAXES if event_type is None and uebersicht_dict: @@ -459,6 +477,13 @@ def from_dict(cls, event_dict: Dict[Any, Any]): if event_type is not None and event_dict.get("status", "").lower() == "canceled": event_type = None + elif event_type is not None and sections: + for section in sections: + if section.get("type") == "header": + header_status = section.get("data", {}).get("status", "").lower() + if header_status == "canceled": + event_type = None + break elif ( event_type is None and eventTypeStr not in events_known_ignored @@ -512,23 +537,13 @@ def from_dict(cls, event_dict: Dict[Any, Any]): PPEventType.SWAP, PPEventType.TAXES, ]: - # Parse ISIN - for section in sections: - action = section.get("action", None) - if action and action.get("type", {}) == "instrumentDetail": - isin = section.get("action", {}).get("payload") - break - if section.get("type", {}) == "header": - isin = section.get("data", {}).get("icon") - if isinstance(isin, dict): - isin = isin.get("asset", "") - break - if isin is None: - isin = event_dict.get("icon", "") - isin = isin[isin.find("/") + 1 :] - isin = isin.split("/", 1)[0] + isin = cls._parse_isin(event_dict) shares, shares2, value, note = cls._parse_shares_value_note(event_type, event_dict) + elif event_type in [PPEventType.TRANSFER_IN, PPEventType.TRANSFER_OUT]: + isin = cls._parse_isin(event_dict) + shares = cls._parse_transfer_shares(event_dict) + value = 0 # Transfers have no monetary value else: value = v if (v := event_dict.get("amount", {}).get("value", None)) is not None and v != 0.0 else None @@ -607,12 +622,14 @@ def _parse_shares_value_note( sections = event_dict.get("details", {}).get("sections", [{}]) - transaction_dict = next(filter(lambda x: x.get("title") in ["Transaktion", "Geschäft"], sections), None) + transaction_dict = next( + filter(lambda x: x.get("title") in ["Transaktion", "Geschäft", "Transaction"], sections), None + ) if transaction_dict: # old style event dump_dict["maintitle"] = transaction_dict["title"] data = transaction_dict.get("data", [{}]) - shares_dict = next(filter(lambda x: x["title"] in ["Aktien", "Anteile"], data), None) + shares_dict = next(filter(lambda x: x["title"] in ["Aktien", "Anteile", "Shares"], data), None) uebersicht_dict = next(filter(lambda x: x.get("title") in ["Übersicht", "Overview"], sections), None) if uebersicht_dict: @@ -759,6 +776,59 @@ def _parse_card_note(event_dict: Dict[Any, Any]) -> Optional[str]: return None + @staticmethod + def _parse_isin(event_dict: Dict[Any, Any]) -> Optional[str]: + """Parses the ISIN from a transfer or corporate-action event""" + sections = event_dict.get("details", {}).get("sections", [{}]) + + for section in sections: + action = section.get("action", None) + if action and action.get("type", {}) == "instrumentDetail": + isin = action.get("payload") + break + if section.get("type", {}) == "header": + isin = section.get("data", {}).get("icon") + if isinstance(isin, dict): + isin = isin.get("asset", "") + break + else: + isin = event_dict.get("icon", "") + + if not isin: + return None + + isin = isin[isin.find("/") + 1 :] + return isin.split("/", 1)[0] + + @classmethod + def _parse_transfer_shares(cls, event_dict: Dict[Any, Any]) -> Optional[float]: + """Parses the number of shares from a transfer event + + Args: + event_dict (Dict[Any, Any]): The event dictionary + + Returns: + Optional[float]: The number of shares transferred + """ + sections = event_dict.get("details", {}).get("sections", [{}]) + + # Try to find shares in "Transaction" / "Transaktion" section (for TRANSFER_OUT) + transaction_dict = next(filter(lambda x: x.get("title") in ["Transaction", "Transaktion"], sections), None) + if transaction_dict: + for item in transaction_dict.get("data", []): + if item.get("title") in ["Shares", "Aktien"]: + return cls._parse_float_from_text_value(item.get("detail", {}).get("text", ""), {}, "en") + + # Try to find shares in "Übersicht" / "Overview" section (for TRANSFER_IN and Wertpapiertransfer) + uebersicht_dict = next(filter(lambda x: x.get("title") in ["Übersicht", "Overview"], sections), None) + if uebersicht_dict: + for item in uebersicht_dict.get("data", []): + # "Aktien" for newer events, "Anteile" for older Wertpapiertransfer events + if item.get("title") in ["Aktien", "Shares", "Anteile"]: + return cls._parse_float_from_text_value(item.get("detail", {}).get("text", ""), {}, "en") + + return None + @staticmethod def _parse_float_from_text_value( unparsed_val: str, diff --git a/tests/test_events.py b/tests/test_events.py index 1bd47a8..9438ce8 100644 --- a/tests/test_events.py +++ b/tests/test_events.py @@ -1058,6 +1058,123 @@ def test_events(): } ], }, + { + "filename": "transfer_out.json", + "event_type": PPEventType.TRANSFER_OUT, + "title": "Novo-Nordisk (B)", + "isin": "DK0062498333", + "shares": 42.0, + "value": 0, + "transactions": [ + { + "Datum": "2025-09-18T17:03:45", + "Typ": "Umbuchung (Ausgang)", + "Wert": 0, + "Notiz": "Novo-Nordisk (B)", + "ISIN": "DK0062498333", + "Stück": 42.0, + } + ], + }, + { + "filename": "transfer_in.json", + "event_type": PPEventType.TRANSFER_IN, + "title": "British American Tobacco", + "isin": "GB0002875804", + "shares": 1.0, + "value": 0, + "transactions": [ + { + "Datum": "2024-06-14T16:40:07", + "Typ": "Umbuchung (Eingang)", + "Wert": 0, + "Notiz": "British American Tobacco", + "ISIN": "GB0002875804", + "Stück": 1.0, + } + ], + }, + { + "filename": "wertpapiertransfer_in.json", + "event_type": PPEventType.TRANSFER_IN, + "title": "Metro", + "isin": "DE000BFB0019", + "shares": 76.0, + "value": 0, + "transactions": [ + { + "Datum": "2023-06-13T20:38:45", + "Typ": "Umbuchung (Eingang)", + "Wert": 0, + "Notiz": "Metro", + "ISIN": "DE000BFB0019", + "Stück": 76.0, + } + ], + }, + { + "filename": "wertpapiertransfer_out.json", + "event_type": PPEventType.TRANSFER_OUT, + "title": "Netflix", + "isin": "US64110L1061", + "shares": 4.0, + "value": 0, + "transactions": [ + { + "Datum": "2024-03-15T14:22:33", + "Typ": "Umbuchung (Ausgang)", + "Wert": 0, + "Notiz": "Netflix", + "ISIN": "US64110L1061", + "Stück": 4.0, + } + ], + }, + { + "filename": "wertpapiertransfer_in_legacy.json", + "event_type": PPEventType.TRANSFER_IN, + "title": "Metro", + "isin": "DE000BFB0019", + "shares": 76.0, + "value": 0, + "transactions": [ + { + "Datum": "2022-04-10T10:15:30", + "Typ": "Umbuchung (Eingang)", + "Wert": 0, + "Notiz": "Metro", + "ISIN": "DE000BFB0019", + "Stück": 76.0, + } + ], + }, + { + "filename": "wertpapiertransfer_out_legacy.json", + "event_type": PPEventType.TRANSFER_OUT, + "title": "Netflix", + "isin": "US64110L1061", + "shares": 4.0, + "value": 0, + "transactions": [ + { + "Datum": "2022-05-20T16:45:00", + "Typ": "Umbuchung (Ausgang)", + "Wert": 0, + "Notiz": "Netflix", + "ISIN": "US64110L1061", + "Stück": 4.0, + } + ], + }, + { + "filename": "transfer_out_cancelled.json", + "event_type": None, + "title": "MSCI World USD (Dist)", + "isin": None, + "shares": None, + "value": None, + "transactions": [], + }, { "filename": "payment_inbound_credit_card.json", "event_type": PPEventType.DEPOSIT, diff --git a/tests/transfer_in.json b/tests/transfer_in.json new file mode 100644 index 0000000..6912104 --- /dev/null +++ b/tests/transfer_in.json @@ -0,0 +1,93 @@ +{ + "id": "c511b534-0c1a-4390-ac9c-8572eb47430c", + "timestamp": "2024-06-14T16:40:07.424+0000", + "title": "British American Tobacco", + "icon": "logos/GB0002875804/v2", + "subtitle": "Aktien erhalten", + "action": { + "type": "timelineDetail", + "payload": "c511b534-0c1a-4390-ac9c-8572eb47430c" + }, + "source": "timelineActivity", + "details": { + "id": "c511b534-0c1a-4390-ac9c-8572eb47430c", + "sections": [ + { + "title": "Du hast Aktien im Wert von 1.0 erhalten", + "data": { + "icon": { + "asset": "logos/GB0002875804/v2", + "badge": null + }, + "timestamp": "2024-06-14T16:40:07.424Z", + "status": "executed" + }, + "action": { + "payload": "GB0002875804", + "type": "instrumentDetail" + }, + "type": "header" + }, + { + "title": "Übersicht", + "data": [ + { + "title": "Status", + "detail": { + "text": "Abgeschlossen", + "functionalStyle": "EXECUTED", + "type": "status" + }, + "style": "plain" + }, + { + "title": "Auftragsart", + "detail": { + "text": "Wertpapierübertrag", + "displayValue": { + "text": "Wertpapierübertrag" + }, + "type": "text" + }, + "style": "plain" + }, + { + "title": "Aktien", + "detail": { + "text": "1.0", + "displayValue": { + "text": "1.0" + }, + "type": "text" + }, + "style": "plain" + }, + { + "title": "Asset", + "detail": { + "text": "British American Tobacco", + "displayValue": { + "text": "British American Tobacco" + }, + "type": "text" + }, + "style": "plain" + } + ], + "type": "table" + }, + { + "title": "Dokumente", + "data": [ + { + "title": "Ausführungsmitteilung", + "detail": "18.06.2024", + "id": "c511b534-0c1a-4390-ac9c-8572eb47430c", + "postboxType": "TRANSFER_INVOICE" + } + ], + "type": "documents" + } + ] + } +} diff --git a/tests/transfer_out.json b/tests/transfer_out.json new file mode 100644 index 0000000..214b6e9 --- /dev/null +++ b/tests/transfer_out.json @@ -0,0 +1,106 @@ +{ + "id": "9cadff27-504a-3326-9102-cfd67a0ac5c2", + "timestamp": "2025-09-18T17:03:45.166+0000", + "title": "Novo-Nordisk (B)", + "icon": "logos/DK0062498333/v2", + "subtitle": "Aktien übertragen", + "action": { + "type": "timelineDetail", + "payload": "9cadff27-504a-3326-9102-cfd67a0ac5c2" + }, + "source": "timelineActivity", + "details": { + "id": "9cadff27-504a-3326-9102-cfd67a0ac5c2", + "sections": [ + { + "type": "header", + "title": "You transferred 42 shares", + "data": { + "status": "executed", + "icon": "logos/DK0062498333/v2", + "timestamp": "2025-09-18T17:03:45.166804327Z" + } + }, + { + "type": "table", + "title": "Overview", + "data": [ + { + "title": "Status", + "style": "plain", + "detail": { + "type": "status", + "text": "Completed", + "functionalStyle": "EXECUTED" + } + }, + { + "title": "Asset", + "style": "plain", + "detail": { + "type": "text", + "text": "Novo-Nordisk (B)" + } + }, + { + "title": "Action", + "style": "plain", + "detail": { + "type": "text", + "text": "Securities transfer" + } + }, + { + "title": "Transfer to", + "style": "plain", + "detail": { + "type": "text", + "text": "BAADER BANK AKTIENGESELLSCHAFT" + } + }, + { + "title": "BIC", + "style": "plain", + "detail": { + "type": "text", + "text": "BDWBDEMMXXX" + } + } + ] + }, + { + "type": "table", + "title": "Transaction", + "data": [ + { + "title": "Shares", + "style": "plain", + "detail": { + "type": "text", + "text": "42" + } + }, + { + "title": "Fee", + "style": "plain", + "detail": { + "type": "text", + "text": "Free" + } + } + ] + }, + { + "type": "documents", + "title": "Documents", + "data": [ + { + "id": "d7b428e6-218d-3197-8d8b-57a22d164ce8", + "title": "Execution Notice", + "postboxType": "TRANSFER_INVOICE_TYPE" + } + ] + } + ] + } +} diff --git a/tests/transfer_out_cancelled.json b/tests/transfer_out_cancelled.json new file mode 100644 index 0000000..f4f2c80 --- /dev/null +++ b/tests/transfer_out_cancelled.json @@ -0,0 +1,92 @@ +{ + "id": "83af5c46-caa7-4e07-a504-ef0fbe367925", + "timestamp": "2024-11-16T11:55:12.959+0000", + "title": "MSCI World USD (Dist)", + "icon": "logos/IE00BK1PV551/v2", + "subtitle": "Aktien übertragen", + "action": { + "type": "timelineDetail", + "payload": "83af5c46-caa7-4e07-a504-ef0fbe367925" + }, + "source": "timelineActivity", + "details": { + "id": "83af5c46-caa7-4e07-a504-ef0fbe367925", + "sections": [ + { + "type": "header", + "title": "You transferred 14 shares", + "data": { + "status": "canceled", + "icon": "logos/IE00BK1PV551/v2", + "timestamp": "2024-11-16T11:55:12.959548322Z" + } + }, + { + "type": "banner", + "title": "Shares not accepted", + "description": "Your outgoing transfer was rejected since your receiving bank didn't accept your shares within 21 days." + }, + { + "type": "table", + "title": "Overview", + "data": [ + { + "title": "Status", + "style": "plain", + "detail": { + "type": "status", + "text": "Rejected", + "functionalStyle": "CANCELED" + } + }, + { + "title": "Asset", + "style": "plain", + "detail": { + "type": "text", + "text": "MSCI World USD (Dist)" + } + }, + { + "title": "Action", + "style": "plain", + "detail": { + "type": "text", + "text": "Securities transfer" + } + }, + { + "title": "BIC", + "style": "plain", + "detail": { + "type": "text", + "text": "BDWBDEMMXXX" + } + } + ] + }, + { + "type": "table", + "title": "Transaction", + "data": [ + { + "title": "Shares", + "style": "plain", + "detail": { + "type": "text", + "text": "14" + } + }, + { + "title": "Fee", + "style": "plain", + "detail": { + "type": "text", + "text": "Free" + } + } + ] + } + ] + } +} diff --git a/tests/wertpapiertransfer_in.json b/tests/wertpapiertransfer_in.json new file mode 100644 index 0000000..59b0f47 --- /dev/null +++ b/tests/wertpapiertransfer_in.json @@ -0,0 +1,82 @@ +{ + "id": "6471c9c6-445d-4309-bb41-a29d8b3d24ba", + "timestamp": "2023-06-13T20:38:45.991+0000", + "title": "Metro", + "icon": "logos/DE000BFB0019/v2", + "subtitle": "Wertpapiertransfer", + "action": { + "type": "timelineDetail", + "payload": "6471c9c6-445d-4309-bb41-a29d8b3d24ba" + }, + "source": "timelineActivity", + "details": { + "id": "6471c9c6-445d-4309-bb41-a29d8b3d24ba", + "sections": [ + { + "title": "Du hast 76 Aktien erhalten", + "data": { + "icon": "logos/DE000BFB0019/v2", + "subtitleText": null, + "timestamp": "2023-06-13T20:38:45.991+0000", + "status": "executed" + }, + "action": { + "type": "instrumentDetail", + "payload": "DE000BFB0019" + }, + "type": "header" + }, + { + "title": "Übersicht", + "data": [ + { + "title": "Status", + "detail": { + "text": "Completed", + "functionalStyle": "EXECUTED", + "type": "status" + }, + "style": "plain" + }, + { + "title": "Orderart", + "detail": { + "text": "Wertpapiertransfer", + "type": "text" + }, + "style": "plain" + }, + { + "title": "Anteile", + "detail": { + "text": "76", + "type": "text" + }, + "style": "plain" + }, + { + "title": "Anteil", + "detail": { + "text": "Metro", + "type": "text" + }, + "style": "plain" + } + ], + "type": "table" + }, + { + "title": "Dokumente", + "data": [ + { + "title": "Abrechnung", + "detail": "13.06.2023", + "id": "3f4fcb77-fe00-45f6-bd03-23621e27a1f6", + "postboxType": "SHAREBOOKING" + } + ], + "type": "documents" + } + ] + } +} diff --git a/tests/wertpapiertransfer_in_legacy.json b/tests/wertpapiertransfer_in_legacy.json new file mode 100644 index 0000000..d539a9e --- /dev/null +++ b/tests/wertpapiertransfer_in_legacy.json @@ -0,0 +1,83 @@ +{ + "id": "a1b2c3d4-e5f6-7890-ab12-cd34ef567890", + "timestamp": "2022-04-10T10:15:30.000+0000", + "title": "Metro", + "icon": "logos/DE000BFB0019/v2", + "subtitle": "Wertpapiertransfer", + "eventType": "timeline_legacy_migrated_events", + "action": { + "type": "timelineDetail", + "payload": "a1b2c3d4-e5f6-7890-ab12-cd34ef567890" + }, + "source": "timelineActivity", + "details": { + "id": "a1b2c3d4-e5f6-7890-ab12-cd34ef567890", + "sections": [ + { + "title": "Du hast 76 Aktien erhalten", + "data": { + "icon": "logos/DE000BFB0019/v2", + "subtitleText": null, + "timestamp": "2022-04-10T10:15:30.000+0000", + "status": "executed" + }, + "action": { + "type": "instrumentDetail", + "payload": "DE000BFB0019" + }, + "type": "header" + }, + { + "title": "Übersicht", + "data": [ + { + "title": "Status", + "detail": { + "text": "Completed", + "functionalStyle": "EXECUTED", + "type": "status" + }, + "style": "plain" + }, + { + "title": "Orderart", + "detail": { + "text": "Wertpapiertransfer", + "type": "text" + }, + "style": "plain" + }, + { + "title": "Anteile", + "detail": { + "text": "76", + "type": "text" + }, + "style": "plain" + }, + { + "title": "Anteil", + "detail": { + "text": "Metro", + "type": "text" + }, + "style": "plain" + } + ], + "type": "table" + }, + { + "title": "Dokumente", + "data": [ + { + "title": "Abrechnung", + "detail": "10.04.2022", + "id": "b2c3d4e5-f6a7-8901-bc23-de45fg678901", + "postboxType": "SHAREBOOKING" + } + ], + "type": "documents" + } + ] + } +} diff --git a/tests/wertpapiertransfer_out.json b/tests/wertpapiertransfer_out.json new file mode 100644 index 0000000..6b08dc2 --- /dev/null +++ b/tests/wertpapiertransfer_out.json @@ -0,0 +1,82 @@ +{ + "id": "7582dac7-556e-5410-cc52-b30e9c4e35cb", + "timestamp": "2024-03-15T14:22:33.456+0000", + "title": "Netflix", + "icon": "logos/US64110L1061/v2", + "subtitle": "Wertpapiertransfer", + "action": { + "type": "timelineDetail", + "payload": "7582dac7-556e-5410-cc52-b30e9c4e35cb" + }, + "source": "timelineActivity", + "details": { + "id": "7582dac7-556e-5410-cc52-b30e9c4e35cb", + "sections": [ + { + "title": "Du hast 4 Aktien gesendet", + "data": { + "icon": "logos/US64110L1061/v2", + "subtitleText": null, + "timestamp": "2024-03-15T14:22:33.456+0000", + "status": "executed" + }, + "action": { + "type": "instrumentDetail", + "payload": "US64110L1061" + }, + "type": "header" + }, + { + "title": "Übersicht", + "data": [ + { + "title": "Status", + "detail": { + "text": "Completed", + "functionalStyle": "EXECUTED", + "type": "status" + }, + "style": "plain" + }, + { + "title": "Orderart", + "detail": { + "text": "Wertpapiertransfer", + "type": "text" + }, + "style": "plain" + }, + { + "title": "Anteile", + "detail": { + "text": "4", + "type": "text" + }, + "style": "plain" + }, + { + "title": "Anteil", + "detail": { + "text": "Netflix", + "type": "text" + }, + "style": "plain" + } + ], + "type": "table" + }, + { + "title": "Dokumente", + "data": [ + { + "title": "Abrechnung", + "detail": "15.03.2024", + "id": "4g5gdc88-gf11-56g7-ce04-34732f38b2g7", + "postboxType": "SHAREBOOKING" + } + ], + "type": "documents" + } + ] + } +} diff --git a/tests/wertpapiertransfer_out_legacy.json b/tests/wertpapiertransfer_out_legacy.json new file mode 100644 index 0000000..1928379 --- /dev/null +++ b/tests/wertpapiertransfer_out_legacy.json @@ -0,0 +1,83 @@ +{ + "id": "b2c3d4e5-f6a7-8901-bc23-de45fg678901", + "timestamp": "2022-05-20T16:45:00.000+0000", + "title": "Netflix", + "icon": "logos/US64110L1061/v2", + "subtitle": "Wertpapiertransfer", + "eventType": "timeline_legacy_migrated_events", + "action": { + "type": "timelineDetail", + "payload": "b2c3d4e5-f6a7-8901-bc23-de45fg678901" + }, + "source": "timelineActivity", + "details": { + "id": "b2c3d4e5-f6a7-8901-bc23-de45fg678901", + "sections": [ + { + "title": "Du hast 4 Aktien gesendet", + "data": { + "icon": "logos/US64110L1061/v2", + "subtitleText": null, + "timestamp": "2022-05-20T16:45:00.000+0000", + "status": "executed" + }, + "action": { + "type": "instrumentDetail", + "payload": "US64110L1061" + }, + "type": "header" + }, + { + "title": "Übersicht", + "data": [ + { + "title": "Status", + "detail": { + "text": "Completed", + "functionalStyle": "EXECUTED", + "type": "status" + }, + "style": "plain" + }, + { + "title": "Orderart", + "detail": { + "text": "Wertpapiertransfer", + "type": "text" + }, + "style": "plain" + }, + { + "title": "Anteile", + "detail": { + "text": "4", + "type": "text" + }, + "style": "plain" + }, + { + "title": "Anteil", + "detail": { + "text": "Netflix", + "type": "text" + }, + "style": "plain" + } + ], + "type": "table" + }, + { + "title": "Dokumente", + "data": [ + { + "title": "Abrechnung", + "detail": "20.05.2022", + "id": "c3d4e5f6-a7b8-9012-cd34-ef56gh789012", + "postboxType": "SHAREBOOKING" + } + ], + "type": "documents" + } + ] + } +}