wbportfolio 1.52.0__py2.py3-none-any.whl → 1.59.4__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.

Potentially problematic release.


This version of wbportfolio might be problematic. Click here for more details.

Files changed (273) hide show
  1. wbportfolio/admin/__init__.py +3 -1
  2. wbportfolio/admin/indexes.py +1 -1
  3. wbportfolio/admin/orders/__init__.py +2 -0
  4. wbportfolio/admin/orders/order_proposals.py +16 -0
  5. wbportfolio/admin/orders/orders.py +32 -0
  6. wbportfolio/admin/portfolio.py +11 -5
  7. wbportfolio/admin/product_groups.py +1 -1
  8. wbportfolio/admin/products.py +2 -1
  9. wbportfolio/admin/{transactions/rebalancing.py → rebalancing.py} +1 -1
  10. wbportfolio/admin/transactions/__init__.py +0 -2
  11. wbportfolio/admin/transactions/dividends.py +40 -4
  12. wbportfolio/admin/transactions/fees.py +24 -14
  13. wbportfolio/admin/transactions/trades.py +34 -27
  14. wbportfolio/analysis/claims.py +5 -6
  15. wbportfolio/api_clients/ubs.py +162 -0
  16. wbportfolio/constants.py +1 -0
  17. wbportfolio/contrib/company_portfolio/configs/display.py +22 -10
  18. wbportfolio/contrib/company_portfolio/configs/previews.py +3 -3
  19. wbportfolio/contrib/company_portfolio/filters.py +10 -10
  20. wbportfolio/contrib/company_portfolio/models.py +69 -39
  21. wbportfolio/contrib/company_portfolio/scripts.py +7 -2
  22. wbportfolio/contrib/company_portfolio/serializers.py +32 -22
  23. wbportfolio/contrib/company_portfolio/tasks.py +12 -1
  24. wbportfolio/contrib/company_portfolio/tests/conftest.py +2 -2
  25. wbportfolio/defaults/fees/default.py +7 -15
  26. wbportfolio/factories/__init__.py +2 -2
  27. wbportfolio/factories/assets.py +1 -1
  28. wbportfolio/factories/dividends.py +8 -3
  29. wbportfolio/factories/fees.py +8 -4
  30. wbportfolio/factories/orders/__init__.py +2 -0
  31. wbportfolio/factories/orders/order_proposals.py +21 -0
  32. wbportfolio/factories/orders/orders.py +34 -0
  33. wbportfolio/factories/portfolios.py +2 -1
  34. wbportfolio/factories/product_groups.py +3 -3
  35. wbportfolio/factories/products.py +3 -3
  36. wbportfolio/factories/rebalancing.py +1 -1
  37. wbportfolio/factories/trades.py +12 -16
  38. wbportfolio/filters/assets.py +18 -4
  39. wbportfolio/filters/orders/__init__.py +2 -0
  40. wbportfolio/filters/orders/order_proposals.py +55 -0
  41. wbportfolio/filters/orders/orders.py +11 -0
  42. wbportfolio/filters/portfolios.py +38 -1
  43. wbportfolio/filters/positions.py +0 -1
  44. wbportfolio/filters/transactions/__init__.py +1 -2
  45. wbportfolio/filters/transactions/fees.py +5 -12
  46. wbportfolio/filters/transactions/trades.py +16 -8
  47. wbportfolio/filters/transactions/utils.py +42 -0
  48. wbportfolio/import_export/backends/ubs/__init__.py +1 -0
  49. wbportfolio/import_export/backends/ubs/asset_position.py +6 -7
  50. wbportfolio/import_export/backends/ubs/fees.py +10 -20
  51. wbportfolio/import_export/backends/ubs/instrument_price.py +6 -6
  52. wbportfolio/import_export/backends/ubs/trade.py +48 -0
  53. wbportfolio/import_export/backends/utils.py +0 -17
  54. wbportfolio/import_export/handlers/asset_position.py +22 -10
  55. wbportfolio/import_export/handlers/dividend.py +8 -8
  56. wbportfolio/import_export/handlers/fees.py +13 -23
  57. wbportfolio/import_export/handlers/orders.py +71 -0
  58. wbportfolio/import_export/handlers/trade.py +53 -77
  59. wbportfolio/import_export/parsers/default_mapping.py +1 -1
  60. wbportfolio/import_export/parsers/jpmorgan/customer_trade.py +2 -2
  61. wbportfolio/import_export/parsers/jpmorgan/fees.py +4 -4
  62. wbportfolio/import_export/parsers/jpmorgan/strategy.py +59 -85
  63. wbportfolio/import_export/parsers/jpmorgan/valuation.py +2 -2
  64. wbportfolio/import_export/parsers/leonteq/customer_trade.py +5 -5
  65. wbportfolio/import_export/parsers/leonteq/fees.py +11 -7
  66. wbportfolio/import_export/parsers/leonteq/trade.py +2 -6
  67. wbportfolio/import_export/parsers/natixis/d1_fees.py +2 -2
  68. wbportfolio/import_export/parsers/natixis/dividend.py +4 -9
  69. wbportfolio/import_export/parsers/natixis/equity.py +22 -4
  70. wbportfolio/import_export/parsers/natixis/fees.py +7 -9
  71. wbportfolio/import_export/parsers/natixis/utils.py +13 -19
  72. wbportfolio/import_export/parsers/sg_lux/customer_trade_pending_slk.py +1 -1
  73. wbportfolio/import_export/parsers/sg_lux/equity.py +10 -10
  74. wbportfolio/import_export/parsers/sg_lux/fees.py +2 -2
  75. wbportfolio/import_export/parsers/sg_lux/perf_fees.py +2 -2
  76. wbportfolio/import_export/parsers/sg_lux/sylk.py +12 -11
  77. wbportfolio/import_export/parsers/sg_lux/utils.py +2 -2
  78. wbportfolio/import_export/parsers/sg_lux/valuation.py +4 -2
  79. wbportfolio/import_export/parsers/societe_generale/strategy.py +5 -5
  80. wbportfolio/import_export/parsers/tellco/customer_trade.py +2 -1
  81. wbportfolio/import_export/parsers/tellco/valuation.py +4 -3
  82. wbportfolio/import_export/parsers/ubs/api/fees.py +2 -2
  83. wbportfolio/import_export/parsers/ubs/api/trade.py +39 -0
  84. wbportfolio/import_export/parsers/ubs/customer_trade.py +7 -5
  85. wbportfolio/import_export/parsers/ubs/equity.py +3 -2
  86. wbportfolio/import_export/parsers/ubs/valuation.py +2 -1
  87. wbportfolio/import_export/parsers/vontobel/customer_trade.py +2 -3
  88. wbportfolio/import_export/parsers/vontobel/historical_customer_trade.py +0 -1
  89. wbportfolio/import_export/parsers/vontobel/management_fees.py +12 -20
  90. wbportfolio/import_export/parsers/vontobel/performance_fees.py +5 -8
  91. wbportfolio/import_export/parsers/vontobel/valuation_api.py +4 -1
  92. wbportfolio/import_export/resources/trades.py +3 -3
  93. wbportfolio/import_export/utils.py +3 -1
  94. wbportfolio/jinja2/wbportfolio/sql/aum_nnm.sql +2 -2
  95. wbportfolio/metric/backends/base.py +2 -2
  96. wbportfolio/migrations/0059_fees_unique_fees.py +1 -1
  97. wbportfolio/migrations/0077_remove_transaction_currency_and_more.py +622 -0
  98. wbportfolio/migrations/0078_trade_drift_factor.py +26 -0
  99. wbportfolio/migrations/0079_alter_trade_drift_factor.py +19 -0
  100. wbportfolio/migrations/0080_alter_trade_drift_factor_alter_trade_weighting.py +19 -0
  101. wbportfolio/migrations/0081_alter_trade_drift_factor.py +19 -0
  102. wbportfolio/migrations/0082_remove_tradeproposal_creator_and_more.py +93 -0
  103. wbportfolio/migrations/0083_order_alter_trade_options_and_more.py +181 -0
  104. wbportfolio/migrations/0084_orderproposal_min_order_value.py +25 -0
  105. wbportfolio/migrations/0085_order_desired_target_weight.py +26 -0
  106. wbportfolio/migrations/0086_orderproposal_total_cash_weight.py +19 -0
  107. wbportfolio/migrations/0087_product_order_routing_custodian_adapter.py +94 -0
  108. wbportfolio/migrations/0088_orderproposal_total_effective_portfolio_contribution.py +19 -0
  109. wbportfolio/migrations/0089_orderproposal_min_weighting.py +71 -0
  110. wbportfolio/migrations/0090_dividendtransaction_price_fx_portfolio_and_more.py +44 -0
  111. wbportfolio/migrations/0091_remove_order_execution_confirmed_and_more.py +32 -0
  112. wbportfolio/migrations/0092_order_quantization_error_alter_orderproposal_status.py +49 -0
  113. wbportfolio/migrations/0093_remove_portfolioportfoliothroughmodel_unique_primary_and_more.py +35 -0
  114. wbportfolio/models/__init__.py +2 -0
  115. wbportfolio/models/adjustments.py +1 -1
  116. wbportfolio/models/asset.py +28 -170
  117. wbportfolio/models/builder.py +323 -0
  118. wbportfolio/models/custodians.py +3 -3
  119. wbportfolio/models/exceptions.py +1 -1
  120. wbportfolio/models/graphs/portfolio.py +1 -1
  121. wbportfolio/models/graphs/utils.py +11 -11
  122. wbportfolio/models/mixins/instruments.py +7 -0
  123. wbportfolio/models/mixins/liquidity_stress_test.py +4 -4
  124. wbportfolio/models/orders/__init__.py +2 -0
  125. wbportfolio/models/orders/order_proposals.py +1414 -0
  126. wbportfolio/models/orders/orders.py +410 -0
  127. wbportfolio/models/portfolio.py +311 -289
  128. wbportfolio/models/portfolio_relationship.py +6 -0
  129. wbportfolio/models/products.py +12 -0
  130. wbportfolio/models/{transactions/rebalancing.py → rebalancing.py} +40 -27
  131. wbportfolio/models/roles.py +4 -10
  132. wbportfolio/models/transactions/__init__.py +0 -4
  133. wbportfolio/models/transactions/claim.py +7 -6
  134. wbportfolio/models/transactions/dividends.py +42 -5
  135. wbportfolio/models/transactions/fees.py +55 -22
  136. wbportfolio/models/transactions/trades.py +121 -442
  137. wbportfolio/models/transactions/transactions.py +78 -158
  138. wbportfolio/models/utils.py +100 -1
  139. wbportfolio/order_routing/__init__.py +35 -0
  140. wbportfolio/order_routing/adapters/__init__.py +65 -0
  141. wbportfolio/order_routing/adapters/ubs.py +195 -0
  142. wbportfolio/order_routing/router.py +33 -0
  143. wbportfolio/order_routing/tests/__init__.py +0 -0
  144. wbportfolio/order_routing/tests/test_router.py +110 -0
  145. wbportfolio/permissions.py +7 -0
  146. wbportfolio/pms/analytics/portfolio.py +17 -9
  147. wbportfolio/pms/analytics/utils.py +9 -0
  148. wbportfolio/pms/trading/__init__.py +0 -1
  149. wbportfolio/pms/trading/optimizer.py +61 -0
  150. wbportfolio/pms/typing.py +198 -63
  151. wbportfolio/rebalancing/base.py +12 -1
  152. wbportfolio/rebalancing/decorators.py +1 -1
  153. wbportfolio/rebalancing/models/composite.py +4 -8
  154. wbportfolio/rebalancing/models/equally_weighted.py +13 -11
  155. wbportfolio/rebalancing/models/market_capitalization_weighted.py +21 -14
  156. wbportfolio/rebalancing/models/model_portfolio.py +14 -18
  157. wbportfolio/risk_management/backends/__init__.py +1 -0
  158. wbportfolio/risk_management/backends/controversy_portfolio.py +2 -2
  159. wbportfolio/risk_management/backends/esg_aggregation_portfolio.py +64 -0
  160. wbportfolio/risk_management/backends/exposure_portfolio.py +4 -4
  161. wbportfolio/risk_management/backends/instrument_list_portfolio.py +3 -3
  162. wbportfolio/risk_management/tests/test_esg_aggregation_portfolio.py +49 -0
  163. wbportfolio/risk_management/tests/test_exposure_portfolio.py +1 -1
  164. wbportfolio/risk_management/tests/test_stop_loss_instrument.py +2 -2
  165. wbportfolio/risk_management/tests/test_stop_loss_portfolio.py +1 -1
  166. wbportfolio/serializers/__init__.py +1 -0
  167. wbportfolio/serializers/orders/__init__.py +2 -0
  168. wbportfolio/serializers/orders/order_proposals.py +115 -0
  169. wbportfolio/serializers/orders/orders.py +283 -0
  170. wbportfolio/serializers/portfolios.py +7 -7
  171. wbportfolio/serializers/positions.py +2 -2
  172. wbportfolio/serializers/rebalancing.py +1 -1
  173. wbportfolio/serializers/signals.py +9 -12
  174. wbportfolio/serializers/transactions/__init__.py +1 -10
  175. wbportfolio/serializers/transactions/claim.py +2 -2
  176. wbportfolio/serializers/transactions/dividends.py +37 -9
  177. wbportfolio/serializers/transactions/fees.py +39 -10
  178. wbportfolio/serializers/transactions/trades.py +55 -157
  179. wbportfolio/tasks.py +43 -5
  180. wbportfolio/tests/analysis/__init__.py +0 -0
  181. wbportfolio/tests/analysis/test_claims.py +85 -0
  182. wbportfolio/tests/conftest.py +12 -12
  183. wbportfolio/tests/models/orders/__init__.py +0 -0
  184. wbportfolio/tests/models/orders/test_order_proposals.py +1046 -0
  185. wbportfolio/tests/models/test_assets.py +7 -3
  186. wbportfolio/tests/models/test_imports.py +9 -13
  187. wbportfolio/tests/models/test_portfolios.py +102 -95
  188. wbportfolio/tests/models/test_products.py +11 -0
  189. wbportfolio/tests/models/test_splits.py +1 -6
  190. wbportfolio/tests/models/test_utils.py +140 -0
  191. wbportfolio/tests/models/transactions/test_fees.py +7 -13
  192. wbportfolio/tests/models/transactions/test_rebalancing.py +5 -5
  193. wbportfolio/tests/models/transactions/test_trades.py +0 -20
  194. wbportfolio/tests/pms/test_analytics.py +22 -3
  195. wbportfolio/tests/rebalancing/test_models.py +51 -57
  196. wbportfolio/tests/signals.py +10 -20
  197. wbportfolio/tests/tests.py +3 -1
  198. wbportfolio/tests/viewsets/test_products.py +1 -0
  199. wbportfolio/urls.py +10 -13
  200. wbportfolio/viewsets/__init__.py +9 -4
  201. wbportfolio/viewsets/assets.py +3 -204
  202. wbportfolio/viewsets/charts/__init__.py +6 -1
  203. wbportfolio/viewsets/charts/assets.py +344 -154
  204. wbportfolio/viewsets/configs/buttons/__init__.py +2 -2
  205. wbportfolio/viewsets/configs/buttons/assets.py +1 -1
  206. wbportfolio/viewsets/configs/buttons/mixins.py +4 -4
  207. wbportfolio/viewsets/configs/buttons/portfolios.py +45 -1
  208. wbportfolio/viewsets/configs/buttons/products.py +32 -2
  209. wbportfolio/viewsets/configs/display/__init__.py +2 -5
  210. wbportfolio/viewsets/configs/display/assets.py +6 -19
  211. wbportfolio/viewsets/configs/display/fees.py +3 -3
  212. wbportfolio/viewsets/configs/display/portfolios.py +5 -5
  213. wbportfolio/viewsets/configs/display/products.py +1 -1
  214. wbportfolio/viewsets/configs/display/rebalancing.py +2 -2
  215. wbportfolio/viewsets/configs/display/reconciliations.py +4 -4
  216. wbportfolio/viewsets/configs/display/trades.py +1 -189
  217. wbportfolio/viewsets/configs/endpoints/__init__.py +3 -7
  218. wbportfolio/viewsets/configs/endpoints/fees.py +2 -2
  219. wbportfolio/viewsets/configs/endpoints/trades.py +0 -41
  220. wbportfolio/viewsets/configs/menu/__init__.py +1 -1
  221. wbportfolio/viewsets/configs/menu/orders.py +11 -0
  222. wbportfolio/viewsets/configs/titles/__init__.py +2 -3
  223. wbportfolio/viewsets/configs/titles/fees.py +4 -8
  224. wbportfolio/viewsets/esg.py +3 -5
  225. wbportfolio/viewsets/mixins.py +5 -1
  226. wbportfolio/viewsets/orders/__init__.py +6 -0
  227. wbportfolio/viewsets/orders/configs/__init__.py +4 -0
  228. wbportfolio/viewsets/orders/configs/buttons/__init__.py +2 -0
  229. wbportfolio/viewsets/orders/configs/buttons/order_proposals.py +188 -0
  230. wbportfolio/viewsets/orders/configs/buttons/orders.py +113 -0
  231. wbportfolio/viewsets/orders/configs/displays/__init__.py +2 -0
  232. wbportfolio/viewsets/orders/configs/displays/order_proposals.py +157 -0
  233. wbportfolio/viewsets/orders/configs/displays/orders.py +232 -0
  234. wbportfolio/viewsets/orders/configs/endpoints/__init__.py +2 -0
  235. wbportfolio/viewsets/orders/configs/endpoints/order_proposals.py +21 -0
  236. wbportfolio/viewsets/orders/configs/endpoints/orders.py +28 -0
  237. wbportfolio/viewsets/orders/configs/titles/__init__.py +0 -0
  238. wbportfolio/viewsets/orders/configs/titles/orders.py +0 -0
  239. wbportfolio/viewsets/orders/order_proposals.py +252 -0
  240. wbportfolio/viewsets/orders/orders.py +277 -0
  241. wbportfolio/viewsets/portfolios.py +36 -12
  242. wbportfolio/viewsets/positions.py +3 -2
  243. wbportfolio/viewsets/products.py +6 -6
  244. wbportfolio/viewsets/{transactions/rebalancing.py → rebalancing.py} +2 -2
  245. wbportfolio/viewsets/transactions/__init__.py +3 -14
  246. wbportfolio/viewsets/transactions/fees.py +22 -22
  247. wbportfolio/viewsets/transactions/trades.py +1 -180
  248. {wbportfolio-1.52.0.dist-info → wbportfolio-1.59.4.dist-info}/METADATA +3 -1
  249. {wbportfolio-1.52.0.dist-info → wbportfolio-1.59.4.dist-info}/RECORD +252 -203
  250. {wbportfolio-1.52.0.dist-info → wbportfolio-1.59.4.dist-info}/WHEEL +1 -1
  251. wbportfolio/admin/transactions/transactions.py +0 -38
  252. wbportfolio/factories/transactions.py +0 -22
  253. wbportfolio/fdm/tasks.py +0 -13
  254. wbportfolio/filters/transactions/transactions.py +0 -99
  255. wbportfolio/models/transactions/expiry.py +0 -7
  256. wbportfolio/models/transactions/trade_proposals.py +0 -704
  257. wbportfolio/pms/trading/handler.py +0 -161
  258. wbportfolio/serializers/transactions/expiry.py +0 -18
  259. wbportfolio/serializers/transactions/trade_proposals.py +0 -76
  260. wbportfolio/serializers/transactions/transactions.py +0 -85
  261. wbportfolio/tests/models/transactions/test_trade_proposals.py +0 -410
  262. wbportfolio/viewsets/configs/buttons/trade_proposals.py +0 -66
  263. wbportfolio/viewsets/configs/display/trade_proposals.py +0 -100
  264. wbportfolio/viewsets/configs/display/transactions.py +0 -55
  265. wbportfolio/viewsets/configs/endpoints/trade_proposals.py +0 -18
  266. wbportfolio/viewsets/configs/endpoints/transactions.py +0 -14
  267. wbportfolio/viewsets/configs/menu/transactions.py +0 -9
  268. wbportfolio/viewsets/configs/titles/transactions.py +0 -9
  269. wbportfolio/viewsets/signals.py +0 -43
  270. wbportfolio/viewsets/transactions/trade_proposals.py +0 -139
  271. wbportfolio/viewsets/transactions/transactions.py +0 -122
  272. /wbportfolio/{fdm → api_clients}/__init__.py +0 -0
  273. {wbportfolio-1.52.0.dist-info → wbportfolio-1.59.4.dist-info}/licenses/LICENSE +0 -0
