wbportfolio 1.52.1__py2.py3-none-any.whl → 1.52.2rc0__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 (82) hide show
  1. wbportfolio/admin/__init__.py +1 -1
  2. wbportfolio/admin/transactions/__init__.py +0 -1
  3. wbportfolio/admin/transactions/dividends.py +40 -4
  4. wbportfolio/admin/transactions/fees.py +24 -14
  5. wbportfolio/admin/transactions/trades.py +34 -12
  6. wbportfolio/defaults/fees/default.py +7 -15
  7. wbportfolio/factories/__init__.py +0 -1
  8. wbportfolio/factories/dividends.py +8 -3
  9. wbportfolio/factories/fees.py +8 -4
  10. wbportfolio/factories/trades.py +10 -3
  11. wbportfolio/filters/transactions/__init__.py +1 -2
  12. wbportfolio/filters/transactions/fees.py +5 -10
  13. wbportfolio/filters/transactions/trades.py +17 -8
  14. wbportfolio/filters/transactions/utils.py +42 -0
  15. wbportfolio/import_export/handlers/dividend.py +7 -7
  16. wbportfolio/import_export/handlers/fees.py +11 -21
  17. wbportfolio/import_export/handlers/trade.py +5 -7
  18. wbportfolio/import_export/parsers/jpmorgan/fees.py +2 -2
  19. wbportfolio/import_export/parsers/leonteq/customer_trade.py +5 -5
  20. wbportfolio/import_export/parsers/leonteq/fees.py +11 -7
  21. wbportfolio/import_export/parsers/leonteq/trade.py +0 -5
  22. wbportfolio/import_export/parsers/natixis/d1_fees.py +2 -2
  23. wbportfolio/import_export/parsers/natixis/dividend.py +4 -9
  24. wbportfolio/import_export/parsers/natixis/fees.py +7 -9
  25. wbportfolio/import_export/parsers/sg_lux/customer_trade_pending_slk.py +1 -1
  26. wbportfolio/import_export/parsers/sg_lux/fees.py +2 -2
  27. wbportfolio/import_export/parsers/sg_lux/perf_fees.py +2 -2
  28. wbportfolio/import_export/parsers/sg_lux/utils.py +2 -2
  29. wbportfolio/import_export/parsers/ubs/api/fees.py +2 -2
  30. wbportfolio/import_export/parsers/vontobel/customer_trade.py +2 -3
  31. wbportfolio/import_export/parsers/vontobel/historical_customer_trade.py +0 -1
  32. wbportfolio/import_export/parsers/vontobel/management_fees.py +7 -7
  33. wbportfolio/import_export/parsers/vontobel/performance_fees.py +3 -3
  34. wbportfolio/jinja2/wbportfolio/sql/aum_nnm.sql +2 -2
  35. wbportfolio/migrations/0059_fees_unique_fees.py +1 -1
  36. wbportfolio/migrations/0077_remove_transaction_currency_and_more.py +622 -0
  37. wbportfolio/models/mixins/liquidity_stress_test.py +3 -3
  38. wbportfolio/models/transactions/__init__.py +0 -2
  39. wbportfolio/models/transactions/claim.py +1 -1
  40. wbportfolio/models/transactions/dividends.py +41 -5
  41. wbportfolio/models/transactions/fees.py +55 -22
  42. wbportfolio/models/transactions/trade_proposals.py +25 -3
  43. wbportfolio/models/transactions/trades.py +111 -50
  44. wbportfolio/models/transactions/transactions.py +60 -156
  45. wbportfolio/serializers/signals.py +15 -10
  46. wbportfolio/serializers/transactions/__init__.py +0 -5
  47. wbportfolio/serializers/transactions/dividends.py +37 -9
  48. wbportfolio/serializers/transactions/fees.py +39 -10
  49. wbportfolio/serializers/transactions/trades.py +56 -16
  50. wbportfolio/tasks.py +2 -2
  51. wbportfolio/tests/conftest.py +2 -8
  52. wbportfolio/tests/models/test_imports.py +2 -7
  53. wbportfolio/tests/models/transactions/test_fees.py +7 -13
  54. wbportfolio/tests/models/transactions/test_trade_proposals.py +4 -2
  55. wbportfolio/urls.py +3 -6
  56. wbportfolio/viewsets/configs/buttons/mixins.py +2 -2
  57. wbportfolio/viewsets/configs/display/__init__.py +2 -3
  58. wbportfolio/viewsets/configs/display/fees.py +3 -3
  59. wbportfolio/viewsets/configs/endpoints/__init__.py +3 -4
  60. wbportfolio/viewsets/configs/endpoints/fees.py +2 -2
  61. wbportfolio/viewsets/configs/menu/__init__.py +0 -1
  62. wbportfolio/viewsets/configs/titles/__init__.py +2 -3
  63. wbportfolio/viewsets/configs/titles/fees.py +4 -8
  64. wbportfolio/viewsets/mixins.py +5 -1
  65. wbportfolio/viewsets/products.py +6 -6
  66. wbportfolio/viewsets/transactions/__init__.py +2 -7
  67. wbportfolio/viewsets/transactions/fees.py +22 -22
  68. {wbportfolio-1.52.1.dist-info → wbportfolio-1.52.2rc0.dist-info}/METADATA +1 -1
  69. {wbportfolio-1.52.1.dist-info → wbportfolio-1.52.2rc0.dist-info}/RECORD +71 -80
  70. wbportfolio/admin/transactions/transactions.py +0 -38
  71. wbportfolio/factories/transactions.py +0 -22
  72. wbportfolio/filters/transactions/transactions.py +0 -99
  73. wbportfolio/models/transactions/expiry.py +0 -7
  74. wbportfolio/serializers/transactions/expiry.py +0 -18
  75. wbportfolio/serializers/transactions/transactions.py +0 -85
  76. wbportfolio/viewsets/configs/display/transactions.py +0 -55
  77. wbportfolio/viewsets/configs/endpoints/transactions.py +0 -14
  78. wbportfolio/viewsets/configs/menu/transactions.py +0 -9
  79. wbportfolio/viewsets/configs/titles/transactions.py +0 -9
  80. wbportfolio/viewsets/transactions/transactions.py +0 -122
  81. {wbportfolio-1.52.1.dist-info → wbportfolio-1.52.2rc0.dist-info}/WHEEL +0 -0
  82. {wbportfolio-1.52.1.dist-info → wbportfolio-1.52.2rc0.dist-info}/licenses/LICENSE +0 -0
