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.
- wbreport/__init__.py +1 -0
- wbreport/admin.py +87 -0
- wbreport/apps.py +6 -0
- wbreport/defaults/__init__.py +0 -0
- wbreport/defaults/factsheets/__init__.py +0 -0
- wbreport/defaults/factsheets/base.py +990 -0
- wbreport/defaults/factsheets/menu.py +93 -0
- wbreport/defaults/factsheets/mixins.py +35 -0
- wbreport/defaults/factsheets/multitheme.py +947 -0
- wbreport/dynamic_preferences_registry.py +15 -0
- wbreport/factories/__init__.py +8 -0
- wbreport/factories/data_classes.py +48 -0
- wbreport/factories/reports.py +79 -0
- wbreport/filters.py +37 -0
- wbreport/migrations/0001_initial_squashed_squashed_0007_report_key.py +238 -0
- wbreport/migrations/0008_alter_report_file_content_type.py +25 -0
- wbreport/migrations/0009_alter_report_color_palette.py +27 -0
- wbreport/migrations/0010_auto_20240103_0947.py +43 -0
- wbreport/migrations/0011_auto_20240207_1629.py +35 -0
- wbreport/migrations/0012_reportversion_lock.py +17 -0
- wbreport/migrations/0013_alter_reportversion_context.py +18 -0
- wbreport/migrations/0014_alter_reportcategory_options_and_more.py +25 -0
- wbreport/migrations/__init__.py +0 -0
- wbreport/mixins.py +183 -0
- wbreport/models.py +781 -0
- wbreport/pdf/__init__.py +0 -0
- wbreport/pdf/charts/__init__.py +0 -0
- wbreport/pdf/charts/legend.py +15 -0
- wbreport/pdf/charts/pie.py +169 -0
- wbreport/pdf/charts/timeseries.py +77 -0
- wbreport/pdf/sandbox/__init__.py +0 -0
- wbreport/pdf/sandbox/run.py +17 -0
- wbreport/pdf/sandbox/templates/__init__.py +0 -0
- wbreport/pdf/sandbox/templates/basic_factsheet.py +908 -0
- wbreport/pdf/sandbox/templates/fund_factsheet.py +864 -0
- wbreport/pdf/sandbox/templates/long_industry_exposure_factsheet.py +898 -0
- wbreport/pdf/sandbox/templates/multistrat_factsheet.py +872 -0
- wbreport/pdf/sandbox/templates/testfile.pdf +434 -0
- wbreport/pdf/tables/__init__.py +0 -0
- wbreport/pdf/tables/aggregated_tables.py +156 -0
- wbreport/pdf/tables/data_tables.py +75 -0
- wbreport/serializers.py +191 -0
- wbreport/tasks.py +60 -0
- wbreport/templates/__init__.py +0 -0
- wbreport/templatetags/__init__.py +0 -0
- wbreport/templatetags/portfolio_tags.py +35 -0
- wbreport/tests/__init__.py +0 -0
- wbreport/tests/conftest.py +24 -0
- wbreport/tests/test_models.py +253 -0
- wbreport/tests/test_tasks.py +17 -0
- wbreport/tests/test_viewsets.py +0 -0
- wbreport/tests/tests.py +12 -0
- wbreport/urls.py +29 -0
- wbreport/urls_public.py +10 -0
- wbreport/viewsets/__init__.py +10 -0
- wbreport/viewsets/configs/__init__.py +18 -0
- wbreport/viewsets/configs/buttons.py +193 -0
- wbreport/viewsets/configs/displays.py +116 -0
- wbreport/viewsets/configs/endpoints.py +23 -0
- wbreport/viewsets/configs/menus.py +8 -0
- wbreport/viewsets/configs/titles.py +30 -0
- wbreport/viewsets/viewsets.py +330 -0
- wbreport-2.2.1.dist-info/METADATA +6 -0
- wbreport-2.2.1.dist-info/RECORD +66 -0
- wbreport-2.2.1.dist-info/WHEEL +5 -0
- wbreport-2.2.1.dist-info/licenses/LICENSE +4 -0
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
from dynamic_preferences.preferences import Section
|
|
2
|
+
from dynamic_preferences.registries import global_preferences_registry
|
|
3
|
+
from dynamic_preferences.types import IntegerPreference
|
|
4
|
+
|
|
5
|
+
report_section = Section("report")
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
@global_preferences_registry.register
|
|
9
|
+
class ReportMailTemplateIdPreference(IntegerPreference):
|
|
10
|
+
section = report_section
|
|
11
|
+
name = "report_mail_template_id"
|
|
12
|
+
default = -1
|
|
13
|
+
|
|
14
|
+
verbose_name = "Report Mail Template ID"
|
|
15
|
+
help_text = "The Template ID used to send the report by email"
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import datetime as dt
|
|
2
|
+
from io import BytesIO
|
|
3
|
+
|
|
4
|
+
from django.template import Context, Template
|
|
5
|
+
from wbreport.mixins import ReportMixin
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class ReportClass(ReportMixin):
|
|
9
|
+
HTML_TEMPLATE_CONTENT = "<p>{{ title }}</p>"
|
|
10
|
+
|
|
11
|
+
@classmethod
|
|
12
|
+
def parse_parameters(cls, parameters):
|
|
13
|
+
return {
|
|
14
|
+
"iteration": parameters["iteration"],
|
|
15
|
+
"end": dt.datetime.strptime(parameters["end"], "%Y-%m-%d"),
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
@classmethod
|
|
19
|
+
def get_next_parameters(cls, parameters):
|
|
20
|
+
parameters = cls.parse_parameters(parameters=parameters)
|
|
21
|
+
return {
|
|
22
|
+
"iteration": parameters["iteration"] + 1,
|
|
23
|
+
"end": dt.datetime.strftime(parameters["end"] + dt.timedelta(days=1), "%Y-%m-%d"),
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
@classmethod
|
|
27
|
+
def get_version_title(cls, report_title, parameters=None):
|
|
28
|
+
return f'{report_title}-{parameters.get("iteration", "")}'
|
|
29
|
+
|
|
30
|
+
@classmethod
|
|
31
|
+
def get_version_date(cls, parameters):
|
|
32
|
+
return parameters.get("end", None)
|
|
33
|
+
|
|
34
|
+
@classmethod
|
|
35
|
+
def get_context(cls, version):
|
|
36
|
+
if not version.parameters:
|
|
37
|
+
raise ValueError("Parameters needs to be defined")
|
|
38
|
+
return {"title": version.title}
|
|
39
|
+
|
|
40
|
+
@classmethod
|
|
41
|
+
def generate_html(cls, context) -> str:
|
|
42
|
+
template = Template(cls.HTML_TEMPLATE_CONTENT)
|
|
43
|
+
return template.render(Context(context))
|
|
44
|
+
|
|
45
|
+
@classmethod
|
|
46
|
+
def generate_file(cls, context) -> BytesIO:
|
|
47
|
+
output = BytesIO(context["title"].encode("utf_8"))
|
|
48
|
+
return output
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
from io import BytesIO
|
|
2
|
+
|
|
3
|
+
import factory
|
|
4
|
+
from PIL import Image
|
|
5
|
+
from wbcore.contrib.color.factories import ColorGradientFactory
|
|
6
|
+
from wbreport.models import (
|
|
7
|
+
Report,
|
|
8
|
+
ReportAsset,
|
|
9
|
+
ReportCategory,
|
|
10
|
+
ReportClass,
|
|
11
|
+
ReportVersion,
|
|
12
|
+
)
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
def create_test_image():
|
|
16
|
+
file = BytesIO()
|
|
17
|
+
image = Image.new("RGBA", size=(50, 50), color=(155, 0, 0))
|
|
18
|
+
image.save(file, "png")
|
|
19
|
+
file.name = "test.png"
|
|
20
|
+
file.seek(0)
|
|
21
|
+
return file
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
class ReportAssetFactory(factory.django.DjangoModelFactory):
|
|
25
|
+
class Meta:
|
|
26
|
+
model = ReportAsset
|
|
27
|
+
|
|
28
|
+
key = factory.Sequence(lambda n: f"Report Asset {n}")
|
|
29
|
+
description = factory.Faker("paragraph")
|
|
30
|
+
text = factory.Faker("paragraph")
|
|
31
|
+
asset = factory.django.ImageField()
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
class ReportCategoryFactory(factory.django.DjangoModelFactory):
|
|
35
|
+
class Meta:
|
|
36
|
+
model = ReportCategory
|
|
37
|
+
|
|
38
|
+
title = factory.Sequence(lambda n: f"Report Category {n}")
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
class ReportClassFactory(factory.django.DjangoModelFactory):
|
|
42
|
+
class Meta:
|
|
43
|
+
model = ReportClass
|
|
44
|
+
|
|
45
|
+
title = factory.Sequence(lambda n: f"Report Class {n}")
|
|
46
|
+
class_path = "wbreport.factories.data_classes"
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
class ReportFactory(factory.django.DjangoModelFactory):
|
|
50
|
+
class Meta:
|
|
51
|
+
model = Report
|
|
52
|
+
|
|
53
|
+
category = factory.SubFactory(ReportCategoryFactory)
|
|
54
|
+
report_class = factory.SubFactory(ReportClassFactory)
|
|
55
|
+
is_active = factory.Faker("boolean")
|
|
56
|
+
base_color = factory.Faker("color")
|
|
57
|
+
title = factory.Sequence(lambda n: f"Report {n}")
|
|
58
|
+
logo_file = factory.django.ImageField()
|
|
59
|
+
color_palette = factory.SubFactory(ColorGradientFactory)
|
|
60
|
+
mailing_list = factory.SubFactory("wbmailing.factories.MailingListFactory")
|
|
61
|
+
parent_report = factory.SubFactory("wbreport.factories.ParentReportFactory")
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
class ParentReportFactory(ReportFactory):
|
|
65
|
+
parent_report = None
|
|
66
|
+
key = factory.Sequence(lambda n: f"key-{n}")
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
class ReportVersionFactory(factory.django.DjangoModelFactory):
|
|
70
|
+
class Meta:
|
|
71
|
+
model = ReportVersion
|
|
72
|
+
|
|
73
|
+
title = factory.Sequence(lambda n: f"Report Version {n}")
|
|
74
|
+
lookup = factory.Sequence(lambda n: f"lookup-{n}")
|
|
75
|
+
is_primary = True
|
|
76
|
+
disabled = False
|
|
77
|
+
report = factory.SubFactory(ReportFactory)
|
|
78
|
+
comment = factory.Faker("paragraph")
|
|
79
|
+
parameters = factory.Sequence(lambda n: {"type": f"type{n}"})
|
wbreport/filters.py
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
from wbcore import filters as wb_filters
|
|
2
|
+
from wbreport.models import Report, ReportVersion
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
class ReportFilterSet(wb_filters.FilterSet):
|
|
6
|
+
is_active = wb_filters.BooleanFilter(default=True)
|
|
7
|
+
|
|
8
|
+
class Meta:
|
|
9
|
+
model = Report
|
|
10
|
+
fields = {
|
|
11
|
+
"category": ["exact"],
|
|
12
|
+
"parent_report": ["exact", "isnull"],
|
|
13
|
+
"permission_type": ["exact"],
|
|
14
|
+
"base_color": ["exact"],
|
|
15
|
+
"mailing_list": ["exact"],
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
class ReportVersionFilterSet(wb_filters.FilterSet):
|
|
20
|
+
disabled = wb_filters.BooleanFilter(method="boolean_is_disabled", default=False)
|
|
21
|
+
|
|
22
|
+
def boolean_is_disabled(self, queryset, name, value):
|
|
23
|
+
if value is True:
|
|
24
|
+
return queryset.filter(disabled=True)
|
|
25
|
+
if value is False:
|
|
26
|
+
return queryset.filter(disabled=False)
|
|
27
|
+
return queryset
|
|
28
|
+
|
|
29
|
+
class Meta:
|
|
30
|
+
model = ReportVersion
|
|
31
|
+
fields = {
|
|
32
|
+
"report": ["exact"],
|
|
33
|
+
"version_date": ["gte", "exact", "lte"],
|
|
34
|
+
"creation_date": ["gte", "exact", "lte"],
|
|
35
|
+
"update_date": ["gte", "exact", "lte"],
|
|
36
|
+
"is_primary": ["exact"],
|
|
37
|
+
}
|
|
@@ -0,0 +1,238 @@
|
|
|
1
|
+
# Generated by Django 4.1.7 on 2023-04-19 05:30
|
|
2
|
+
|
|
3
|
+
import uuid
|
|
4
|
+
|
|
5
|
+
import colorfield.fields
|
|
6
|
+
import django.core.serializers.json
|
|
7
|
+
import django.db.models.deletion
|
|
8
|
+
import mptt.fields
|
|
9
|
+
import picklefield.fields
|
|
10
|
+
from django.conf import settings
|
|
11
|
+
from django.db import migrations, models
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class Migration(migrations.Migration):
|
|
15
|
+
initial = True
|
|
16
|
+
|
|
17
|
+
dependencies = [
|
|
18
|
+
("wbcore", "0001_initial_squashed_squashed_0010_preset_appliedpreset"),
|
|
19
|
+
("wbmailing", "0001_initial_squashed_squashed_0008_alter_mail_bcc_email_alter_mail_cc_email_and_more"),
|
|
20
|
+
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
|
|
21
|
+
("contenttypes", "0002_remove_content_type_name"),
|
|
22
|
+
]
|
|
23
|
+
|
|
24
|
+
operations = [
|
|
25
|
+
migrations.CreateModel(
|
|
26
|
+
name="Report",
|
|
27
|
+
fields=[
|
|
28
|
+
("id", models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name="ID")),
|
|
29
|
+
(
|
|
30
|
+
"permission_type",
|
|
31
|
+
models.CharField(
|
|
32
|
+
choices=[("INTERNAL", "Internal"), ("PUBLIC", "Public"), ("PRIVATE", "Private")],
|
|
33
|
+
default="PRIVATE",
|
|
34
|
+
max_length=8,
|
|
35
|
+
),
|
|
36
|
+
),
|
|
37
|
+
("object_id", models.PositiveIntegerField(blank=True, null=True)),
|
|
38
|
+
(
|
|
39
|
+
"key",
|
|
40
|
+
models.CharField(
|
|
41
|
+
default="",
|
|
42
|
+
help_text="The key is like the family name: it represents the nature of the report.",
|
|
43
|
+
max_length=256,
|
|
44
|
+
),
|
|
45
|
+
),
|
|
46
|
+
(
|
|
47
|
+
"file_content_type",
|
|
48
|
+
models.CharField(
|
|
49
|
+
choices=[("PDF", "application/pdf"), ("CSV", "text/csv")], default="PDF", max_length=64
|
|
50
|
+
),
|
|
51
|
+
),
|
|
52
|
+
(
|
|
53
|
+
"is_active",
|
|
54
|
+
models.BooleanField(
|
|
55
|
+
default=False, help_text="True if a report needs to be available for this product"
|
|
56
|
+
),
|
|
57
|
+
),
|
|
58
|
+
(
|
|
59
|
+
"file_disabled",
|
|
60
|
+
models.BooleanField(default=False, help_text="True if this version file needs to be disabled"),
|
|
61
|
+
),
|
|
62
|
+
(
|
|
63
|
+
"base_color",
|
|
64
|
+
colorfield.fields.ColorField(default="#FFF000", image_field=None, max_length=64, samples=None),
|
|
65
|
+
),
|
|
66
|
+
("title", models.CharField(max_length=256)),
|
|
67
|
+
("namespace", models.CharField(default="", max_length=256)),
|
|
68
|
+
("logo_file", models.FileField(blank=True, max_length=256, null=True, upload_to="report/logo")),
|
|
69
|
+
("parameters", models.JSONField(default=dict, encoder=django.core.serializers.json.DjangoJSONEncoder)),
|
|
70
|
+
("lft", models.PositiveIntegerField(editable=False)),
|
|
71
|
+
("rght", models.PositiveIntegerField(editable=False)),
|
|
72
|
+
("tree_id", models.PositiveIntegerField(db_index=True, editable=False)),
|
|
73
|
+
("level", models.PositiveIntegerField(editable=False)),
|
|
74
|
+
],
|
|
75
|
+
options={
|
|
76
|
+
"verbose_name": "Report",
|
|
77
|
+
"verbose_name_plural": "Reports",
|
|
78
|
+
"abstract": False,
|
|
79
|
+
"default_permissions": ("add", "change", "delete", "view", "administrate"),
|
|
80
|
+
},
|
|
81
|
+
),
|
|
82
|
+
migrations.CreateModel(
|
|
83
|
+
name="ReportAsset",
|
|
84
|
+
fields=[
|
|
85
|
+
("id", models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name="ID")),
|
|
86
|
+
("key", models.CharField(max_length=255, unique=True)),
|
|
87
|
+
("description", models.TextField(blank=True, null=True)),
|
|
88
|
+
("text", models.TextField(blank=True, null=True)),
|
|
89
|
+
("asset", models.FileField(blank=True, max_length=256, null=True, upload_to="report/assets")),
|
|
90
|
+
],
|
|
91
|
+
options={
|
|
92
|
+
"verbose_name": "Report Asset",
|
|
93
|
+
"verbose_name_plural": "Report Assets",
|
|
94
|
+
},
|
|
95
|
+
),
|
|
96
|
+
migrations.CreateModel(
|
|
97
|
+
name="ReportCategory",
|
|
98
|
+
fields=[
|
|
99
|
+
("id", models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name="ID")),
|
|
100
|
+
("title", models.CharField(max_length=128)),
|
|
101
|
+
("order", models.IntegerField(default=0)),
|
|
102
|
+
],
|
|
103
|
+
options={
|
|
104
|
+
"verbose_name": "Report Category",
|
|
105
|
+
"verbose_name_plural": "Report Categories",
|
|
106
|
+
},
|
|
107
|
+
),
|
|
108
|
+
migrations.CreateModel(
|
|
109
|
+
name="ReportClass",
|
|
110
|
+
fields=[
|
|
111
|
+
("id", models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name="ID")),
|
|
112
|
+
("title", models.CharField(max_length=256)),
|
|
113
|
+
("class_path", models.CharField(max_length=256)),
|
|
114
|
+
],
|
|
115
|
+
options={
|
|
116
|
+
"verbose_name": "Report Class",
|
|
117
|
+
"verbose_name_plural": "Report Classes",
|
|
118
|
+
},
|
|
119
|
+
),
|
|
120
|
+
migrations.CreateModel(
|
|
121
|
+
name="ReportVersion",
|
|
122
|
+
fields=[
|
|
123
|
+
("id", models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name="ID")),
|
|
124
|
+
("uuid", models.UUIDField(default=uuid.uuid4, editable=False, unique=True)),
|
|
125
|
+
("lookup", models.CharField(default="", max_length=256, unique=True)),
|
|
126
|
+
("title", models.CharField(max_length=256)),
|
|
127
|
+
("parameters", models.JSONField(default=dict, encoder=django.core.serializers.json.DjangoJSONEncoder)),
|
|
128
|
+
("context", picklefield.fields.PickledObjectField(default=dict, editable=False)),
|
|
129
|
+
("version_date", models.DateField(blank=True, null=True)),
|
|
130
|
+
("creation_date", models.DateTimeField(auto_now_add=True)),
|
|
131
|
+
("update_date", models.DateTimeField(auto_now=True)),
|
|
132
|
+
("comment", models.TextField(default="")),
|
|
133
|
+
(
|
|
134
|
+
"is_primary",
|
|
135
|
+
models.BooleanField(
|
|
136
|
+
default=False,
|
|
137
|
+
help_text="Only one Version from a report can be considered primary and is usually the last created one",
|
|
138
|
+
),
|
|
139
|
+
),
|
|
140
|
+
("disabled", models.BooleanField(default=False, help_text="True if version needs to be disabled")),
|
|
141
|
+
(
|
|
142
|
+
"report",
|
|
143
|
+
models.ForeignKey(
|
|
144
|
+
on_delete=django.db.models.deletion.CASCADE,
|
|
145
|
+
related_name="versions",
|
|
146
|
+
to="wbreport.report",
|
|
147
|
+
verbose_name="Report",
|
|
148
|
+
),
|
|
149
|
+
),
|
|
150
|
+
],
|
|
151
|
+
options={
|
|
152
|
+
"verbose_name": "Report Version",
|
|
153
|
+
"verbose_name_plural": "Report Versions",
|
|
154
|
+
},
|
|
155
|
+
),
|
|
156
|
+
migrations.AddField(
|
|
157
|
+
model_name="report",
|
|
158
|
+
name="category",
|
|
159
|
+
field=models.ForeignKey(
|
|
160
|
+
blank=True,
|
|
161
|
+
help_text="The Visual Report category",
|
|
162
|
+
null=True,
|
|
163
|
+
on_delete=django.db.models.deletion.SET_NULL,
|
|
164
|
+
related_name="reports",
|
|
165
|
+
to="wbreport.reportcategory",
|
|
166
|
+
verbose_name="Report Category",
|
|
167
|
+
),
|
|
168
|
+
),
|
|
169
|
+
migrations.AddField(
|
|
170
|
+
model_name="report",
|
|
171
|
+
name="content_type",
|
|
172
|
+
field=models.ForeignKey(
|
|
173
|
+
blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to="contenttypes.contenttype"
|
|
174
|
+
),
|
|
175
|
+
),
|
|
176
|
+
migrations.AddField(
|
|
177
|
+
model_name="report",
|
|
178
|
+
name="creator",
|
|
179
|
+
field=models.ForeignKey(
|
|
180
|
+
blank=True,
|
|
181
|
+
null=True,
|
|
182
|
+
on_delete=django.db.models.deletion.SET_NULL,
|
|
183
|
+
related_name="created_%(app_label)s_%(class)s",
|
|
184
|
+
to=settings.AUTH_USER_MODEL,
|
|
185
|
+
),
|
|
186
|
+
),
|
|
187
|
+
migrations.AddField(
|
|
188
|
+
model_name="report",
|
|
189
|
+
name="mailing_list",
|
|
190
|
+
field=models.ForeignKey(
|
|
191
|
+
blank=True,
|
|
192
|
+
help_text="The Mailing List used to send the updated report link",
|
|
193
|
+
null=True,
|
|
194
|
+
on_delete=django.db.models.deletion.SET_NULL,
|
|
195
|
+
related_name="reports",
|
|
196
|
+
to="wbmailing.mailinglist",
|
|
197
|
+
verbose_name="Report Mailing List",
|
|
198
|
+
),
|
|
199
|
+
),
|
|
200
|
+
migrations.AddField(
|
|
201
|
+
model_name="report",
|
|
202
|
+
name="parent_report",
|
|
203
|
+
field=mptt.fields.TreeForeignKey(
|
|
204
|
+
blank=True,
|
|
205
|
+
help_text="The Parent Report attached to this report",
|
|
206
|
+
null=True,
|
|
207
|
+
on_delete=django.db.models.deletion.SET_NULL,
|
|
208
|
+
related_name="child_reports",
|
|
209
|
+
to="wbreport.report",
|
|
210
|
+
verbose_name="Parent Report",
|
|
211
|
+
),
|
|
212
|
+
),
|
|
213
|
+
migrations.AddField(
|
|
214
|
+
model_name="report",
|
|
215
|
+
name="report_class",
|
|
216
|
+
field=models.ForeignKey(
|
|
217
|
+
blank=True,
|
|
218
|
+
help_text="The method used to generate reports based on context",
|
|
219
|
+
null=True,
|
|
220
|
+
on_delete=django.db.models.deletion.SET_NULL,
|
|
221
|
+
related_name="reports",
|
|
222
|
+
to="wbreport.reportclass",
|
|
223
|
+
verbose_name="Report Class",
|
|
224
|
+
),
|
|
225
|
+
),
|
|
226
|
+
migrations.AddConstraint(
|
|
227
|
+
model_name="report",
|
|
228
|
+
constraint=models.UniqueConstraint(
|
|
229
|
+
fields=("parent_report", "title"), name="unique_parent_report_and_report"
|
|
230
|
+
),
|
|
231
|
+
),
|
|
232
|
+
migrations.AddConstraint(
|
|
233
|
+
model_name="report",
|
|
234
|
+
constraint=models.UniqueConstraint(
|
|
235
|
+
fields=("key", "content_type", "object_id"), name="unique_content_object_and_key"
|
|
236
|
+
),
|
|
237
|
+
),
|
|
238
|
+
]
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# Generated by Django 4.2.7 on 2023-11-06 13:30
|
|
2
|
+
|
|
3
|
+
from django.db import migrations, models
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class Migration(migrations.Migration):
|
|
7
|
+
dependencies = [
|
|
8
|
+
("wbreport", "0001_initial_squashed_squashed_0007_report_key"),
|
|
9
|
+
]
|
|
10
|
+
|
|
11
|
+
operations = [
|
|
12
|
+
migrations.AlterField(
|
|
13
|
+
model_name="report",
|
|
14
|
+
name="file_content_type",
|
|
15
|
+
field=models.CharField(
|
|
16
|
+
choices=[
|
|
17
|
+
("PDF", "application/pdf"),
|
|
18
|
+
("CSV", "text/csv"),
|
|
19
|
+
("XLSX", "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"),
|
|
20
|
+
],
|
|
21
|
+
default="PDF",
|
|
22
|
+
max_length=64,
|
|
23
|
+
),
|
|
24
|
+
),
|
|
25
|
+
]
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# Generated by Django 4.2.6 on 2023-11-16 14:03
|
|
2
|
+
|
|
3
|
+
import django.db.models.deletion
|
|
4
|
+
from django.db import migrations, models
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class Migration(migrations.Migration):
|
|
8
|
+
dependencies = [
|
|
9
|
+
("color", "0001_initial"),
|
|
10
|
+
("wbreport", "0008_alter_report_file_content_type"),
|
|
11
|
+
]
|
|
12
|
+
|
|
13
|
+
operations = [
|
|
14
|
+
migrations.AddField(
|
|
15
|
+
model_name="report",
|
|
16
|
+
name="color_palette",
|
|
17
|
+
field=models.ForeignKey(
|
|
18
|
+
blank=True,
|
|
19
|
+
help_text="The report color palette",
|
|
20
|
+
null=True,
|
|
21
|
+
on_delete=django.db.models.deletion.SET_NULL,
|
|
22
|
+
related_name="reports",
|
|
23
|
+
to="color.colorgradient",
|
|
24
|
+
verbose_name="Color Palette",
|
|
25
|
+
),
|
|
26
|
+
)
|
|
27
|
+
]
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
# Generated by Django 4.2.8 on 2024-01-03 08:47
|
|
2
|
+
|
|
3
|
+
from contextlib import suppress
|
|
4
|
+
|
|
5
|
+
from django.apps import apps
|
|
6
|
+
from django.contrib.contenttypes.models import ContentType
|
|
7
|
+
from django.db import migrations
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
def migrate_content_type(apps, schema_editor):
|
|
11
|
+
Report = apps.get_model("wbreport", "Report")
|
|
12
|
+
|
|
13
|
+
for model_name in [
|
|
14
|
+
"Classification",
|
|
15
|
+
"Instrument",
|
|
16
|
+
"ClassificationGroup",
|
|
17
|
+
"Deal",
|
|
18
|
+
"Exchange",
|
|
19
|
+
"InstrumentClassificationRelatedInstrument",
|
|
20
|
+
"InstrumentClassificationThroughModel",
|
|
21
|
+
"InstrumentFavoriteGroup",
|
|
22
|
+
"InstrumentList",
|
|
23
|
+
"InstrumentListThroughModel",
|
|
24
|
+
"InstrumentRequest",
|
|
25
|
+
"RelatedInstrumentThroughModel",
|
|
26
|
+
"InstrumentPrice",
|
|
27
|
+
]:
|
|
28
|
+
with suppress(ContentType.DoesNotExist):
|
|
29
|
+
old_ct = ContentType.objects.get(app_label="wbportfolio", model=model_name.lower())
|
|
30
|
+
new_ct = ContentType.objects.get(app_label="wbfdm", model=model_name.lower())
|
|
31
|
+
Report.objects.filter(content_type_id=old_ct.id).update(content_type_id=new_ct.id)
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
class Migration(migrations.Migration):
|
|
35
|
+
dependencies = (
|
|
36
|
+
[
|
|
37
|
+
("wbreport", "0009_alter_report_color_palette"),
|
|
38
|
+
("wbfdm", "0012_instrumentprice_created_instrumentprice_modified"),
|
|
39
|
+
]
|
|
40
|
+
if apps.is_installed("wbfdm")
|
|
41
|
+
else [("wbreport", "0009_alter_report_color_palette")]
|
|
42
|
+
)
|
|
43
|
+
operations = [migrations.RunPython(migrate_content_type)]
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
# Generated by Django 4.2.9 on 2024-02-07 15:29
|
|
2
|
+
|
|
3
|
+
from contextlib import suppress
|
|
4
|
+
|
|
5
|
+
from django.contrib.contenttypes.models import ContentType
|
|
6
|
+
from django.db import migrations
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
def migrate_theme_portfolio(apps, schema_editor):
|
|
10
|
+
from wbportfolio.models import Product
|
|
11
|
+
from wbreport.models import Report
|
|
12
|
+
|
|
13
|
+
PortfolioPortfolioThroughModel = apps.get_model("wbportfolio", "PortfolioPortfolioThroughModel")
|
|
14
|
+
InstrumentPortfolioThroughModel = apps.get_model("wbportfolio", "InstrumentPortfolioThroughModel")
|
|
15
|
+
for report in Report.objects.filter(content_type=ContentType.objects.get_for_model(Product)):
|
|
16
|
+
theme_portfolio_id = None
|
|
17
|
+
with suppress(InstrumentPortfolioThroughModel.DoesNotExist):
|
|
18
|
+
asset_portfolio = InstrumentPortfolioThroughModel.objects.get(
|
|
19
|
+
instrument_id=report.object_id, asset_portfolio=True
|
|
20
|
+
).portfolio
|
|
21
|
+
if through_portfolio := PortfolioPortfolioThroughModel.objects.filter(
|
|
22
|
+
portfolio=asset_portfolio, is_theme=True
|
|
23
|
+
).first():
|
|
24
|
+
theme_portfolio_id = through_portfolio.dependency_portfolio.id
|
|
25
|
+
report.parameters["theme_portfolio_id"] = theme_portfolio_id
|
|
26
|
+
report.save()
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
class Migration(migrations.Migration):
|
|
30
|
+
run_before = [("wbportfolio", "0054_portfolioinstrumentpreferredclassificationthroughmodel_and_more")]
|
|
31
|
+
dependencies = [
|
|
32
|
+
("wbreport", "0010_auto_20240103_0947"),
|
|
33
|
+
]
|
|
34
|
+
|
|
35
|
+
operations = [migrations.RunPython(migrate_theme_portfolio)]
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
# Generated by Django 5.0.6 on 2024-07-05 09:06
|
|
2
|
+
|
|
3
|
+
from django.db import migrations, models
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class Migration(migrations.Migration):
|
|
7
|
+
dependencies = [
|
|
8
|
+
("wbreport", "0011_auto_20240207_1629"),
|
|
9
|
+
]
|
|
10
|
+
|
|
11
|
+
operations = [
|
|
12
|
+
migrations.AddField(
|
|
13
|
+
model_name="reportversion",
|
|
14
|
+
name="lock",
|
|
15
|
+
field=models.BooleanField(default=False, help_text="True, the context cannot be regenerated"),
|
|
16
|
+
),
|
|
17
|
+
]
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# Generated by Django 5.0.7 on 2024-07-30 12:24
|
|
2
|
+
|
|
3
|
+
import django.core.serializers.json
|
|
4
|
+
from django.db import migrations, models
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class Migration(migrations.Migration):
|
|
8
|
+
dependencies = [
|
|
9
|
+
("wbreport", "0012_reportversion_lock"),
|
|
10
|
+
]
|
|
11
|
+
|
|
12
|
+
operations = [
|
|
13
|
+
migrations.AlterField(
|
|
14
|
+
model_name="reportversion",
|
|
15
|
+
name="context",
|
|
16
|
+
field=models.JSONField(default=dict, encoder=django.core.serializers.json.DjangoJSONEncoder),
|
|
17
|
+
),
|
|
18
|
+
]
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# Generated by Django 5.0.9 on 2024-11-11 11:59
|
|
2
|
+
|
|
3
|
+
from django.db import migrations, models
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class Migration(migrations.Migration):
|
|
7
|
+
dependencies = [
|
|
8
|
+
("wbreport", "0013_alter_reportversion_context"),
|
|
9
|
+
]
|
|
10
|
+
|
|
11
|
+
operations = [
|
|
12
|
+
migrations.AlterModelOptions(
|
|
13
|
+
name="reportcategory",
|
|
14
|
+
options={
|
|
15
|
+
"ordering": ("order",),
|
|
16
|
+
"verbose_name": "Report Category",
|
|
17
|
+
"verbose_name_plural": "Report Categories",
|
|
18
|
+
},
|
|
19
|
+
),
|
|
20
|
+
migrations.AlterField(
|
|
21
|
+
model_name="reportcategory",
|
|
22
|
+
name="order",
|
|
23
|
+
field=models.PositiveIntegerField(db_index=True, editable=False, verbose_name="order"),
|
|
24
|
+
),
|
|
25
|
+
]
|
|
File without changes
|