@@ -2,6 +2,7 @@ from contextlib import suppress
2
2
  from datetime import date
3
3
 
4
4
  from pandas._libs.tslibs.offsets import BDay
5
+ from rest_framework.reverse import reverse
5
6
  from wbcore import serializers as wb_serializers
6
7
  from wbcore.contrib.currency.serializers import CurrencyRepresentationSerializer
7
8
  from wbcore.contrib.icons import WBIcon
@@ -11,9 +12,11 @@ from wbcore.metadata.configs.buttons.view_config import ButtonViewConfig
11
12
  from wbcore.metadata.configs.display.instance_display.shortcuts import (
12
13
  create_simple_display,
13
14
  )
15
+ from wbfdm.models import Instrument
16
+ from wbfdm.serializers import InvestableUniverseRepresentationSerializer
14
17
 
15
18
  from wbportfolio.models import AssetPosition, Portfolio
16
- from wbportfolio.serializers import RebalancerModelSerializer
19
+ from wbportfolio.serializers import PortfolioRepresentationSerializer, RebalancerModelSerializer
17
20
  from wbportfolio.viewsets.configs.display.rebalancing import RebalancerDisplayConfig
18
21
 
19
22
 
@@ -32,6 +35,28 @@ class CreateModelPortfolioSerializer(wb_serializers.ModelSerializer):
32
35
  )