@@ -2,7 +2,6 @@ from datetime import timedelta
2
2
  from decimal import Decimal
3
3
 
4
4
  import pytest
5
- from wbfdm.factories import CashFactory
6
5
  from wbfdm.models import InstrumentPrice
7
6
 
8
7
  from wbportfolio.models import FeeCalculation, Fees, Product
@@ -11,19 +10,14 @@ from wbportfolio.models import FeeCalculation, Fees, Product
11
10
  def fees_calculation(price_id):
12
11
  price = InstrumentPrice.objects.get(id=price_id)
13
12
  product = Product.objects.get(id=price.instrument.id)
14
- cash = CashFactory.create(currency=product.currency)
15
13
  yield {
16
- "portfolio": product.primary_portfolio,
17
- "linked_product": product,
18
- "transaction_date": price.date,
14
+ "product": product,
15
+ "fee_date": price.date,
19
16
  "transaction_subtype": Fees.Type.MANAGEMENT,
20
- "underlying_instrument": cash,
21
17
  "currency": product.currency,
22
18
  "calculated": True,
23
19
  "total_value": price.net_value,
24
- "total_value_fx_portfolio": price.net_value,
25
20
  "total_value_gross": price.net_value,
26
- "total_value_gross_fx_portfolio": price.net_value,
27
21
  }
28
22
 
29
23
 
@@ -38,14 +32,14 @@ class TestFeesModel:
38
32
  ) # no matter if estimated or not, we expect this fee to be on the resulting queryset
39
33
  calculated_fees_d1 = fees_factory.create( # there will be a real fee for that date, type and product, so this will be filtered out
40
34
  calculated=True,
41
- linked_product=fees_d0.linked_product,
42
- transaction_date=(fees_d0.transaction_date + timedelta(days=1)),
35
+ product=fees_d0.product,
36
+ fee_date=(fees_d0.fee_date + timedelta(days=1)),
43
37
  transaction_subtype=fees_d0.transaction_subtype,
44
38
  )
45
39
  real_fees_d1 = fees_factory.create(
46
40
  calculated=False,
47
- linked_product=calculated_fees_d1.linked_product,
48
- transaction_date=calculated_fees_d1.transaction_date,
41
+ product=calculated_fees_d1.product,
42
+ fee_date=calculated_fees_d1.fee_date,
49
43
  transaction_subtype=calculated_fees_d1.transaction_subtype,
50
44
  )
