wbreport 2.2.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 (66) 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/migrations/0001_initial_squashed_squashed_0007_report_key.py +238 -0
  16. wbreport/migrations/0008_alter_report_file_content_type.py +25 -0
  17. wbreport/migrations/0009_alter_report_color_palette.py +27 -0
  18. wbreport/migrations/0010_auto_20240103_0947.py +43 -0
  19. wbreport/migrations/0011_auto_20240207_1629.py +35 -0
  20. wbreport/migrations/0012_reportversion_lock.py +17 -0
  21. wbreport/migrations/0013_alter_reportversion_context.py +18 -0
  22. wbreport/migrations/0014_alter_reportcategory_options_and_more.py +25 -0
  23. wbreport/migrations/__init__.py +0 -0
  24. wbreport/mixins.py +183 -0
  25. wbreport/models.py +781 -0
  26. wbreport/pdf/__init__.py +0 -0
  27. wbreport/pdf/charts/__init__.py +0 -0
  28. wbreport/pdf/charts/legend.py +15 -0
  29. wbreport/pdf/charts/pie.py +169 -0
  30. wbreport/pdf/charts/timeseries.py +77 -0
  31. wbreport/pdf/sandbox/__init__.py +0 -0
  32. wbreport/pdf/sandbox/run.py +17 -0
  33. wbreport/pdf/sandbox/templates/__init__.py +0 -0
  34. wbreport/pdf/sandbox/templates/basic_factsheet.py +908 -0
  35. wbreport/pdf/sandbox/templates/fund_factsheet.py +864 -0
  36. wbreport/pdf/sandbox/templates/long_industry_exposure_factsheet.py +898 -0
  37. wbreport/pdf/sandbox/templates/multistrat_factsheet.py +872 -0
  38. wbreport/pdf/sandbox/templates/testfile.pdf +434 -0
  39. wbreport/pdf/tables/__init__.py +0 -0
  40. wbreport/pdf/tables/aggregated_tables.py +156 -0
  41. wbreport/pdf/tables/data_tables.py +75 -0
  42. wbreport/serializers.py +191 -0
  43. wbreport/tasks.py +60 -0
  44. wbreport/templates/__init__.py +0 -0
  45. wbreport/templatetags/__init__.py +0 -0
  46. wbreport/templatetags/portfolio_tags.py +35 -0
  47. wbreport/tests/__init__.py +0 -0
  48. wbreport/tests/conftest.py +24 -0
  49. wbreport/tests/test_models.py +253 -0
  50. wbreport/tests/test_tasks.py +17 -0
  51. wbreport/tests/test_viewsets.py +0 -0
  52. wbreport/tests/tests.py +12 -0
  53. wbreport/urls.py +29 -0
  54. wbreport/urls_public.py +10 -0
  55. wbreport/viewsets/__init__.py +10 -0
  56. wbreport/viewsets/configs/__init__.py +18 -0
  57. wbreport/viewsets/configs/buttons.py +193 -0
  58. wbreport/viewsets/configs/displays.py +116 -0
  59. wbreport/viewsets/configs/endpoints.py +23 -0
  60. wbreport/viewsets/configs/menus.py +8 -0
  61. wbreport/viewsets/configs/titles.py +30 -0
  62. wbreport/viewsets/viewsets.py +330 -0
  63. wbreport-2.2.1.dist-info/METADATA +6 -0
  64. wbreport-2.2.1.dist-info/RECORD +66 -0
  65. wbreport-2.2.1.dist-info/WHEEL +5 -0
  66. wbreport-2.2.1.dist-info/licenses/LICENSE +4 -0