33
36
 
34
37
 
38
+ class AdjustQuoteSerializer(wb_serializers.Serializer):
39
+ old_quote = wb_serializers.PrimaryKeyRelatedField(queryset=Instrument.objects.all())
40
+ _old_quote = InvestableUniverseRepresentationSerializer(source="old_quote")
41
+
42
+ new_quote = wb_serializers.PrimaryKeyRelatedField(queryset=Instrument.objects.all())
43
+ _new_quote = InvestableUniverseRepresentationSerializer(
44
+ source="new_quote",
45
+ optional_get_parameters={"old_quote": "sibling_of"},
46
+ depends_on=[{"field": "old_quote", "options": {}}],
47
+ )
48
+
49
+ only_portfolios = wb_serializers.PrimaryKeyRelatedField(queryset=Portfolio.objects.all(), required=False)
50
+ _only_portfolios = PortfolioRepresentationSerializer(
51
+ source="only_portfolios",
52
+ optional_get_parameters={"old_quote": "invests_in"},
53
+ depends_on=[{"field": "new_quote", "options": {}}],
54
+ many=True,
55
+ )
56
+
57
+ adjust_after = wb_serializers.DateField(required=False)
58
+
59
+
35
60
  def _get_portfolio_start_end_serializer_class(portfolio):