51
45
 
@@ -61,6 +55,6 @@ class TestFeesModel:
61
55
  price = instrument_price_factory.create(instrument=product) # post save must be called to compute fees
62
56
 
63
57
  fees = Fees.objects.get(
64
- linked_product=product, fee_date=price.date, calculated=True, transaction_subtype=Fees.Type.MANAGEMENT
58
+ product=product, fee_date=price.date, calculated=True, transaction_subtype=Fees.Type.MANAGEMENT
65
59
  )
66
60
  assert fees.total_value == pytest.approx(price.net_value, rel=Decimal(1e-4))
@@ -250,7 +250,7 @@ class TestTradeProposal:
250
250
  assert t3.weighting == normalized_t3_weight
251
251
 
252
252
  # Test resetting trades
253
- def test_reset_trades(self, trade_proposal, instrument_factory, asset_position_factory):
253
+ def test_reset_trades(self, trade_proposal, instrument_factory, instrument_price_factory, asset_position_factory):
254
254
  """
255
255
  Verify trades are correctly reset based on effective and target portfolios.
256
256
  """
@@ -260,7 +260,6 @@ class TestTradeProposal:
260
260
  i1 = instrument_factory.create(currency=trade_proposal.portfolio.currency)
261
261
  i2 = instrument_factory.create(currency=trade_proposal.portfolio.currency)
262
262
  i3 = instrument_factory.create(currency=trade_proposal.portfolio.currency)
263
-
264
263
  # Build initial effective portfolio constituting only from two positions of i1 and i2
