wbreport 1.43.1__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 wbreport might be problematic. Click here for more details.

Files changed (70) hide show
  1. wbreport/__init__.py +1 -0
  2. wbreport/admin.py +87 -0
  3. wbreport/apps.py +6 -0
  4. wbreport/defaults/__init__.py +0 -0
  5. wbreport/defaults/factsheets/__init__.py +0 -0
  6. wbreport/defaults/factsheets/base.py +990 -0
  7. wbreport/defaults/factsheets/menu.py +93 -0
  8. wbreport/defaults/factsheets/mixins.py +35 -0
  9. wbreport/defaults/factsheets/multitheme.py +947 -0
  10. wbreport/dynamic_preferences_registry.py +15 -0
  11. wbreport/factories/__init__.py +8 -0
  12. wbreport/factories/data_classes.py +48 -0
  13. wbreport/factories/reports.py +79 -0
  14. wbreport/filters.py +37 -0
  15. wbreport/fixtures/wbreport.yaml +1 -0
  16. wbreport/migrations/0001_initial_squashed_squashed_0007_report_key.py +238 -0
  17. wbreport/migrations/0008_alter_report_file_content_type.py +25 -0
  18. wbreport/migrations/0009_alter_report_color_palette.py +27 -0
  19. wbreport/migrations/0010_auto_20240103_0947.py +43 -0
  20. wbreport/migrations/0011_auto_20240207_1629.py +35 -0
  21. wbreport/migrations/0012_reportversion_lock.py +17 -0
  22. wbreport/migrations/0013_alter_reportversion_context.py +18 -0
  23. wbreport/migrations/0014_alter_reportcategory_options_and_more.py +25 -0
  24. wbreport/migrations/__init__.py +0 -0
  25. wbreport/mixins.py +183 -0
  26. wbreport/models.py +781 -0
  27. wbreport/pdf/__init__.py +0 -0
  28. wbreport/pdf/charts/__init__.py +0 -0
  29. wbreport/pdf/charts/legend.py +15 -0
  30. wbreport/pdf/charts/pie.py +169 -0
  31. wbreport/pdf/charts/timeseries.py +77 -0
  32. wbreport/pdf/flowables/risk.py +88 -0
  33. wbreport/pdf/flowables/textboxes.py +143 -0
  34. wbreport/pdf/flowables/themes.py +179 -0
  35. wbreport/pdf/sandbox/__init__.py +0 -0
  36. wbreport/pdf/sandbox/run.py +17 -0
  37. wbreport/pdf/sandbox/templates/__init__.py +0 -0
  38. wbreport/pdf/sandbox/templates/basic_factsheet.py +908 -0
  39. wbreport/pdf/sandbox/templates/fund_factsheet.py +864 -0
  40. wbreport/pdf/sandbox/templates/long_industry_exposure_factsheet.py +898 -0
  41. wbreport/pdf/sandbox/templates/multistrat_factsheet.py +872 -0
  42. wbreport/pdf/sandbox/templates/testfile.pdf +434 -0
  43. wbreport/pdf/tables/__init__.py +0 -0
  44. wbreport/pdf/tables/aggregated_tables.py +156 -0
  45. wbreport/pdf/tables/data_tables.py +75 -0
  46. wbreport/serializers.py +191 -0
  47. wbreport/tasks.py +60 -0
  48. wbreport/templates/__init__.py +0 -0
  49. wbreport/templatetags/__init__.py +0 -0
  50. wbreport/templatetags/portfolio_tags.py +35 -0
  51. wbreport/tests/__init__.py +0 -0
  52. wbreport/tests/conftest.py +24 -0
  53. wbreport/tests/test_models.py +253 -0
  54. wbreport/tests/test_tasks.py +17 -0
  55. wbreport/tests/test_viewsets.py +0 -0
  56. wbreport/tests/tests.py +12 -0
  57. wbreport/urls.py +29 -0
  58. wbreport/urls_public.py +10 -0
  59. wbreport/viewsets/__init__.py +10 -0
  60. wbreport/viewsets/configs/__init__.py +18 -0
  61. wbreport/viewsets/configs/buttons.py +193 -0
  62. wbreport/viewsets/configs/displays.py +116 -0
  63. wbreport/viewsets/configs/endpoints.py +23 -0
  64. wbreport/viewsets/configs/menus.py +8 -0
  65. wbreport/viewsets/configs/titles.py +30 -0
  66. wbreport/viewsets/viewsets.py +330 -0
  67. wbreport-1.43.1.dist-info/METADATA +7 -0
  68. wbreport-1.43.1.dist-info/RECORD +70 -0
  69. wbreport-1.43.1.dist-info/WHEEL +5 -0
  70. wbreport-1.43.1.dist-info/licenses/LICENSE +4 -0