36
61
  today = date.today()
37
62
 
@@ -60,6 +85,25 @@ def _get_rebalance_serializer_class(portfolio):
60
85
 
61
86
 
62
87
  class PortfolioButtonConfig(ButtonViewConfig):
88
+ def get_custom_buttons(self) -> set:
89
+ return {
90
+ bt.ActionButton(
91
+ method=RequestType.POST,
92
+ identifiers=("wbportfolio:portfolio",),
93
+ endpoint=reverse("wbportfolio:portfolio-adjustquote", args=[], request=self.request),
94
+ label="Adjust quote",
95
+ serializer=AdjustQuoteSerializer,
96
+ action_label="Action triggered",
97
+ title="Adjust Quote",
98
+ instance_display=create_simple_display(
99
+ [
100
+ ["old_quote", "new_quote", "adjust_after"],
101
+ ["only_portfolios", "only_portfolios", "only_portfolios"],
102
+ ]
103
+ ),
104
+ ),
105
+ }
106
+
63
107
  def get_custom_instance_buttons(self):
64
108
  admin_buttons = [
65
109
  bt.ActionButton(
@@ -1,15 +1,18 @@
1
+ from rest_framework.reverse import reverse
1
2
  from wbcore.contrib.icons import WBIcon
2
3
  from wbcore.metadata.configs import buttons as bt
3
4
  from wbcore.metadata.configs.buttons.view_config import ButtonViewConfig
4
5
  from wbfdm.viewsets.configs.buttons.instruments import InstrumentButtonViewConfig
5
6
 
7
+ from wbportfolio.models import Product
8
+
6
9
 
7
10
  class ProductButtonConfig(ButtonViewConfig):
8
11
  def get_custom_list_instance_buttons(self):
9
12
  return self.get_custom_instance_buttons()
10
13
 
11
14
  def get_custom_instance_buttons(self):
12
- return {
15
+ buttons = [
13
16
  bt.DropDownButton(
14
17
  label="Commission",
15
18
  icon=WBIcon.UNFOLD.icon,
@@ -35,7 +38,34 @@ class ProductButtonConfig(ButtonViewConfig):
35
38
  ),
36
39
  ],
37
40
  ),
38
- }
41
+ ]
42
+ if product_id := self.view.kwargs.get("pk", None):
43
+ product = Product.objects.get(id=product_id)
44
+ report_buttons = []
45
+ for report in product.reports.filter(is_active=True):
46
+ tmp_buttons = []
47
+ if primary_version := report.primary_version:
48
+ tmp_buttons.append(
49
+ bt.HyperlinkButton(
50
+ label="Public Report",
51
+ endpoint=reverse(
52
+ "public_report:report_version", args=[primary_version.lookup], request=self.request
53
+ ),
54
+ ),
55
+ )
56
+ if self.request.user.profile.is_internal or self.request.user.is_superuser:
57
+ tmp_buttons.append(
58
+ bt.WidgetButton(
59
+ label="Widget",
60
+ endpoint=reverse("wbreport:report-detail", args=[report.id], request=self.request),
61
+ ),
62
+ )
63
+ if tmp_buttons:
64
+ report_buttons.append(bt.DropDownButton(label=str(report), buttons=tmp_buttons))
65
+ if report_buttons:
66
+ buttons.append(bt.DropDownButton(label="Reports", buttons=report_buttons))
67
+
68
+ return set(buttons)
39
69
 