wbreport/mixins.py ADDED
@@ -0,0 +1,183 @@
1
+ from datetime import date
2
+ from io import BytesIO
3
+ from typing import Any, Dict
4
+
5
+ from django.contrib.auth import get_user_model
6
+ from django.template.loader import get_template
7
+ from wbreport.models import Report, ReportVersion
8
+
9
+ User = get_user_model()
10
+
11
+
12
+ class ReportMixin:
13
+ HTML_TEMPLATE_FILE = ""
14
+
15
+ @classmethod
16
+ def has_view_permission(cls, report: "Report", user: "User") -> bool:
17
+ """
18
+ Return if the given report, user pair has the view permission
19
+ Args:
20
+ report: A Report object
21
+ user: A User object
22
+
23
+ Returns:
24
+ True if the user has the permission to view the report
25
+ Raises:
26
+ NotImplementedError: If inheriting subclass does not explicitly defined this method
27
+ """
28
+ return False
29
+
30
+ @classmethod
31
+ def has_change_permission(cls, report: "Report", user: "User") -> bool:
32
+ """
33
+ Return if the given report, user pair has the change permission
34
+ Args:
35
+ report: A Report object
36
+ user: A User object
37
+
38
+ Returns:
39
+ True if the user has the permission to change the report
40
+ Raises:
41
+ NotImplementedError: If inheriting subclass does not explicitly defined this method
42
+ """
43
+ return False
44
+
45
+ @classmethod
46
+ def has_delete_permission(cls, report: "Report", user: "User") -> bool:
47
+ """
48
+ Return if the given report, user pair has the delete permission
49
+ Args:
50
+ report: A Report object
51
+ user: A User object
52
+
53
+ Returns:
54
+ True if the user has the permission to delete the report
55
+ Raises:
56
+ NotImplementedError: If inheriting subclass does not explicitly define this method
57
+ """
58
+ return False
59
+
60
+ @classmethod
61
+ def get_next_parameters(cls, parameters: Dict[str, Any]) -> Dict[str, Any]:
62
+ """
63
+ Return the temporal next set of parameters (e.g. next month)
64
+ Args:
65
+ parameters: The current parameters set
66
+
67
+ Returns:
68
+ The next parameter set
69
+ Raises:
70
+ NotImplementedError: If inheriting subclass does not explicitly define this method
71
+ """
72
+ raise NotImplementedError("Not Implemented")
73
+
74
+ @classmethod
75
+ def get_version_title(cls, report_title: str, parameters: Dict[str, Any]) -> str:
76
+ """
77
+ Derivate the version title based on its report's title and the given parameters set
78
+
79
+ e.g. report_january_2021
80
+
81
+ Args:
82
+ report_title: The report title
83
+ parameters: Current paramaters set
84
+
85
+ Returns:
86
+ The version title. Default to the report title
87
+ """
88
+ return report_title
89
+
90
+ @classmethod
91
+ def get_version_date(cls, parameters: Dict[str, Any]) -> date:
92
+ """
93
+ Extract the version date based on the current parameters set
94
+ Args:
95
+ parameters: Current parameters set
96
+
97
+ Returns:
98
+ The version date. Default to the value from the key "end" or None.
99
+ """
100
+ parameters = cls.parse_parameters(parameters)
101
+ return parameters.get("end", None)
102
+
103
+ @classmethod
104
+ def get_context(cls, version: "ReportVersion") -> Dict[str, Any]:
105
+ """
106
+ Generate context as a dictionary for the passed object
107
+
108
+ Args:
109
+ version: The object where context needs to be generated against
110
+
111
+ Returns:
112
+ Dictionary of key,value pairs
113
+
114
+ Raise:
115
+ NotImplementedError: If inheriting subclass does not explicitly define this method
116
+ """
117
+ raise NotImplementedError
118
+
119
+ @classmethod
120
+ def generate_html(cls, context: Dict[str, Any]) -> str:
121
+ """
122
+ Generate a html given a predetermined context dictionary
123
+
124
+ Args:
125
+ context: The dictionary context
126
+
127
+ Returns:
128
+ A rendered template as string
129
+
130
+ """
131
+ template = get_template(cls.HTML_TEMPLATE_FILE)
132
+ return template.render(context)
133
+
134
+ @classmethod
135
+ def generate_file(cls, context: Dict[str, Any]) -> BytesIO:
136
+ """
137
+ Generate a file given a predetermined context dictionary
138
+ Args:
139
+ context: The dictionary context
140
+
141
+ Returns:
142
+ The generated bytes stream
143
+
144
+ Raises:
145
+ NotImplementedError: If inheriting subclass does not explicitly define this method
146
+ """
147
+ raise NotImplementedError
148
+
149
+ @classmethod
150
+ def parse_parameters(cls, parameters: Dict[str, str]) -> Dict[str, Any]:
151
+ """
152
+ Parse the json parameters into a python dictionary (e.g. str to date)
153
+
154
+ Args:
155
+ parameters: parameters as json
156
+
157
+ Returns:
158
+ A python dictionary
159
+ """
160
+ raise parameters
161
+
162
+ @classmethod
163
+ def serialize_context(cls, context: Dict[str, Any]) -> Dict[str, Any]:
164
+ if "uuid" in context:
165
+ context["uuid"] = str(context["uuid"])
166
+ return context
167
+
168
+ @classmethod
169
+ def deserialize_context(cls, context: Dict[str, Any]) -> Dict[str, Any]:
170
+ """
171
+ Method called before rendering the template. Defaults return the passed dictionary untouched.
172
+
173
+ e.g. Can return the file url
174
+
175
+ Args:
176
+ context: The context as pickled dictionry
177
+
178
+ Returns:
179
+ The deserialized context
180
+ """
181
+ if report_logo_file_id := context.pop("report_logo_file_id", None):
182
+ context["logo_file"] = Report.objects.get(id=report_logo_file_id).logo_file
183
+ return context