@@ -0,0 +1,23 @@
1
+ from rest_framework.reverse import reverse
2
+ from wbcore.metadata.configs.endpoints import EndpointViewConfig
3
+
4
+
5
+ class ReportVersionEndpointConfig(EndpointViewConfig):
6
+ def get_endpoint(self, **kwargs):
7
+ return None
8
+
9
+ def get_list_endpoint(self, **kwargs):
10
+ return reverse("wbreport:reportversion-list", request=self.request)
11
+
12
+ def get_instance_endpoint(self):
13
+ return self.get_list_endpoint()
14
+
15
+
16
+ class ReportEndpointConfig(EndpointViewConfig):
17
+ def get_endpoint(self, **kwargs):
18
+ return reverse("wbreport:report-list", request=self.request)
19
+
20
+
21
+ class ReportVersionReportEndpointConfig(EndpointViewConfig):
22
+ def get_list_endpoint(self, **kwargs):
23
+ return reverse("wbreport:report-version-list", args=[self.view.kwargs["report_id"]], request=self.request)
@@ -0,0 +1,8 @@
1
+ from wbcore.menus import ItemPermission, MenuItem
2
+
3
+ REPORT_MENUITEM = MenuItem(
4
+ label="Reports",
5
+ endpoint="wbreport:report-list",
6
+ permission=ItemPermission(permissions=["wbreport.view_report"]),
7
+ endpoint_get_parameters={"parent_report__isnull": True},
8
+ )
@@ -0,0 +1,30 @@
1
+ from wbcore.metadata.configs.titles import TitleViewConfig
2
+ from wbreport.models import Report
3
+
4
+
5
+ class ReportVersionTitleConfig(TitleViewConfig):
6
+ def get_list_title(self):
7
+ return "Versions"
8
+
9
+ def get_instance_title(self):
10
+ return "Version: {{title}}"
11
+
12
+ def get_create_title(self):
13
+ return "New Version"
14
+
15
+
16
+ class ReportTitleConfig(TitleViewConfig):
17
+ def get_list_title(self):
18
+ return "Reports"
19
+
20
+ def get_instance_title(self):
21
+ return "Report: {{title}}"
22
+
23
+ def get_create_title(self):
24
+ return "New Report"
25
+
26
+
27
+ class ReportVersionReportTitleConfig(ReportVersionTitleConfig):
28
+ def get_list_title(self):
29
+ report = Report.objects.get(id=self.view.kwargs["report_id"])
30
+ return f"Versions for report {str(report)}"
@@ -0,0 +1,330 @@
1
+ import json
2
+
3
+ from django.db.models import Case, Exists, F, IntegerField, OuterRef, When
4
+ from django.http import FileResponse, HttpResponse
5
+ from django.shortcuts import get_object_or_404, render
6
+ from django.views.decorators.cache import cache_page
7
+ from rest_framework import filters, status
8
+ from rest_framework.authentication import SessionAuthentication
9
+ from rest_framework.decorators import (
10
+ action,
11
+ api_view,
12
+ authentication_classes,
13
+ permission_classes,
14
+ )
15
+ from rest_framework.permissions import AllowAny, IsAuthenticated
16
+ from rest_framework.renderers import StaticHTMLRenderer
17
+ from rest_framework.response import Response
18
+ from wbcore import viewsets
19
+ from wbcore.contrib.authentication.authentication import (
20
+ JWTCookieAuthentication,
21
+ QueryTokenAuthentication,
22
+ )
23
+ from wbcore.contrib.guardian.viewsets.mixins import GuardianFilterMixin
24
+ from wbreport.filters import ReportFilterSet, ReportVersionFilterSet
25
+ from wbreport.models import (
26
+ Report,
27
+ ReportCategory,
28
+ ReportClass,
29
+ ReportVersion,
30
+ bulk_create_child_reports_as_task,
31
+ generate_next_reports_as_task,
32
+ set_primary_report_version_as_task,
33
+ update_context_as_task,
34
+ update_version_context_as_task,
35
+ )
36
+ from wbreport.serializers import (
37
+ ReportCategoryModelSerializer,
38
+ ReportCategoryRepresentationSerializer,
39
+ ReportClassRepresentationSerializer,
40
+ ReportModelSerializer,
41
+ ReportRepresentationSerializer,
42
+ ReportVersionModelSerializer,
43
+ ReportVersionRepresentationSerializer,
44
+ )
45
+ from wbreport.tasks import generate_and_send_current_report_file
46
+ from wbreport.viewsets.configs import (
47
+ ReportButtonConfig,
48
+ ReportCategoryDisplayConfig,
49
+ ReportDisplayConfig,
50
+ ReportEndpointConfig,
51
+ ReportTitleConfig,
52
+ ReportVersionButtonConfig,
53
+ ReportVersionDisplayConfig,
54
+ ReportVersionEndpointConfig,
55
+ ReportVersionReportDisplayConfig,
56
+ ReportVersionReportEndpointConfig,
57
+ ReportVersionReportTitleConfig,
58
+ ReportVersionTitleConfig,
59
+ )
60
+
61
+
62
+ @api_view(["GET"])
63
+ @permission_classes([AllowAny])
64
+ @authentication_classes([SessionAuthentication, JWTCookieAuthentication, QueryTokenAuthentication])
65
+ def report(request, namespace):
66
+ report = get_object_or_404(Report, namespace=namespace, is_active=True)
67
+ if (version := report.primary_version) and not version.disabled:
68
+ # Need the report to be public or the user to have access
69
+ if version.report.is_accessible(request.user):
70
+ return HttpResponse(version.generate_html())
71
+ return render(
72
+ request,
73
+ "errors/custom.html",
74
+ {
75
+ "title": "Report Unavailable",
76
+ "header": "Report Unavailable",
77
+ "description": "If you thing this report should be enabled, please " "contact a system administrator",
78
+ },
79
+ status=status.HTTP_403_FORBIDDEN,
80
+ )
81
+
82
+
83
+ @api_view(["GET"])
84
+ @cache_page(None, key_prefix="report")
85
+ @permission_classes([AllowAny])
86
+ @authentication_classes([SessionAuthentication, JWTCookieAuthentication, QueryTokenAuthentication])
87
+ def download_report_version_file(request, uuid):
88
+ version = get_object_or_404(ReportVersion, uuid=uuid, report__is_active=True, disabled=False)
89
+ if version.report.is_accessible(request.user):
90
+ output = version.generate_file()
91
+ if output:
92
+ return FileResponse(
93
+ output,
94
+ as_attachment=True,
95
+ filename=output.name,
96
+ content_type=Report.FileContentType[version.report.file_content_type].label,
97
+ )
98
+ return HttpResponse(
99
+ "No PDF report for this version, please contact an administrator", status=status.HTTP_403_FORBIDDEN
100
+ )
101
+
102
+
103
+ @api_view(["GET"])
104
+ @permission_classes([AllowAny])
105
+ @authentication_classes([SessionAuthentication, JWTCookieAuthentication, QueryTokenAuthentication])
106
+ def report_version(request, lookup):
107
+ version = get_object_or_404(ReportVersion, lookup=lookup, report__is_active=True, disabled=False)
108
+ # Need the report to be public or the user to have access
109
+ if version.report.is_accessible(request.user):
110
+ return HttpResponse(version.generate_html())
111
+ return render(
112
+ request,
113
+ "errors/custom.html",
114
+ {
115
+ "title": "Report Unavailable",
116
+ "header": "Report Unavailable",
117
+ "description": "If you thing this report should be enabled, please " "contact a system administrator",
118
+ },
119
+ status=status.HTTP_403_FORBIDDEN,
120
+ )
121
+
122
+
123
+ class ReportCategoryRepresentationViewSet(viewsets.RepresentationViewSet):
124
+ filter_backends = (filters.OrderingFilter, filters.SearchFilter)
125
+ ordering_fields = ordering = ("title",)
126
+ search_fields = ("title",)
127
+ serializer_class = ReportCategoryRepresentationSerializer
128
+ queryset = ReportCategory.objects.all()
129
+
130
+
131
+ class ReportRepresentationViewSet(viewsets.RepresentationViewSet):
132
+ filter_backends = (filters.OrderingFilter, filters.SearchFilter)
133
+ ordering_fields = ordering = ("title",)
134
+ search_fields = ("title",)
135
+ serializer_class = ReportRepresentationSerializer
136
+ queryset = Report.objects.all()
137
+
138
+
139
+ class ReportClassRepresentationViewSet(viewsets.RepresentationViewSet):
140
+ ordering_fields = ordering = ("title",)
141
+ search_fields = ("title",)
142
+ serializer_class = ReportClassRepresentationSerializer
143
+ queryset = ReportClass.objects.all()
144
+
145
+
146
+ class ReportVersionRepresentationViewSet(viewsets.RepresentationViewSet):
147
+ ordering_fields = ordering = ("title",)
148
+ search_fields = ("title",)
149
+ serializer_class = ReportVersionRepresentationSerializer
150
+ queryset = ReportVersion.objects.all()
151
+
152
+
153
+ class ReportCategoryModelViewSet(viewsets.ModelViewSet):
154
+ serializer_class = ReportCategoryModelSerializer
155
+ ordering_fields = ("title", "order")
156
+ ordering = ("-title",)
157
+ search_fields = ("title",)
158
+
159
+ display_config_class = ReportCategoryDisplayConfig
160
+
161
+ queryset = ReportCategory.objects.all()
162
+
163
+
164
+ class ReportModelViewSet(GuardianFilterMixin, viewsets.ModelViewSet):
165
+ serializer_class = ReportModelSerializer
166
+ ordering_fields = (
167
+ "title",
168
+ "parent_report__title",
169
+ "category__title",
170
+ "is_active",
171
+ "permission_type",
172
+ "base_color",
173
+ "mailing_list__title",
174
+ )
175
+ ordering = ("title",)
176
+ search_fields = ("title",)
177
+ filterset_class = ReportFilterSet
178
+ display_config_class = ReportDisplayConfig
179
+ endpoint_config_class = ReportEndpointConfig
180
+ title_config_class = ReportTitleConfig
181
+ button_config_class = ReportButtonConfig
182
+
183
+ queryset = Report.objects.annotate(
184
+ has_children=Exists(Report.objects.filter(parent_report=OuterRef("pk"))),
185
+ _group_key=Case(When(has_children=True, then=F("id")), default=None, output_field=IntegerField()),
186
+ )
187
+
188
+ @action(detail=True, methods=["PATCH"], permission_classes=[IsAuthenticated])
189
+ def bundletreport(self, request, pk=None):
190
+ if request.user.is_superuser:
191
+ report = get_object_or_404(Report, pk=pk)
192
+ try:
193
+ parameters = json.loads(request.POST["parameters"])
194
+ except KeyError:
195
+ parameters = report.last_version.parameters if report.versions.exists() else None
196
+ generate_and_send_current_report_file.delay(request.user.id, pk, parameters=parameters)
197
+ return Response({}, status=status.HTTP_200_OK)
198
+
199
+ @action(detail=True, methods=["PATCH"], permission_classes=[IsAuthenticated])
200
+ def switchprimaryversions(self, request, pk=None):
201
+ if request.user.is_superuser:
202
+ report = get_object_or_404(Report, pk=pk)
203
+ try:
204
+ parameters = json.loads(request.POST["parameters"])
205
+ except KeyError:
206
+ parameters = report.last_version.parameters if report.versions.exists() else None
207
+ set_primary_report_version_as_task.delay(report.pk, parameters=parameters)
208
+ return Response({}, status=status.HTTP_200_OK)
209
+
210
+ @action(detail=True, methods=["PATCH"], permission_classes=[IsAuthenticated])
211
+ def generatenextreports(self, request, pk=None):
212
+ if request.user.is_superuser:
213
+ parameters = None
214
+ if (start := request.GET.get("start_date", None)) and (end := request.GET.get("end_date", None)):
215
+ parameters = {"start": start, "end": end}
216
+ generate_next_reports_as_task.delay(
217
+ pk,
218
+ user=request.user,
219
+ parameters=parameters,
220
+ comment=request.GET.get("comment", ""),
221
+ max_depth_only=request.GET.get("max_depth_only", False) == "true",
222
+ )
223
+ return Response({}, status=status.HTTP_200_OK)
224
+
225
+ @action(detail=True, methods=["PATCH"], permission_classes=[IsAuthenticated])
226
+ def bulkcreatereport(self, request, pk=None):
227
+ if request.user.is_superuser:
228
+ start_parameters = end_parameters = None
229
+ if start_parameters_str := request.POST.get("start_parameters", None):
230
+ start_parameters = json.loads(start_parameters_str)
231
+ if end_parameters_str := request.POST.get("end_parameters", None):
232
+ end_parameters = json.loads(end_parameters_str)
233
+
234
+ if start_parameters and end_parameters:
235
+ bulk_create_child_reports_as_task.delay(pk, start_parameters, end_parameters, user=request.user)
236
+ return Response({}, status=status.HTTP_200_OK)
237
+
238
+ @action(detail=True, methods=["PATCH"], permission_classes=[IsAuthenticated])
239
+ def updatecontext(self, request, pk=None):
240
+ if request.user.is_superuser:
241
+ report = get_object_or_404(Report, pk=pk)
242
+ if report.versions.exists():
243
+ try:
244
+ parameters = json.loads(request.POST["parameters"])
245
+ except KeyError:
246
+ parameters = report.last_version.parameters
247
+ update_version_context_as_task.delay(pk, parameters=parameters, user=request.user)
248
+ return Response({}, status=status.HTTP_200_OK)
249
+
250
+
251
+ class ReportVersionModelViewSet(viewsets.ModelViewSet):
252
+ serializer_class = ReportVersionModelSerializer
253
+ ordering_fields = (
254
+ "uuid",
255
+ "report",
256
+ "title",
257
+ "version_date",
258
+ "creation_date",
259
+ "update_date",
260
+ "is_primary",
261
+ "disabled",
262
+ )
263
+ ordering = ("-version_date",)
264
+ search_fields = ("title", "report__title")
265
+ filterset_class = ReportVersionFilterSet
266
+
267
+ display_config_class = ReportVersionDisplayConfig
268
+ endpoint_config_class = ReportVersionEndpointConfig
269
+ title_config_class = ReportVersionTitleConfig
270
+ button_config_class = ReportVersionButtonConfig
271
+
272
+ queryset = ReportVersion.objects.all()
273
+
274
+ @action(detail=True, methods=["GET"], permission_classes=[IsAuthenticated])
275
+ def sendemail(self, request, pk=None):
276
+ version = ReportVersion.objects.get(id=pk)
277
+ if version:
278
+ version.send_mail()
279
+ return Response({}, status=status.HTTP_200_OK)
280
+ return Response({}, status=status.HTTP_404_NOT_FOUND)
281
+
282
+ @action(detail=True, methods=["GET"], permission_classes=[IsAuthenticated])
283
+ def updatecontext(self, request, pk=None):
284
+ update_context_as_task.delay(pk, request.user, comment=request.GET.get("comment", ""))
285
+ return Response({}, status=status.HTTP_200_OK)
286
+
287
+ @action(
288
+ detail=True,
289
+ methods=["GET"],
290
+ permission_classes=[IsAuthenticated],
291
+ renderer_classes=[StaticHTMLRenderer],
292
+ authentication_classes=[JWTCookieAuthentication],
293
+ )
294
+ def html(self, request, pk=None):
295
+ version = get_object_or_404(ReportVersion, id=pk, disabled=False, report__is_active=True)
296
+ if version.report.is_accessible(request.user):
297
+ return HttpResponse(version.generate_html())
298
+ return Response({}, status=status.HTTP_401_UNAUTHORIZED)
299
+
300
+ @action(
301
+ detail=True,
302
+ methods=["GET"],
303
+ permission_classes=[IsAuthenticated],
304
+ authentication_classes=[JWTCookieAuthentication],
305
+ )
306
+ def file(self, request, pk=None):
307
+ version = get_object_or_404(ReportVersion, id=pk, disabled=False, report__is_active=True)
308
+ if version.report.is_accessible(request.user):
309
+ output = version.generate_file()
310
+ output.seek(0)
311
+ if output:
312
+ return FileResponse(
313
+ output,
314
+ as_attachment=True,
315
+ filename=output.name,
316
+ content_type=Report.FileContentType[version.report.file_content_type].label,
317
+ )
318
+ return Response({}, status=status.HTTP_401_UNAUTHORIZED)
319
+
320
+
321
+ class ReportVersionReportModelViewSet(ReportVersionModelViewSet):
322
+ display_config_class = ReportVersionReportDisplayConfig
323
+ endpoint_config_class = ReportVersionReportEndpointConfig
324
+ title_config_class = ReportVersionReportTitleConfig
325
+
326
+ def get_queryset(self):
327
+ report = Report.objects.get(id=self.kwargs["report_id"])
328
+ if report.is_accessible(self.request.user):
329
+ return super().get_queryset().filter(report=self.kwargs["report_id"])
330
+ return ReportVersion.objects.none()
@@ -0,0 +1,7 @@
1
+ Metadata-Version: 2.4
2
+ Name: wbreport
3
+ Version: 1.43.1
4
+ Author-email: Christopher Wittlinger <c.wittlinger@stainly.com>
5
+ License-File: LICENSE
6
+ Requires-Dist: wbcore
7
+ Requires-Dist: wbmailing
@@ -0,0 +1,70 @@
1
+ wbreport/__init__.py,sha256=J-j-u0itpEFT6irdmWmixQqYMadNl1X91TxUmoiLHMI,22
2
+ wbreport/admin.py,sha256=tQPq0BKzXZ7I3aOE0FaGyjuKs37TiT56s7OT0mDfOXo,2364
3
+ wbreport/apps.py,sha256=4z2N25hswEAlsJsntASC5iOWUwsqMCL99-gvqBlPGFY,148
4
+ wbreport/dynamic_preferences_registry.py,sha256=nGT-fS5vN-BSVNyGcJ81ORjiXlOngePRN9hipB9olPw,508
5
+ wbreport/filters.py,sha256=2j8osC3fx5mLWilV3rKoSjSph9mWL04TMuVcd-yEf4A,1146
6
+ wbreport/mixins.py,sha256=Hx_LTPVfmygrnyDTOjNi58N_QNfdBURPmriLNV3pbfU,5520
7
+ wbreport/models.py,sha256=cRKgmdbb2cKRr04jkTtwv6kmRc5fd8CcIUENKlGIegQ,29595
8
+ wbreport/serializers.py,sha256=_heMGD75ncR3ygs-OcdpFVPjCZUyEI4F3iVS9yp47Yc,7226
9
+ wbreport/tasks.py,sha256=KLSRyw0aRhLsmT5UGdlalpRbNyRFXBRfejg5k9j8wPo,2270
10
+ wbreport/urls.py,sha256=6VuxcSKi5aMmH8IIqmXlBcIhdam_pGl2T_xemhZh6FI,1205
11
+ wbreport/urls_public.py,sha256=LbzOc79VKmKUntsUb54lm0QoC22ip05ZdyNbSl2j3KQ,369
12
+ wbreport/defaults/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
13
+ wbreport/defaults/factsheets/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
14
+ wbreport/defaults/factsheets/base.py,sha256=0qmn10S2l6cqcZV_pUS7c-lHlC8ajOmDmUsgJVQ2OJU,41089
15
+ wbreport/defaults/factsheets/menu.py,sha256=G2iX6jZhqddoFsc3-t2uI7ZverUaBzF7EjqAbLrIEYU,4579
16
+ wbreport/defaults/factsheets/mixins.py,sha256=E0RvxmUpvpG7B7YngBPXJ35eD3nwNandJFzLjj1rNRI,1267
17
+ wbreport/defaults/factsheets/multitheme.py,sha256=Kje360mRE8XTIOugCOL7-44fjjIrnbmcx5HrzVqtzbI,38487
18
+ wbreport/factories/__init__.py,sha256=jyD1_R-xc2JPZIaSwtE7zYATdL9NIXIDqTwjLw1MolA,170
19
+ wbreport/factories/data_classes.py,sha256=BwYqbw75lnZSim8LNY9-mhf79GjGqdQdd8XQiPPNyvA,1486
20
+ wbreport/factories/reports.py,sha256=_oJBJp5WmoaZ0BjU8MwqYdBpSJxsQH61b3QQrOmYOOU,2285
21
+ wbreport/fixtures/wbreport.yaml,sha256=VKagUKjjW49ZMjKvUdO72AS9rQzWk-6YWzpiUjmHCXk,5467
22
+ wbreport/migrations/0001_initial_squashed_squashed_0007_report_key.py,sha256=ghAnYJK01-ISld9CUfU18sqdIstuw5UrOgWH2y8gcTs,10061
23
+ wbreport/migrations/0008_alter_report_file_content_type.py,sha256=qPR9kWiZLDvfw9H3-BsUdmdIEwlhm5iHSoSax8hzjNE,715
24
+ wbreport/migrations/0009_alter_report_color_palette.py,sha256=sEIqeMBPYfOg5Onom8H9VCNmlMkpqNI9qT51UVtoBTM,770
25
+ wbreport/migrations/0010_auto_20240103_0947.py,sha256=voHHRETqSZRxrUJBD81ig20MuJMm_ymnZ8cbdANUMLQ,1468
26
+ wbreport/migrations/0011_auto_20240207_1629.py,sha256=7f21bmsb91nEUWtnWnXpNJwJYRUMurnGzWEmQxmU2Wk,1505
27
+ wbreport/migrations/0012_reportversion_lock.py,sha256=eSs6TIJY2YgWPMk3k8ykl2nsnNBc16lFMKtkWCC1btA,445
28
+ wbreport/migrations/0013_alter_reportversion_context.py,sha256=_6hcwvxYzDu3UiBoO6Vq6-pxF_j7hNlQ4VK-dltxUSw,485
29
+ wbreport/migrations/0014_alter_reportcategory_options_and_more.py,sha256=52ot6CkuICQfGCrYU5Zqtz7olqUgSw2Ppp17adnPqh0,723
30
+ wbreport/migrations/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
31
+ wbreport/pdf/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
32
+ wbreport/pdf/charts/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
33
+ wbreport/pdf/charts/legend.py,sha256=D-_-ZLDF7q7KlYLiNYVXHWLs4I-LgV8Ce8lk1sLfbPU,461
34
+ wbreport/pdf/charts/pie.py,sha256=EcWTDOv1ZD5Az6MnBt_w5pBXusPBB3zTHlpguBPNjfU,4287
35
+ wbreport/pdf/charts/timeseries.py,sha256=dN2N66qg9S3bW9OV8q-Vms3wFxUHhLMnaUnymzTNeWY,2381
36
+ wbreport/pdf/flowables/risk.py,sha256=KdE5RQU0kPUqZX6mpvqITVxpLFu1uDeA2C5lrtSA0mY,3443
37
+ wbreport/pdf/flowables/textboxes.py,sha256=BMzlva7WBD5UZ5DD1cwWV5ZPragt61YaJquikDYk7eU,4369
38
+ wbreport/pdf/flowables/themes.py,sha256=Y5LcgSTJDhIZM3uIWAPY68HVMhTY9aY9PDwWsG5_IVk,6548
39
+ wbreport/pdf/sandbox/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
40
+ wbreport/pdf/sandbox/run.py,sha256=Vkzp_xVVJHctToS49Uef2Mnpb_5KUOWPxNdTFHOqri8,584
41
+ wbreport/pdf/sandbox/templates/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
42
+ wbreport/pdf/sandbox/templates/basic_factsheet.py,sha256=w_PpPS8rbirkrodgXs538_xOw6aNKGr4GGuVn_XGPPU,33967
43
+ wbreport/pdf/sandbox/templates/fund_factsheet.py,sha256=aGf5CfUHAp-kGJfU8tZ3TnEO26re4Sny_G2QCFte4gk,31054
44
+ wbreport/pdf/sandbox/templates/long_industry_exposure_factsheet.py,sha256=TnOz_NJLhX7ZT1amnbPkyee719dYug688JGSzVGRaMQ,32684
45
+ wbreport/pdf/sandbox/templates/multistrat_factsheet.py,sha256=8-WU-r7x6Yq5v1ml2mUT7e33SUYk7IzKMNXFWuE7Y2k,31481
46
+ wbreport/pdf/sandbox/templates/testfile.pdf,sha256=eV55RNFdqxqYzre6mg8EWZoL_cbc_lwPjyTGt1pr1AI,144012
47
+ wbreport/pdf/tables/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
48
+ wbreport/pdf/tables/aggregated_tables.py,sha256=rYikFswLMcaTpW7Em5B5oE1WSItQjkW_MJJTsumRpq8,4763
49
+ wbreport/pdf/tables/data_tables.py,sha256=snJlyMMRz4YSR4gcXeIdQR38h-IkOQiO0A5jx5lF45o,2241
50
+ wbreport/templates/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
51
+ wbreport/templatetags/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
52
+ wbreport/templatetags/portfolio_tags.py,sha256=N2MC_6iFcUAFDH5Wx5rD1-PVK_Ltq4VPIoq7WL4aXGQ,900
53
+ wbreport/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
54
+ wbreport/tests/conftest.py,sha256=oMidAuP41_yxMubUDUpqcsW_YslEq_CyPmfD11CUPhY,745
55
+ wbreport/tests/test_models.py,sha256=nCBcCLBylZsFMSgkU6mm4iQdoPVRuS42taCI0pb6Gx4,11292
56
+ wbreport/tests/test_tasks.py,sha256=icRtEyAtKfhxyx_oN6cYtkUA4QMaGwEpdKKhc07OPKc,762
57
+ wbreport/tests/test_viewsets.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
58
+ wbreport/tests/tests.py,sha256=j2A1uu5DtGu2w056j0S4O7u2OxylldMPCmr7bbSOvfk,282
59
+ wbreport/viewsets/__init__.py,sha256=EzsLpS7Y7HxrcLXUJ0DPAmtgewOqkKjoLwHmgijT7Hk,287
60
+ wbreport/viewsets/viewsets.py,sha256=MuglJiKtfKWX3uq81ghChEGJVzvXDqJEef9dSEZJ2Ao,13120
61
+ wbreport/viewsets/configs/__init__.py,sha256=Tsw7Ffe_iy63CPRZgtsIXkZjUMvKdsMxSz5xzmyqF5A,494
62
+ wbreport/viewsets/configs/buttons.py,sha256=Hbofe9TtZ5JdoLOb_rlGzC-_Z_lnJpIseXnFoJd9i-g,8914
63
+ wbreport/viewsets/configs/displays.py,sha256=py3Wcut9uKmer7LV-ftIi0xU97PFctJT-yKZmdgc8qk,4897
64
+ wbreport/viewsets/configs/endpoints.py,sha256=wPbB0JnnKSF8hSX07W67rdGkP0VKqLBhTnjBKjZzaL0,799
65
+ wbreport/viewsets/configs/menus.py,sha256=trDZsdjXip8KQ4SY1uIudZWFqwb3rQHIRSU36dzRzy0,269
66
+ wbreport/viewsets/configs/titles.py,sha256=AYY1ekJp9V8iihcuR8Ygl-7_1AYpXoAp8WthpWWD5GE,782
67
+ wbreport-1.43.1.dist-info/METADATA,sha256=nltLmRrsq8T-9bprxsqF46kNmlWntkD-XILmxr98-AM,186
68
+ wbreport-1.43.1.dist-info/WHEEL,sha256=tkmg4JIqwd9H8mL30xA7crRmoStyCtGp0VWshokd1Jc,105
69
+ wbreport-1.43.1.dist-info/licenses/LICENSE,sha256=jvfVH0SY8_YMHlsJHKe_OajiscQDz4lpTlqT6x24sVw,172
70
+ wbreport-1.43.1.dist-info/RECORD,,
@@ -0,0 +1,5 @@
1
+ Wheel-Version: 1.0
2
+ Generator: hatchling 1.27.0
3
+ Root-Is-Purelib: true
4
+ Tag: py2-none-any
5
+ Tag: py3-none-any
@@ -0,0 +1,4 @@
1
+ This repository is not allowed to be used without written consent from either:
2
+
3
+ - Stainly SarL (Geneva, Switzerland)
4
+ - Intellineers GmbH & Co.KG (Hamburg, Germany)