40
70
 
41
71
  class ProductCustomerButtonConfig(ButtonViewConfig):
@@ -19,9 +19,9 @@ from .claim import (
19
19
  from .custodians import CustodianDisplayConfig
20
20
 
21
21
  from .fees import (
22
- FeesAggregatedPortfolioPandasDisplayConfig,
22
+ FeesAggregatedProductPandasDisplayConfig,
23
23
  FeesDisplayConfig,
24
- FeesPortfolioDisplayConfig,
24
+ FeesProductDisplayConfig,
25
25
  )
26
26
  from .portfolios import (
27
27
  PortfolioDisplayConfig,
@@ -49,10 +49,7 @@ from .trades import (
49
49
  SubscriptionRedemptionDisplayConfig,
50
50
  TradeDisplayConfig,
51
51
  TradePortfolioDisplayConfig,
52
- TradeTradeProposalDisplayConfig,
53
52
  )
54
- from .trade_proposals import TradeProposalDisplayConfig
55
- from .transactions import TransactionDisplayConfig, TransactionPortfolioDisplayConfig
56
53
  from .portfolio_relationship import (
57
54
  PortfolioInstrumentPreferredClassificationThroughDisplayConfig,
58
55
  InstrumentPortfolioThroughPortfolioModelDisplayConfig,
@@ -234,22 +234,9 @@ class CompositionModelPortfolioPandasDisplayConfig(DisplayViewConfig):
234
234
 
235
235
  class DistributionTableDisplayConfig(DisplayViewConfig):
236
236
  def get_list_display(self) -> Optional[dp.ListDisplay]:
237
- if group_by := self.request.GET.get("group_by", ""):
238
- group_by = group_by.title().replace("_", " ")
239
-
240
- if group_by != "Industry":
241
- fields = [
242
- dp.Field(key="aggregate_field", label=group_by),
243
- dp.Field(key="weighting", label="Weight"),
244
- ]
245
- else:
246
- fields = []
247
- for level_rep in self.view.classification_levels_representation:
248
- fields.append(dp.Field(key=level_rep, label=level_rep))
249
- fields.extend(
250
- [
251
- dp.Field(key="equity", label="Equity"),
252
- dp.Field(key="weighting", label="Weight"),
253
- ]
254
- )
255
- return dp.ListDisplay(fields=tuple(fields))
237
+ fields = [
238
+ dp.Field(key="weighting", label="Weighting"),
239
+ ]
240
+ for k, v in reversed(self.view.columns_map.items()):
241
+ fields.append(dp.Field(key=k, label=v))
242
+ return dp.ListDisplay(fields=fields)
@@ -55,7 +55,7 @@ class FeesDisplayConfig(DisplayViewConfig):
55
55
  )
56
56
 
57
57
 
58
- class FeesPortfolioDisplayConfig(DisplayViewConfig):
58
+ class FeesProductDisplayConfig(DisplayViewConfig):
59
59
  def get_list_display(self) -> Optional[dp.ListDisplay]:
60
60
  return dp.ListDisplay(
61
61
  fields=[
@@ -98,7 +98,7 @@ class FeesPortfolioDisplayConfig(DisplayViewConfig):
98
98
  dp.Field(key="calculated", label="Calculated"),
99
99
  dp.Field(key="currency_fx_rate", label="FX rate", show="open"),
100
100
  dp.Field(key="currency", label="Currency", show="open"),
101
- dp.Field(key="linked_product", label="Product", show="open"),
101
+ dp.Field(key="product", label="Product", show="open"),
102
102
  ],
103
103
  ),
104
104
  ]
@@ -117,7 +117,7 @@ class FeesPortfolioDisplayConfig(DisplayViewConfig):
117
117
  )
118
118
 
119
119
 
120
- class FeesAggregatedPortfolioPandasDisplayConfig(DisplayViewConfig):
120
+ class FeesAggregatedProductPandasDisplayConfig(DisplayViewConfig):
121
121
  def get_list_display(self) -> Optional[dp.ListDisplay]:
122
122
  return dp.ListDisplay(
123
123
  fields=[
@@ -51,9 +51,9 @@ class PortfolioDisplayConfig(DisplayViewConfig):
51
51
  key=None,
52
52
  children=[
53
53
  dp.Field(key="automatic_rebalancer", label="Automatic Rebalancer"),
54
- dp.Field(key="last_trade_proposal_date", label="Last Rebalance", width=Unit.PIXEL(250)),
54
+ dp.Field(key="last_order_proposal_date", label="Last Rebalance", width=Unit.PIXEL(250)),
55
55
  dp.Field(
56
- key="next_expected_trade_proposal_date",
56
+ key="next_expected_order_proposal_date",
57
57
  label="Next Rebalancing",
58
58
  width=Unit.PIXEL(250),
59
59
  show="open",
@@ -126,15 +126,15 @@ class PortfolioDisplayConfig(DisplayViewConfig):
126
126
  },
127
127
  ),
128
128
  Page(
129
- title="Trade",
129
+ title="Order",
130
130
  layouts={
131
131
  default(): dp.Layout(
132
132
  grid_template_areas=[
133
- ["trade_proposals"],
133
+ ["order_proposals"],
134
134
  ],
135
135
  grid_template_rows=["auto"],
136
136
  inlines=[
137
- dp.Inline(key="trade_proposals", endpoint="trade_proposals"),
137
+ dp.Inline(key="order_proposals", endpoint="order_proposals"),
138
138
  ],
139
139
  )
140
140
  },
@@ -124,7 +124,7 @@ class ProductDisplayConfig(DisplayViewConfig):
124
124
  return create_simple_display(
125
125
  [
126
126
  [repeat_field(2, "name"), repeat_field(2, "name_repr")],
127
- ["inception_date", "isin", "ticker", "id_repr"],
127
+ ["inception_date", "delisted_date", "isin", "id_repr"],
128
128
  ["share_price", "issue_price", "initial_high_water_mark", "currency"],
129
129
  [repeat_field(2, "bank"), repeat_field(2, "parent")],
130
130
  [repeat_field(4, "tags")],
@@ -11,7 +11,7 @@ class RebalancerDisplayConfig(DisplayViewConfig):
11
11
  fields=[
12
12
  dp.Field(key="portfolio", label="Portfolio"),
13
13
  dp.Field(key="rebalancing_model", label="Rebalancing Model"),
14
- dp.Field(key="approve_trade_proposal_automatically", label="Approve automatically"),
14
+ dp.Field(key="apply_order_proposal_automatically", label="Approve automatically"),
15
15
  dp.Field(key="frequency_repr", label="Frequency"),
16
16
  dp.Field(key="activation_date", label="Activation Date"),
17
17
  ],
@@ -20,7 +20,7 @@ class RebalancerDisplayConfig(DisplayViewConfig):
20
20
  def get_instance_display(self) -> Display:
21
21
  return create_simple_display(
22
22
  [
23
- ["rebalancing_model", "approve_trade_proposal_automatically"],
23
+ ["rebalancing_model", "apply_order_proposal_automatically"],
24
24
  ["frequency", "activation_date"],
25
25
  ["rebalancing_dates", "rebalancing_dates"],
26
26
  ]
@@ -49,14 +49,14 @@ class AccountReconciliationLineDisplayViewConfig(DisplayViewConfig):
49
49
  ]
50
50
  editable = [dp.FormattingRule(style={"fontWeight": "bold"})]
51
51
  equal = [dp.FormattingRule(condition=("==", False, "is_equal"), style={"backgroundColor": "orange"})]
52
- borderLeft = [
52
+ border_left = [
53
53
  dp.FormattingRule(
54
54
  style={
55
55
  "borderLeft": "1px solid #bdc3c7",
56
56
  }
57
57
  )
58
58
  ]
59
- borderRight = [
59
+ border_right = [
60
60
  dp.FormattingRule(
61
61
  style={
62
62
  "borderRight": "1px solid #bdc3c7",
@@ -111,7 +111,7 @@ class AccountReconciliationLineDisplayViewConfig(DisplayViewConfig):
111
111
  key="shares_external",
112
112
  label="Shares",
113
113
  width=90,
114
- formatting_rules=[*equal, *editable, *borderLeft],
114
+ formatting_rules=[*equal, *editable, *border_left],
115
115
  ),
116
116
  dp.Field(
117
117
  key="nominal_value_external",
@@ -128,7 +128,7 @@ class AccountReconciliationLineDisplayViewConfig(DisplayViewConfig):
128
128
  key="assets_under_management_external",
129
129
  label="AuM",
130
130
  width=120,
131
- formatting_rules=[*equal, *borderRight],
131
+ formatting_rules=[*equal, *border_right],
132
132
  ),
133
133
  ],
134
134
  ),
@@ -1,6 +1,5 @@
1
1
  from typing import Optional
2
2
 
3
- from django.shortcuts import get_object_or_404
4
3
  from wbcore.contrib.color.enums import WBColor
5
4
  from wbcore.contrib.icons import WBIcon
6
5
  from wbcore.enums import Unit
@@ -12,8 +11,6 @@ from wbcore.metadata.configs.display.instance_display.shortcuts import (
12
11
  from wbcore.metadata.configs.display.instance_display.utils import repeat_field
13
12
  from wbcore.metadata.configs.display.view_config import DisplayViewConfig
14
13
 
15
- from wbportfolio.models import Trade, TradeProposal
16
-
17
14
  NEGATIVE_RED_FORMATTING = [
18
15
  dp.FormattingRule(
19
16
  style={
@@ -37,63 +34,6 @@ SHARE_FORMATTING = dp.Formatting(
37
34
  ],
38
35
  )
39
36
 
40
- TRADE_STATUS_LEGENDS = dp.Legend(
41
- key="status",
42
- items=[
43
- dp.LegendItem(
44
- icon=WBColor.RED_LIGHT.value,
45
- label=Trade.Status.FAILED.label,
46
- value=Trade.Status.FAILED.value,
47
- ),
48
- dp.LegendItem(
49
- icon=WBColor.BLUE_LIGHT.value,
50
- label=Trade.Status.DRAFT.label,
51
- value=Trade.Status.DRAFT.value,
52
- ),
53
- dp.LegendItem(
54
- icon=WBColor.YELLOW_LIGHT.value,
55
- label=Trade.Status.SUBMIT.label,
56
- value=Trade.Status.SUBMIT.value,
57
- ),
58
- dp.LegendItem(
59
- icon=WBColor.GREEN_LIGHT.value,
60
- label=Trade.Status.EXECUTED.label,
61
- value=Trade.Status.EXECUTED.value,
62
- ),
63
- dp.LegendItem(
64
- icon=WBColor.GREEN.value,
65
- label=Trade.Status.CONFIRMED.label,
66
- value=Trade.Status.CONFIRMED.value,
67
- ),
68
- ],
69
- )
70
-
71
- TRADE_STATUS_FORMATTING = dp.Formatting(
72
- column="status",
73
- formatting_rules=[
74
- dp.FormattingRule(
75
- style={"backgroundColor": WBColor.RED_LIGHT.value},
76
- condition=("==", Trade.Status.FAILED.value),
77
- ),
78
- dp.FormattingRule(
79
- style={"backgroundColor": WBColor.BLUE_LIGHT.value},
80
- condition=("==", Trade.Status.DRAFT.value),
81
- ),
82
- dp.FormattingRule(
83
- style={"backgroundColor": WBColor.YELLOW_LIGHT.value},
84
- condition=("==", Trade.Status.SUBMIT.value),
85
- ),
86
- dp.FormattingRule(
87
- style={"backgroundColor": WBColor.GREEN_LIGHT.value},
88
- condition=("==", Trade.Status.EXECUTED.value),
89
- ),
90
- dp.FormattingRule(
91
- style={"backgroundColor": WBColor.GREEN.value},
92
- condition=("==", Trade.Status.CONFIRMED.value),
93
- ),
94
- ],
95
- )
96
-
97
37
 
98
38
  class TradeDisplayConfig(DisplayViewConfig):
99
39
  def get_list_display(self) -> Optional[dp.ListDisplay]:
@@ -145,8 +85,7 @@ class TradeDisplayConfig(DisplayViewConfig):
145
85
  ),
146
86
  ),
147
87
  ],
148
- legends=[TRADE_STATUS_LEGENDS],
149
- formatting=[SHARE_FORMATTING, TRADE_STATUS_FORMATTING],
88
+ formatting=[SHARE_FORMATTING],
150
89
  )
151
90
 
152
91
  def get_instance_display(self) -> Display:
@@ -285,130 +224,3 @@ class SubscriptionRedemptionDisplayConfig(TradeDisplayConfig):
285
224
 
286
225
  class TradePortfolioDisplayConfig(TradeDisplayConfig):
287
226
  pass
288
-
289
-
290
- class TradeTradeProposalDisplayConfig(DisplayViewConfig):
291
- def get_list_display(self) -> Optional[dp.ListDisplay]:
292
- trade_proposal = get_object_or_404(TradeProposal, pk=self.view.kwargs.get("trade_proposal_id", None))
293
- fields = [
294
- dp.Field(
295
- label="Instrument",
296
- open_by_default=True,
297
- key=None,
298
- children=[
299
- dp.Field(key="underlying_instrument", label="Name", width=Unit.PIXEL(250)),
300
- dp.Field(key="underlying_instrument_isin", label="ISIN", width=Unit.PIXEL(125)),
301
- dp.Field(key="underlying_instrument_ticker", label="Ticker", width=Unit.PIXEL(100)),
302
- dp.Field(
303
- key="underlying_instrument_refinitiv_identifier_code", label="RIC", width=Unit.PIXEL(100)
304
- ),
305
- dp.Field(key="underlying_instrument_instrument_type", label="Asset Class", width=Unit.PIXEL(125)),
306
- ],
307
- ),
308
- dp.Field(
309
- label="Weight",
310
- open_by_default=False,
311
- key=None,
312
- children=[
313
- dp.Field(key="effective_weight", label="Effective Weight", show="open", width=Unit.PIXEL(150)),
314
- dp.Field(key="target_weight", label="Target Weight", show="open", width=Unit.PIXEL(150)),
315
- dp.Field(
316
- key="weighting",
317
- label="Delta Weight",
318
- formatting_rules=[
319
- dp.FormattingRule(
320
- style={"color": WBColor.RED_DARK.value, "fontWeight": "bold"},
321
- condition=("<", 0),
322
- ),
323
- dp.FormattingRule(
324
- style={"color": WBColor.GREEN_DARK.value, "fontWeight": "bold"},
325
- condition=(">", 0),
326
- ),
327
- ],
328
- width=Unit.PIXEL(150),
329
- ),
330
- ],
331
- ),
332
- ]
333
- if not trade_proposal.portfolio.only_weighting:
334
- fields.append(
335
- dp.Field(
336
- label="Shares",
337
- open_by_default=False,
338
- key=None,
339
- children=[
340
- dp.Field(key="effective_shares", label="Effective Shares", show="open", width=Unit.PIXEL(150)),
341
- dp.Field(key="target_shares", label="Target Shares", show="open", width=Unit.PIXEL(150)),
342
- dp.Field(
343
- key="shares",
344
- label="Shares",
345
- formatting_rules=[
346
- dp.FormattingRule(
347
- style={"color": WBColor.RED_DARK.value, "fontWeight": "bold"},
348
- condition=("<", 0),
349
- ),
350
- dp.FormattingRule(
351
- style={"color": WBColor.GREEN_DARK.value, "fontWeight": "bold"},
352
- condition=(">", 0),
353
- ),
354
- ],
355
- width=Unit.PIXEL(150),
356
- ),
357
- ],
358
- )
359
- )
360
- fields.append(
361
- dp.Field(
362
- label="Information",
363
- open_by_default=False,
364
- key=None,
365
- children=[
366
- dp.Field(
367
- key="transaction_subtype",
368
- label="Direction",
369
- formatting_rules=[
370
- dp.FormattingRule(
371
- style={"color": WBColor.RED_DARK.value, "fontWeight": "bold"},
372
- condition=("==", Trade.Type.SELL.name),
373
- ),
374
- dp.FormattingRule(
375
- style={"color": WBColor.RED_DARK.value, "fontWeight": "bold"},
376
- condition=("==", Trade.Type.DECREASE.name),
377
- ),
378
- dp.FormattingRule(
379
- style={"color": WBColor.GREEN_DARK.value, "fontWeight": "bold"},
380
- condition=("==", Trade.Type.INCREASE.name),
381
- ),
382
- dp.FormattingRule(
383
- style={"color": WBColor.GREEN_DARK.value, "fontWeight": "bold"},
384
- condition=("==", Trade.Type.BUY.name),
385
- ),
386
- dp.FormattingRule(
387
- style={"color": WBColor.GREY.value, "fontWeight": "bold"},
388
- condition=("==", Trade.Type.NO_CHANGE.name),
389
- ),
390
- ],
391
- width=Unit.PIXEL(125),
392
- ),
393
- dp.Field(key="comment", label="Comment", width=Unit.PIXEL(250)),
394
- dp.Field(key="order", label="Order", show="open", width=Unit.PIXEL(100)),
395
- ],
396
- )
397
- )
398
- return dp.ListDisplay(
399
- fields=fields,
400
- legends=[TRADE_STATUS_LEGENDS],
401
- formatting=[TRADE_STATUS_FORMATTING],
402
- )
403
-
404
- def get_instance_display(self) -> Display:
405
- trade_proposal = get_object_or_404(TradeProposal, pk=self.view.kwargs.get("trade_proposal_id", None))
406
-
407
- fields = [
408
- ["company", "security", "underlying_instrument"],
409
- ["effective_weight", "target_weight", "weighting"],
410
- ]
411
- if not trade_proposal.portfolio.only_weighting:
412
- fields.append(["effective_shares", "target_shares", "shares"])
413
- fields.append([repeat_field(3, "comment")])
414
- return create_simple_display(fields)
@@ -28,10 +28,10 @@ from .claim import (
28
28
 
29
29
  from .custodians import CustodianEndpointConfig
30
30
  from .fees import (
31
- FeesAggregatedPortfolioPandasEndpointConfig,
32
- FeesPortfolioEndpointConfig,
31
+ FeesAggregatedProductPandasEndpointConfig,
32
+ FeesProductEndpointConfig,
33
33
  )
34
- from .fees import FeesAggregatedPortfolioPandasEndpointConfig, FeesPortfolioEndpointConfig, FeeEndpointConfig
34
+ from .fees import FeesAggregatedProductPandasEndpointConfig, FeesProductEndpointConfig, FeeEndpointConfig
35
35
 
36
36
  from .portfolios import (
37
37
  PortfolioEndpointConfig,
@@ -62,12 +62,8 @@ from .trades import (
62
62
  TradeEndpointConfig,
63
63
  TradeInstrumentEndpointConfig,
64
64
  TradePortfolioEndpointConfig,
65
- TradeProposalEndpointConfig,
66
- TradeProposalPortfolioEndpointConfig,
67
- TradeTradeProposalEndpointConfig,
68
65
  SubscriptionRedemptionEndpointConfig,
69
66
  )
70
- from .transactions import TransactionEndpointConfig, TransactionPortfolioEndpointConfig
71
67
  from .portfolio_relationship import (
72
68
  PortfolioInstrumentPreferredClassificationThroughEndpointConfig,
73
69
  InstrumentPortfolioThroughPortfolioModelEndpointConfig,
@@ -6,9 +6,9 @@ class FeeEndpointConfig(EndpointViewConfig):
6
6
  return None
7
7
 
8
8
 
9
- class FeesPortfolioEndpointConfig(FeeEndpointConfig):
9
+ class FeesProductEndpointConfig(FeeEndpointConfig):
10
10
  pass
11
11
 
12
12
 
13
- class FeesAggregatedPortfolioPandasEndpointConfig(EndpointViewConfig):
13
+ class FeesAggregatedProductPandasEndpointConfig(EndpointViewConfig):
14
14
  pass
@@ -1,11 +1,6 @@
1
- from contextlib import suppress
2
-
3
- from django.shortcuts import get_object_or_404
4
1
  from rest_framework.reverse import reverse
5
2
  from wbcore.metadata.configs.endpoints import EndpointViewConfig
6
3
 
7
- from wbportfolio.models import TradeProposal
8
-
9
4
 
10
5
  class TradeEndpointConfig(EndpointViewConfig):
11
6
  def get_endpoint(self, **kwargs):
@@ -50,42 +45,6 @@ class CustodianDistributionInstrumentEndpointConfig(EndpointViewConfig):
50
45
  )
51
46
 
52
47
 
53
- class TradeProposalEndpointConfig(EndpointViewConfig):
54
- def get_delete_endpoint(self, **kwargs):
55
- if pk := self.view.kwargs.get("pk", None):
56
- trade_proposal = get_object_or_404(TradeProposal, pk=pk)
57
- if trade_proposal.status == TradeProposal.Status.DRAFT:
58
- return super().get_endpoint()
59
- return None
60
-
61
-
62
- class TradeProposalPortfolioEndpointConfig(TradeProposalEndpointConfig):
63
- def get_endpoint(self, **kwargs):
64
- return reverse(
65
- "wbportfolio:portfolio-tradeproposal-list", args=[self.view.kwargs["portfolio_id"]], request=self.request
66
- )
67
-
68
-
69
- class TradeTradeProposalEndpointConfig(EndpointViewConfig):
70
- def get_endpoint(self, **kwargs):
71
- if trade_proposal_id := self.view.kwargs.get("trade_proposal_id", None):
72
- trade_proposal = TradeProposal.objects.get(id=trade_proposal_id)
73
- if trade_proposal.status == TradeProposal.Status.DRAFT:
74
- return reverse(
75
- "wbportfolio:tradeproposal-trade-list",
76
- args=[self.view.kwargs["trade_proposal_id"]],
77
- request=self.request,
78
- )
79
- return None
80
-
81
- def get_delete_endpoint(self, **kwargs):
82
- with suppress(AttributeError, AssertionError):
83
- trade = self.view.get_object()
84
- if trade._effective_weight: # we make sure trade with a valid effective position cannot be deleted
85
- return None
86
- return super().get_delete_endpoint(**kwargs)
87
-
88
-
89
48
  class SubscriptionRedemptionEndpointConfig(TradeEndpointConfig):
90
49
  def get_endpoint(self, **kwargs):
91
50
  return reverse("wbportfolio:subscriptionredemption-list", args=[], request=self.request)
@@ -25,6 +25,6 @@ from .products import PRODUCT_MENUITEM, PRODUCTCUSTOMER_MENUITEM
25
25
  from .registers import REGISTER_MENUITEM
26
26
  from .roles import PORTFOLIOROLE_MENUITEM
27
27
  from .trades import SUBSCRIPTION_REDEMPTION_MENUITEM, TRADE_MENUITEM
28
- from .transactions import TRANSACTION_MENUITEM
29
28
  from .portfolio_cash_flow import PORTFOLIO_DAILY_CASH_FLOW
30
29
  from .reconciliations import ACCOUNT_RECONCILIATION_MENU_ITEM
30
+ from .orders import OrderProposalMenuItem
@@ -0,0 +1,11 @@
1
+ from wbcore.menus import ItemPermission, MenuItem
2
+ from wbcore.permissions.shortcuts import is_internal_user
3
+
4
+ OrderProposalMenuItem = MenuItem(
5
+ label="Order Proposals",
6
+ endpoint="wbportfolio:orderproposal-list",
7
+ endpoint_get_parameters={"waiting_for_input": True},
8
+ permission=ItemPermission(
9
+ permissions=["wbportfolio.view_orderproposal"], method=lambda request: is_internal_user(request.user)
10
+ ),
11
+ )
@@ -27,8 +27,8 @@ from .claim import (
27
27
  from .custodians import CustodianTitleConfig
28
28
 
29
29
  from .fees import (
30
- FeesAggregatedPortfolioTitleConfig,
31
- FeesPortfolioTitleConfig,
30
+ FeesAggregatedProductTitleConfig,
31
+ FeesProductTitleConfig,
32
32
  FeesTitleConfig,
33
33
  )
34
34
 
@@ -60,6 +60,5 @@ from .trades import (
60
60
  TradePortfolioTitleConfig,
61
61
  TradeTitleConfig,
62
62
  )
63
- from .transactions import TransactionPortfolioTitleConfig
64
63
  from .esg import ESGMetricAggregationPortfolioPandasTitleConfig
65
64
  from .assets_and_net_new_money_progression import AssetAndNetNewMoneyProgressionChartTitleConfig