265
264
  asset_position_factory.create(
266
265
  portfolio=trade_proposal.portfolio, date=effective_date, underlying_instrument=i1, weighting=Decimal("0.7")
@@ -268,6 +267,9 @@ class TestTradeProposal:
268
267
  asset_position_factory.create(
269
268
  portfolio=trade_proposal.portfolio, date=effective_date, underlying_instrument=i2, weighting=Decimal("0.3")
270
269
  )
270
+ instrument_price_factory.create(instrument=i1, date=effective_date)
271
+ instrument_price_factory.create(instrument=i2, date=effective_date)
272
+ instrument_price_factory.create(instrument=i3, date=effective_date)
271
273
 
272
274
  # build the target portfolio
273
275
  target_portfolio = PortfolioDTO(
wbportfolio/urls.py CHANGED
@@ -30,7 +30,6 @@ router.register(
30
30
  router.register(r"portfoliorole", viewsets.PortfolioRoleModelViewSet, basename="portfoliorole")
31
31
 
32
32
 
33
- router.register(r"transaction", viewsets.TransactionModelViewSet, basename="transaction")
34
33
  router.register(r"fees", viewsets.FeesModelViewSet, basename="fees")
35
34
  router.register(r"trade", viewsets.TradeModelViewSet, basename="trade")
36
35
  router.register(
@@ -79,8 +78,6 @@ portfolio_router.register(
79
78
  )
80
79
  portfolio_router.register(r"asset", viewsets.AssetPositionPortfolioModelViewSet, basename="portfolio-asset")
81
80
  portfolio_router.register(r"contributor", viewsets.ContributorPortfolioChartView, basename="portfolio-contributor")
82
- portfolio_router.register(r"fees", viewsets.FeesPortfolioModelViewSet, basename="portfolio-fees")
83
- portfolio_router.register(r"transaction", viewsets.TransactionPortfolioModelViewSet, basename="portfolio-transaction")
84
81
  portfolio_router.register(r"trade", viewsets.TradePortfolioModelViewSet, basename="portfolio-trade")
85
82
  portfolio_router.register(
86
83
  r"instrument", viewsets.InstrumentPortfolioThroughPortfolioModelViewSet, basename="portfolio-instrument"
@@ -101,9 +98,7 @@ portfolio_router.register(
101
98
  viewsets.CompositionModelPortfolioPandasView,
102
99
  basename="portfolio-modelcompositionpandas",
103
100
  )
104
- portfolio_router.register(
105
- r"feesaggregated", viewsets.FeesAggregatedPortfolioPandasView, basename="portfolio-feesaggregated"
106
- )
101
+
107
102
  portfolio_router.register(
108
103
  r"distributionchart",
109
104
  viewsets.DistributionChartViewSet,
@@ -139,6 +134,8 @@ product_router = WBCoreRouter()
139
134
  product_router.register(r"nominalchart", viewsets.NominalProductChartView, basename="product-nominalchart")
140
135
  product_router.register(r"aumchart", viewsets.AUMProductChartView, basename="product-aumchart")
141
136
  product_router.register(r"claim", viewsets.ClaimProductModelViewSet, basename="product-claim")
137
+ product_router.register(r"feesaggregated", viewsets.FeesAggregatedProductPandasView, basename="product-feesaggregated")
138
+ product_router.register(r"fees", viewsets.FeesProductModelViewSet, basename="product-fees")
142
139
 
143
140
  # Subrouter for Trade Proposal
144
141
  trade_proposal_router = WBCoreRouter()
@@ -53,8 +53,8 @@ class InstrumentButtonMixin:
53
53
  bt.WidgetButton(key="portfolio_trades", label="Trades"),
54
54
  bt.WidgetButton(key="instrument_subscriptionsredemptions", label="Subscriptions/Redemptions"),
55
55
  bt.WidgetButton(key="instrument_trades", label="Trades (Implemented)"),
56
- bt.WidgetButton(key="portfolio_fees", label="Fees"),
57
- bt.WidgetButton(key="portfolio_aggregatedfees", label="Aggregated Fees"),
56
+ bt.WidgetButton(key="product_fees", label="Fees"),
57
+ bt.WidgetButton(key="product_aggregatedfees", label="Aggregated Fees"),
58
58
  bt.DropDownButton(
59
59
  label="Charts",
60
60
  icon=WBIcon.UNFOLD.icon,
@@ -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,
@@ -52,7 +52,6 @@ from .trades import (
52
52
  TradeTradeProposalDisplayConfig,
53
53
  )
54
54
  from .trade_proposals import TradeProposalDisplayConfig
55
- from .transactions import TransactionDisplayConfig, TransactionPortfolioDisplayConfig
56
55
  from .portfolio_relationship import (
57
56
  PortfolioInstrumentPreferredClassificationThroughDisplayConfig,
58
57
  InstrumentPortfolioThroughPortfolioModelDisplayConfig,
@@ -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=[
@@ -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,
@@ -67,7 +67,6 @@ from .trades import (
67
67
  TradeTradeProposalEndpointConfig,
68
68
  SubscriptionRedemptionEndpointConfig,
69
69
  )
70
- from .transactions import TransactionEndpointConfig, TransactionPortfolioEndpointConfig
71
70
  from .portfolio_relationship import (
72
71
  PortfolioInstrumentPreferredClassificationThroughEndpointConfig,
73
72
  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
@@ -25,6 +25,5 @@ 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
@@ -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
@@ -1,7 +1,5 @@
1
1
  from wbcore.metadata.configs.titles import TitleViewConfig
2
2
 
3
- from wbportfolio.models import Portfolio
4
-
5
3
 
6
4
  class FeesTitleConfig(TitleViewConfig):
7
5
  def get_list_title(self):
@@ -14,13 +12,11 @@ class FeesTitleConfig(TitleViewConfig):
14
12
  return "New Fees"
15
13
 
16
14
 
17
- class FeesPortfolioTitleConfig(FeesTitleConfig):
15
+ class FeesProductTitleConfig(FeesTitleConfig):
18
16
  def get_list_title(self):
19
- portfolio = Portfolio.objects.get(id=self.view.kwargs["portfolio_id"])
20
- return f"Fees: {portfolio.name}"
17
+ return f"Fees: {self.view.product}"
21
18
 
22
19
 
23
- class FeesAggregatedPortfolioTitleConfig(TitleViewConfig):
20
+ class FeesAggregatedProductTitleConfig(TitleViewConfig):
24
21
  def get_list_title(self):
25
- portfolio = Portfolio.objects.get(id=self.view.kwargs["portfolio_id"])
26
- return f"Aggregated Fees for {portfolio.name}"
22
+ return f"Aggregated Fees for {self.view.product}"
@@ -2,7 +2,7 @@ from django.shortcuts import get_object_or_404
2
2
  from django.utils.functional import cached_property
3
3
  from wbfdm.models import Instrument
4
4
 
5
- from wbportfolio.models import Portfolio, PortfolioRole
5
+ from wbportfolio.models import Portfolio, PortfolioRole, Product
6
6
 
7
7
 
8
8
  class UserPortfolioRequestPermissionMixin:
@@ -10,6 +10,10 @@ class UserPortfolioRequestPermissionMixin:
10
10
  def instrument(self) -> Instrument:
11
11
  return get_object_or_404(Instrument, pk=self.kwargs["instrument_id"])
12
12
 
13
+ @cached_property
14
+ def product(self) -> Instrument:
15
+ return get_object_or_404(Product, pk=self.kwargs["product_id"])
16
+
13
17
  @cached_property
14
18
  def portfolio(self) -> Portfolio:
15
19
  return get_object_or_404(Portfolio, id=self.kwargs["portfolio_id"])
@@ -317,16 +317,16 @@ class ProductPerformanceFeesModelViewSet(
317
317
  if date_lte is None and date_gte is None:
318
318
  date_gte, date_lte = get_start_and_end_date_from_date(date.today())
319
319
 
320
- fees = Fees.valid_objects.filter(linked_product=OuterRef("pk"))
320
+ fees = Fees.valid_objects.filter(product=OuterRef("pk"))
321
321
  if date_gte:
322
- fees = fees.filter(transaction_date__gte=date_gte)
322
+ fees = fees.filter(fee_date__gte=date_gte)
323
323
  if date_lte:
324
- fees = fees.filter(transaction_date__lte=date_lte)
324
+ fees = fees.filter(fee_date__lte=date_lte)
325
325
 
326
326
  management_fees = Coalesce(
327
327
  Subquery(
328
328
  fees.filter(transaction_subtype=Fees.Type.MANAGEMENT)
329
- .values("linked_product")
329
+ .values("product")
330
330
  .annotate(sum_management_fees=Sum("total_value"))
331
331
  .values("sum_management_fees")[:1],
332
332
  output_field=FloatField(),
@@ -340,7 +340,7 @@ class ProductPerformanceFeesModelViewSet(
340
340
  Q(transaction_subtype=Fees.Type.PERFORMANCE)
341
341
  | Q(transaction_subtype=Fees.Type.PERFORMANCE_CRYSTALIZED)
342
342
  )
343
- .values("linked_product")
343
+ .values("product")
344
344
  .annotate(sum_performance_fees_net=Sum("total_value"))
345
345
  .values("sum_performance_fees_net")[:1],
346
346
  output_field=FloatField(),
@@ -367,7 +367,7 @@ class ProductPerformanceFeesModelViewSet(
367
367
  sum_total_usd=F("sum_management_fees_usd") + F("sum_performance_fees_net_usd"),
368
368
  )
369
369
  .select_related("currency")
370
- .prefetch_related("transactions", "prices")
370
+ .prefetch_related("fees", "prices")
371
371
  )
372
372
  return qs
373
373
 
@@ -13,9 +13,9 @@ from .claim import (
13
13
  ProfitAndLossPandasView,
14
14
  )
15
15
  from .fees import (
16
- FeesAggregatedPortfolioPandasView,
16
+ FeesAggregatedProductPandasView,
17
17
  FeesModelViewSet,
18
- FeesPortfolioModelViewSet,
18
+ FeesProductModelViewSet,
19
19
  )
20
20
  from .rebalancing import RebalancingModelRepresentationViewSet, RebalancerRepresentationViewSet, RebalancerModelViewSet
21
21
  from .trade_proposals import (
@@ -34,8 +34,3 @@ from .trades import (
34
34
  TradeRepresentationViewSet,
35
35
  TradeTradeProposalModelViewSet,
36
36
  )
37
- from .transactions import (
38
- TransactionModelViewSet,
39
- TransactionPortfolioModelViewSet,
40
- TransactionRepresentationViewSet,
41
- )
@@ -8,28 +8,28 @@ from wbcore.pandas import fields as pf
8
8
  from wbcore.permissions.permissions import InternalUserPermissionMixin
9
9
  from wbcore.serializers import decorator
10
10
  from wbcore.utils.strings import format_number
11
+ from wbcore.viewsets import ModelViewSet
11
12
 
12
- from wbportfolio.filters import FeesAggregatedFilter, FeesFilter, FeesPortfolioFilterSet
13
+ from wbportfolio.filters import FeesAggregatedFilter, FeesFilter, FeesProductFilterSet
13
14
  from wbportfolio.models import Fees
14
15
  from wbportfolio.serializers import FeesModelSerializer
15
16
 
16
17
  from ..configs import (
17
18
  FeeEndpointConfig,
18
- FeesAggregatedPortfolioPandasDisplayConfig,
19
- FeesAggregatedPortfolioPandasEndpointConfig,
20
- FeesAggregatedPortfolioTitleConfig,
19
+ FeesAggregatedProductPandasDisplayConfig,
20
+ FeesAggregatedProductPandasEndpointConfig,
21
+ FeesAggregatedProductTitleConfig,
21
22
  FeesButtonConfig,
22
23
  FeesDisplayConfig,
23
- FeesPortfolioDisplayConfig,
24
- FeesPortfolioEndpointConfig,
25
- FeesPortfolioTitleConfig,
24
+ FeesProductDisplayConfig,
25
+ FeesProductEndpointConfig,
26
+ FeesProductTitleConfig,
26
27
  FeesTitleConfig,
27
28
  )
28
29
  from ..mixins import UserPortfolioRequestPermissionMixin
29
- from .transactions import TransactionModelViewSet
30
30
 
31
31
 
32
- class FeesModelViewSet(TransactionModelViewSet):
32
+ class FeesModelViewSet(UserPortfolioRequestPermissionMixin, InternalUserPermissionMixin, ModelViewSet):
33
33
  filter_backends = (
34
34
  DjangoFilterBackend,
35
35
  filters.OrderingFilter,
@@ -56,27 +56,27 @@ class FeesModelViewSet(TransactionModelViewSet):
56
56
 
57
57
  def get_queryset(self):
58
58
  if self.is_manager:
59
- return super().get_queryset().select_related("import_source", "linked_product")
59
+ return super().get_queryset().select_related("import_source", "product")
60
60
  return Fees.objects.none()
61
61
 
62
62
 
63
- class FeesPortfolioModelViewSet(FeesModelViewSet):
64
- IDENTIFIER = "wbportfolio:portfolio-fees"
63
+ class FeesProductModelViewSet(FeesModelViewSet):
64
+ IDENTIFIER = "wbportfolio:product-fees"
65
65
 
66
- filterset_class = FeesPortfolioFilterSet
66
+ filterset_class = FeesProductFilterSet
67
67
 
68
- display_config_class = FeesPortfolioDisplayConfig
69
- title_config_class = FeesPortfolioTitleConfig
70
- endpoint_config_class = FeesPortfolioEndpointConfig
68
+ display_config_class = FeesProductDisplayConfig
69
+ title_config_class = FeesProductTitleConfig
70
+ endpoint_config_class = FeesProductEndpointConfig
71
71
 
72
72
  def get_queryset(self):
73
73
  if self.is_portfolio_manager:
74
- return super().get_queryset().filter(portfolio=self.portfolio)
74
+ return super().get_queryset().filter(product=self.product)
75
75
 
76
76
  return Fees.objects.none()
77
77
 
78
78
 
79
- class FeesAggregatedPortfolioPandasView(
79
+ class FeesAggregatedProductPandasView(
80
80
  UserPortfolioRequestPermissionMixin, InternalUserPermissionMixin, ExportPandasAPIViewSet
81
81
  ):
82
82
  IDENTIFIER = "wbportfolio:aggregetedfees"
@@ -85,9 +85,9 @@ class FeesAggregatedPortfolioPandasView(
85
85
 
86
86
  queryset = Fees.valid_objects.all()
87
87
 
88
- display_config_class = FeesAggregatedPortfolioPandasDisplayConfig
89
- title_config_class = FeesAggregatedPortfolioTitleConfig
90
- endpoint_config_class = FeesAggregatedPortfolioPandasEndpointConfig
88
+ display_config_class = FeesAggregatedProductPandasDisplayConfig
89
+ title_config_class = FeesAggregatedProductTitleConfig
90
+ endpoint_config_class = FeesAggregatedProductPandasEndpointConfig
91
91
 
92
92
  pandas_fields = pf.PandasFields(
93
93
  fields=(
@@ -153,7 +153,7 @@ class FeesAggregatedPortfolioPandasView(
153
153
 
154
154
  def get_queryset(self):
155
155
  if self.is_portfolio_manager:
156
- qs = super().get_queryset().filter(portfolio=self.portfolio)
156
+ qs = super().get_queryset().filter(product=self.product)
157
157
  return qs.annotate(
158
158
  currency_fx_rate_usd=CurrencyFXRates.get_fx_rates_subquery(
159
159
  "fee_date", currency="currency", lookup_expr="exact"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: wbportfolio
3
- Version: 1.52.1
3
+ Version: 1.52.2rc0
4
4
  Author-email: Christopher Wittlinger <c.wittlinger@stainly.com>
5
5
  License-File: LICENSE
6
6
  Requires-Dist: cryptography==3.4.*