wbcrm 1.56.8__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.
Files changed (182) hide show
  1. wbcrm/__init__.py +1 -0
  2. wbcrm/admin/__init__.py +5 -0
  3. wbcrm/admin/accounts.py +60 -0
  4. wbcrm/admin/activities.py +104 -0
  5. wbcrm/admin/events.py +43 -0
  6. wbcrm/admin/groups.py +8 -0
  7. wbcrm/admin/products.py +9 -0
  8. wbcrm/apps.py +5 -0
  9. wbcrm/configurations/__init__.py +1 -0
  10. wbcrm/configurations/base.py +16 -0
  11. wbcrm/dynamic_preferences_registry.py +38 -0
  12. wbcrm/factories/__init__.py +14 -0
  13. wbcrm/factories/accounts.py +57 -0
  14. wbcrm/factories/activities.py +124 -0
  15. wbcrm/factories/groups.py +24 -0
  16. wbcrm/factories/products.py +11 -0
  17. wbcrm/filters/__init__.py +10 -0
  18. wbcrm/filters/accounts.py +80 -0
  19. wbcrm/filters/activities.py +204 -0
  20. wbcrm/filters/groups.py +21 -0
  21. wbcrm/filters/products.py +38 -0
  22. wbcrm/filters/signals.py +95 -0
  23. wbcrm/fixtures/wbcrm.json +1215 -0
  24. wbcrm/kpi_handlers/activities.py +171 -0
  25. wbcrm/locale/de/LC_MESSAGES/django.mo +0 -0
  26. wbcrm/locale/de/LC_MESSAGES/django.po +1557 -0
  27. wbcrm/locale/de/LC_MESSAGES/django.po.translated +1630 -0
  28. wbcrm/locale/en/LC_MESSAGES/django.mo +0 -0
  29. wbcrm/locale/en/LC_MESSAGES/django.po +1466 -0
  30. wbcrm/locale/fr/LC_MESSAGES/django.mo +0 -0
  31. wbcrm/locale/fr/LC_MESSAGES/django.po +1467 -0
  32. wbcrm/migrations/0001_initial_squashed_squashed_0032_productcompanyrelationship_alter_product_prospects_and_more.py +3948 -0
  33. wbcrm/migrations/0002_alter_activity_repeat_choice.py +32 -0
  34. wbcrm/migrations/0003_remove_activity_external_id_and_more.py +63 -0
  35. wbcrm/migrations/0004_alter_activity_status.py +28 -0
  36. wbcrm/migrations/0005_account_accountrole_accountroletype_and_more.py +182 -0
  37. wbcrm/migrations/0006_alter_activity_location.py +17 -0
  38. wbcrm/migrations/0007_alter_account_status.py +23 -0
  39. wbcrm/migrations/0008_alter_activity_options.py +16 -0
  40. wbcrm/migrations/0009_alter_account_is_public.py +19 -0
  41. wbcrm/migrations/0010_alter_account_reference_id.py +17 -0
  42. wbcrm/migrations/0011_activity_summary.py +22 -0
  43. wbcrm/migrations/0012_alter_activity_summary.py +17 -0
  44. wbcrm/migrations/0013_account_action_plan_account_relationship_status_and_more.py +34 -0
  45. wbcrm/migrations/0014_alter_account_relationship_status.py +24 -0
  46. wbcrm/migrations/0015_alter_activity_type.py +23 -0
  47. wbcrm/migrations/0016_auto_20241205_1015.py +106 -0
  48. wbcrm/migrations/0017_event.py +40 -0
  49. wbcrm/migrations/0018_activity_search_vector.py +24 -0
  50. wbcrm/migrations/__init__.py +0 -0
  51. wbcrm/models/__init__.py +5 -0
  52. wbcrm/models/accounts.py +648 -0
  53. wbcrm/models/activities.py +1419 -0
  54. wbcrm/models/events.py +15 -0
  55. wbcrm/models/groups.py +119 -0
  56. wbcrm/models/llm/activity_summaries.py +41 -0
  57. wbcrm/models/llm/analyze_relationship.py +50 -0
  58. wbcrm/models/products.py +86 -0
  59. wbcrm/models/recurrence.py +280 -0
  60. wbcrm/preferences.py +13 -0
  61. wbcrm/report/activity_report.py +110 -0
  62. wbcrm/serializers/__init__.py +23 -0
  63. wbcrm/serializers/accounts.py +141 -0
  64. wbcrm/serializers/activities.py +525 -0
  65. wbcrm/serializers/groups.py +30 -0
  66. wbcrm/serializers/products.py +58 -0
  67. wbcrm/serializers/recurrence.py +91 -0
  68. wbcrm/serializers/signals.py +71 -0
  69. wbcrm/static/wbcrm/markdown/documentation/activity.md +86 -0
  70. wbcrm/static/wbcrm/markdown/documentation/activitytype.md +20 -0
  71. wbcrm/static/wbcrm/markdown/documentation/group.md +2 -0
  72. wbcrm/static/wbcrm/markdown/documentation/product.md +11 -0
  73. wbcrm/synchronization/__init__.py +0 -0
  74. wbcrm/synchronization/activity/__init__.py +0 -0
  75. wbcrm/synchronization/activity/admin.py +73 -0
  76. wbcrm/synchronization/activity/backend.py +214 -0
  77. wbcrm/synchronization/activity/backends/__init__.py +0 -0
  78. wbcrm/synchronization/activity/backends/google/__init__.py +2 -0
  79. wbcrm/synchronization/activity/backends/google/google_calendar_backend.py +406 -0
  80. wbcrm/synchronization/activity/backends/google/request_utils/__init__.py +16 -0
  81. wbcrm/synchronization/activity/backends/google/request_utils/external_to_internal/create.py +75 -0
  82. wbcrm/synchronization/activity/backends/google/request_utils/external_to_internal/delete.py +78 -0
  83. wbcrm/synchronization/activity/backends/google/request_utils/external_to_internal/update.py +155 -0
  84. wbcrm/synchronization/activity/backends/google/request_utils/internal_to_external/update.py +181 -0
  85. wbcrm/synchronization/activity/backends/google/tasks.py +21 -0
  86. wbcrm/synchronization/activity/backends/google/tests/__init__.py +0 -0
  87. wbcrm/synchronization/activity/backends/google/tests/conftest.py +1 -0
  88. wbcrm/synchronization/activity/backends/google/tests/test_data.py +81 -0
  89. wbcrm/synchronization/activity/backends/google/tests/test_google_backend.py +319 -0
  90. wbcrm/synchronization/activity/backends/google/tests/test_utils.py +274 -0
  91. wbcrm/synchronization/activity/backends/google/typing_informations.py +139 -0
  92. wbcrm/synchronization/activity/backends/google/utils.py +217 -0
  93. wbcrm/synchronization/activity/backends/outlook/__init__.py +0 -0
  94. wbcrm/synchronization/activity/backends/outlook/backend.py +593 -0
  95. wbcrm/synchronization/activity/backends/outlook/msgraph.py +436 -0
  96. wbcrm/synchronization/activity/backends/outlook/parser.py +432 -0
  97. wbcrm/synchronization/activity/backends/outlook/tests/__init__.py +0 -0
  98. wbcrm/synchronization/activity/backends/outlook/tests/conftest.py +1 -0
  99. wbcrm/synchronization/activity/backends/outlook/tests/fixtures.py +606 -0
  100. wbcrm/synchronization/activity/backends/outlook/tests/test_admin.py +118 -0
  101. wbcrm/synchronization/activity/backends/outlook/tests/test_backend.py +274 -0
  102. wbcrm/synchronization/activity/backends/outlook/tests/test_controller.py +249 -0
  103. wbcrm/synchronization/activity/backends/outlook/tests/test_parser.py +174 -0
  104. wbcrm/synchronization/activity/controller.py +627 -0
  105. wbcrm/synchronization/activity/dynamic_preferences_registry.py +119 -0
  106. wbcrm/synchronization/activity/preferences.py +27 -0
  107. wbcrm/synchronization/activity/shortcuts.py +16 -0
  108. wbcrm/synchronization/activity/tasks.py +21 -0
  109. wbcrm/synchronization/activity/urls.py +7 -0
  110. wbcrm/synchronization/activity/utils.py +46 -0
  111. wbcrm/synchronization/activity/views.py +41 -0
  112. wbcrm/synchronization/admin.py +1 -0
  113. wbcrm/synchronization/apps.py +14 -0
  114. wbcrm/synchronization/dynamic_preferences_registry.py +1 -0
  115. wbcrm/synchronization/management.py +36 -0
  116. wbcrm/synchronization/tasks.py +1 -0
  117. wbcrm/synchronization/urls.py +5 -0
  118. wbcrm/tasks.py +264 -0
  119. wbcrm/templates/email/activity.html +98 -0
  120. wbcrm/templates/email/activity_report.html +6 -0
  121. wbcrm/templates/email/daily_summary.html +72 -0
  122. wbcrm/templates/email/global_daily_summary.html +85 -0
  123. wbcrm/tests/__init__.py +0 -0
  124. wbcrm/tests/accounts/__init__.py +0 -0
  125. wbcrm/tests/accounts/test_models.py +393 -0
  126. wbcrm/tests/accounts/test_viewsets.py +88 -0
  127. wbcrm/tests/conftest.py +76 -0
  128. wbcrm/tests/disable_signals.py +62 -0
  129. wbcrm/tests/e2e/__init__.py +1 -0
  130. wbcrm/tests/e2e/e2e_wbcrm_utility.py +83 -0
  131. wbcrm/tests/e2e/test_e2e.py +370 -0
  132. wbcrm/tests/test_assignee_methods.py +40 -0
  133. wbcrm/tests/test_chartviewsets.py +112 -0
  134. wbcrm/tests/test_dto.py +64 -0
  135. wbcrm/tests/test_filters.py +52 -0
  136. wbcrm/tests/test_models.py +217 -0
  137. wbcrm/tests/test_recurrence.py +292 -0
  138. wbcrm/tests/test_report.py +21 -0
  139. wbcrm/tests/test_serializers.py +171 -0
  140. wbcrm/tests/test_tasks.py +95 -0
  141. wbcrm/tests/test_viewsets.py +967 -0
  142. wbcrm/tests/tests.py +121 -0
  143. wbcrm/typings.py +109 -0
  144. wbcrm/urls.py +67 -0
  145. wbcrm/viewsets/__init__.py +22 -0
  146. wbcrm/viewsets/accounts.py +122 -0
  147. wbcrm/viewsets/activities.py +341 -0
  148. wbcrm/viewsets/buttons/__init__.py +7 -0
  149. wbcrm/viewsets/buttons/accounts.py +27 -0
  150. wbcrm/viewsets/buttons/activities.py +89 -0
  151. wbcrm/viewsets/buttons/signals.py +17 -0
  152. wbcrm/viewsets/display/__init__.py +12 -0
  153. wbcrm/viewsets/display/accounts.py +110 -0
  154. wbcrm/viewsets/display/activities.py +444 -0
  155. wbcrm/viewsets/display/groups.py +22 -0
  156. wbcrm/viewsets/display/products.py +105 -0
  157. wbcrm/viewsets/endpoints/__init__.py +8 -0
  158. wbcrm/viewsets/endpoints/accounts.py +25 -0
  159. wbcrm/viewsets/endpoints/activities.py +30 -0
  160. wbcrm/viewsets/endpoints/groups.py +7 -0
  161. wbcrm/viewsets/endpoints/products.py +9 -0
  162. wbcrm/viewsets/groups.py +38 -0
  163. wbcrm/viewsets/menu/__init__.py +8 -0
  164. wbcrm/viewsets/menu/accounts.py +18 -0
  165. wbcrm/viewsets/menu/activities.py +49 -0
  166. wbcrm/viewsets/menu/groups.py +16 -0
  167. wbcrm/viewsets/menu/products.py +20 -0
  168. wbcrm/viewsets/mixins.py +35 -0
  169. wbcrm/viewsets/previews/__init__.py +1 -0
  170. wbcrm/viewsets/previews/activities.py +10 -0
  171. wbcrm/viewsets/products.py +57 -0
  172. wbcrm/viewsets/recurrence.py +27 -0
  173. wbcrm/viewsets/titles/__init__.py +13 -0
  174. wbcrm/viewsets/titles/accounts.py +23 -0
  175. wbcrm/viewsets/titles/activities.py +61 -0
  176. wbcrm/viewsets/titles/products.py +13 -0
  177. wbcrm/viewsets/titles/utils.py +46 -0
  178. wbcrm/workflows/__init__.py +1 -0
  179. wbcrm/workflows/assignee_methods.py +25 -0
  180. wbcrm-1.56.8.dist-info/METADATA +11 -0
  181. wbcrm-1.56.8.dist-info/RECORD +182 -0
  182. wbcrm-1.56.8.dist-info/WHEEL +5 -0
@@ -0,0 +1,32 @@
1
+ # Generated by Django 4.1.8 on 2023-04-25 11:57
2
+
3
+ from django.db import migrations, models
4
+
5
+
6
+ class Migration(migrations.Migration):
7
+ dependencies = [
8
+ ("wbcrm", "0001_initial_squashed_squashed_0032_productcompanyrelationship_alter_product_prospects_and_more"),
9
+ ]
10
+
11
+ operations = [
12
+ migrations.AlterField(
13
+ model_name="activity",
14
+ name="repeat_choice",
15
+ field=models.CharField(
16
+ choices=[
17
+ ("NEVER", "Never"),
18
+ ("RRULE:FREQ=DAILY;INTERVAL=1;WKST=MO;BYDAY=MO,TU,WE,TH,FR", "Business Daily"),
19
+ ("RRULE:FREQ=DAILY", "Daily"),
20
+ ("RRULE:FREQ=WEEKLY", "Weekly"),
21
+ ("RRULE:FREQ=WEEKLY;INTERVAL=2", "Bi-Weekly"),
22
+ ("RRULE:FREQ=MONTHLY", "Monthly"),
23
+ ("RRULE:FREQ=MONTHLY;INTERVAL=3", "Quarterly"),
24
+ ("RRULE:FREQ=YEARLY", "Annually"),
25
+ ],
26
+ default="NEVER",
27
+ help_text="Repeat activity at the specified frequency",
28
+ max_length=56,
29
+ verbose_name="Recurrence Frequency",
30
+ ),
31
+ ),
32
+ ]
@@ -0,0 +1,63 @@
1
+ # Generated by Django 4.1.8 on 2023-04-21 08:27
2
+
3
+ import django_fsm
4
+ from django.db import migrations, models
5
+
6
+
7
+ def move_external_id_in_metadata(apps, schema):
8
+ Activity = apps.get_model("wbcrm", "Activity")
9
+ for activity in Activity.objects.filter(external_id__isnull=False):
10
+ if activity.parent_activity:
11
+ metadata = {"outlook": {"event_id": activity.external_id}}
12
+ else:
13
+ metadata = {"outlook": {"event_uid": activity.external_id}}
14
+ activity.metadata = metadata
15
+ activity.save()
16
+
17
+
18
+ class Migration(migrations.Migration):
19
+ dependencies = [
20
+ ("wbcrm", "0002_alter_activity_repeat_choice"),
21
+ ]
22
+
23
+ operations = [
24
+ migrations.AddField(
25
+ model_name="activity",
26
+ name="exclude_from_propagation",
27
+ field=models.BooleanField(
28
+ default=False,
29
+ help_text="If this is checked, changes will not be propagated on this activity.",
30
+ verbose_name="Exclude occurrence from propagation?",
31
+ ),
32
+ ),
33
+ migrations.AddField(
34
+ model_name="activity",
35
+ name="metadata",
36
+ field=models.JSONField(blank=True, default=dict),
37
+ ),
38
+ migrations.RemoveField(
39
+ model_name="activity",
40
+ name="external_id",
41
+ ),
42
+ migrations.AlterField(
43
+ model_name="activityparticipant",
44
+ name="participation_status",
45
+ field=django_fsm.FSMField(
46
+ choices=[
47
+ ("CANCELLED", "Cancelled"),
48
+ ("MAYBE", "Maybe"),
49
+ ("ATTENDS", "Attends"),
50
+ ("NOTRESPONDED", "Not Responded"),
51
+ ("ATTENDS_DIGITALLY", "Attends Digitally"),
52
+ ],
53
+ default="NOTRESPONDED",
54
+ max_length=50,
55
+ verbose_name="Participation Status",
56
+ ),
57
+ ),
58
+ migrations.RenameField(
59
+ model_name="activity",
60
+ old_name="parent_activity",
61
+ new_name="parent_occurrence",
62
+ ),
63
+ ]
@@ -0,0 +1,28 @@
1
+ # Generated by Django 4.1.10 on 2023-08-16 08:16
2
+
3
+ import django_fsm
4
+ from django.db import migrations
5
+
6
+
7
+ class Migration(migrations.Migration):
8
+ dependencies = [
9
+ ("wbcrm", "0003_remove_activity_external_id_and_more"),
10
+ ]
11
+
12
+ operations = [
13
+ migrations.AlterField(
14
+ model_name="activity",
15
+ name="status",
16
+ field=django_fsm.FSMField(
17
+ choices=[
18
+ ("CANCELLED", "Cancelled"),
19
+ ("PLANNED", "Planned"),
20
+ ("FINISHED", "Finished"),
21
+ ("REVIEWED", "Reviewed"),
22
+ ],
23
+ default="PLANNED",
24
+ max_length=50,
25
+ verbose_name="Status",
26
+ ),
27
+ ),
28
+ ]
@@ -0,0 +1,182 @@
1
+ # Generated by Django 4.1.9 on 2023-07-05 16:48
2
+ import django.contrib.postgres.constraints
3
+ import django.contrib.postgres.fields.ranges
4
+ import django.db.models.deletion
5
+ import django_fsm
6
+ import mptt.fields
7
+ import wbcore.utils.strings
8
+ from django.conf import settings
9
+ from django.contrib.postgres.operations import BtreeGistExtension
10
+ from django.db import migrations, models
11
+
12
+
13
+ class Migration(migrations.Migration):
14
+ dependencies = [
15
+ migrations.swappable_dependency(settings.AUTH_USER_MODEL),
16
+ ("directory", "0004_entry_is_draft_entry"),
17
+ ("wbcrm", "0004_alter_activity_status"),
18
+ ]
19
+
20
+ operations = [
21
+ BtreeGistExtension(),
22
+ migrations.CreateModel(
23
+ name="Account",
24
+ fields=[
25
+ ("reference_id", models.PositiveIntegerField(unique=True)),
26
+ ("id", models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name="ID")),
27
+ ("computed_str", models.CharField(blank=True, max_length=512, null=True, verbose_name="Name")),
28
+ ("is_active", models.BooleanField(default=True)),
29
+ ("deletion_datetime", models.DateTimeField(blank=True, null=True)),
30
+ ("title", models.CharField(max_length=255, verbose_name="Title")),
31
+ (
32
+ "status",
33
+ django_fsm.FSMField(
34
+ choices=[("PENDING", "Pending"), ("OPEN", "Open"), ("CLOSE", "Close")],
35
+ default="CLOSE",
36
+ max_length=50,
37
+ verbose_name="Status",
38
+ ),
39
+ ),
40
+ (
41
+ "is_terminal_account",
42
+ models.BooleanField(
43
+ default=False,
44
+ help_text="If true, sales or revenue can happen in this account",
45
+ verbose_name="Terminal Account",
46
+ ),
47
+ ),
48
+ (
49
+ "is_public",
50
+ models.BooleanField(
51
+ default=False,
52
+ help_text="If True, all internal users can access this account",
53
+ verbose_name="Public",
54
+ ),
55
+ ),
56
+ ("lft", models.PositiveIntegerField(editable=False)),
57
+ ("rght", models.PositiveIntegerField(editable=False)),
58
+ ("tree_id", models.PositiveIntegerField(db_index=True, editable=False)),
59
+ ("level", models.PositiveIntegerField(editable=False)),
60
+ (
61
+ "owner",
62
+ models.ForeignKey(
63
+ blank=True,
64
+ null=True,
65
+ on_delete=django.db.models.deletion.PROTECT,
66
+ related_name="accounts",
67
+ to="directory.entry",
68
+ verbose_name="Owner",
69
+ ),
70
+ ),
71
+ (
72
+ "parent",
73
+ mptt.fields.TreeForeignKey(
74
+ blank=True,
75
+ null=True,
76
+ on_delete=django.db.models.deletion.CASCADE,
77
+ related_name="children",
78
+ to="wbcrm.account",
79
+ verbose_name="Parent Account",
80
+ ),
81
+ ),
82
+ ],
83
+ options={
84
+ "verbose_name": "Account",
85
+ "verbose_name_plural": "Accounts",
86
+ "permissions": [("administrate_account", "Administrate Account")],
87
+ },
88
+ bases=(wbcore.utils.strings.ReferenceIDMixin, models.Model),
89
+ ),
90
+ migrations.CreateModel(
91
+ name="AccountRole",
92
+ fields=[
93
+ ("id", models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name="ID")),
94
+ ("computed_str", models.CharField(blank=True, max_length=512, null=True, verbose_name="Name")),
95
+ ("weighting", models.FloatField(default=1, verbose_name="Weight")),
96
+ (
97
+ "is_hidden",
98
+ models.BooleanField(
99
+ default=False,
100
+ help_text="If True, this role is hidden and can be seen only by authorized people",
101
+ verbose_name="Hidden",
102
+ ),
103
+ ),
104
+ (
105
+ "account",
106
+ models.ForeignKey(
107
+ on_delete=django.db.models.deletion.CASCADE,
108
+ related_name="roles",
109
+ to="wbcrm.account",
110
+ verbose_name="Account",
111
+ ),
112
+ ),
113
+ (
114
+ "authorized_hidden_users",
115
+ models.ManyToManyField(
116
+ blank=True,
117
+ help_text="List of users that are allowed to see this hidden account role",
118
+ related_name="authorized_hidden_roles",
119
+ to=settings.AUTH_USER_MODEL,
120
+ verbose_name="authorized Hidden Users",
121
+ ),
122
+ ),
123
+ (
124
+ "entry",
125
+ models.ForeignKey(
126
+ on_delete=django.db.models.deletion.PROTECT,
127
+ related_name="account_roles",
128
+ to="directory.entry",
129
+ verbose_name="Entry",
130
+ ),
131
+ ),
132
+ ],
133
+ options={
134
+ "verbose_name": "Account Role",
135
+ "verbose_name_plural": "Account Roles",
136
+ },
137
+ ),
138
+ migrations.CreateModel(
139
+ name="AccountRoleType",
140
+ fields=[
141
+ ("id", models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name="ID")),
142
+ ("title", models.CharField(max_length=126, verbose_name="Title")),
143
+ ("key", models.CharField(max_length=126, unique=True)),
144
+ ],
145
+ ),
146
+ migrations.CreateModel(
147
+ name="AccountRoleValidity",
148
+ fields=[
149
+ ("id", models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name="ID")),
150
+ ("timespan", django.contrib.postgres.fields.ranges.DateRangeField(verbose_name="Timespan")),
151
+ (
152
+ "role",
153
+ models.ForeignKey(
154
+ on_delete=django.db.models.deletion.CASCADE,
155
+ related_name="validity_set",
156
+ to="wbcrm.accountrole",
157
+ verbose_name="Account Role",
158
+ ),
159
+ ),
160
+ ],
161
+ ),
162
+ migrations.AddField(
163
+ model_name="accountrole",
164
+ name="role_type",
165
+ field=models.ForeignKey(
166
+ on_delete=django.db.models.deletion.PROTECT,
167
+ related_name="roles",
168
+ to="wbcrm.accountroletype",
169
+ verbose_name="Role Type",
170
+ ),
171
+ ),
172
+ migrations.AddConstraint(
173
+ model_name="accountrolevalidity",
174
+ constraint=django.contrib.postgres.constraints.ExclusionConstraint(
175
+ expressions=[("timespan", "&&"), ("role", "=")], name="exclude_overlapping_roles"
176
+ ),
177
+ ),
178
+ migrations.AddConstraint(
179
+ model_name="accountrole",
180
+ constraint=models.UniqueConstraint(fields=("account", "entry"), name="unique_account_entry_relationship"),
181
+ ),
182
+ ]
@@ -0,0 +1,17 @@
1
+ # Generated by Django 4.2.7 on 2023-12-20 08:47
2
+
3
+ from django.db import migrations, models
4
+
5
+
6
+ class Migration(migrations.Migration):
7
+ dependencies = [
8
+ ("wbcrm", "0005_account_accountrole_accountroletype_and_more"),
9
+ ]
10
+
11
+ operations = [
12
+ migrations.AlterField(
13
+ model_name="activity",
14
+ name="location",
15
+ field=models.CharField(blank=True, max_length=2048, null=True, verbose_name="Location"),
16
+ ),
17
+ ]
@@ -0,0 +1,23 @@
1
+ # Generated by Django 4.2.6 on 2024-01-31 08:30
2
+
3
+ import django_fsm
4
+ from django.db import migrations
5
+
6
+
7
+ class Migration(migrations.Migration):
8
+ dependencies = [
9
+ ("wbcrm", "0006_alter_activity_location"),
10
+ ]
11
+
12
+ operations = [
13
+ migrations.AlterField(
14
+ model_name="account",
15
+ name="status",
16
+ field=django_fsm.FSMField(
17
+ choices=[("PENDING", "Pending"), ("OPEN", "Open"), ("CLOSE", "Close")],
18
+ default="OPEN",
19
+ max_length=50,
20
+ verbose_name="Status",
21
+ ),
22
+ ),
23
+ ]
@@ -0,0 +1,16 @@
1
+ # Generated by Django 4.2.9 on 2024-02-20 10:08
2
+
3
+ from django.db import migrations
4
+
5
+
6
+ class Migration(migrations.Migration):
7
+ dependencies = [
8
+ ("wbcrm", "0007_alter_account_status"),
9
+ ]
10
+
11
+ operations = [
12
+ migrations.AlterModelOptions(
13
+ name="activity",
14
+ options={"verbose_name": "Activity", "verbose_name_plural": "Activities"},
15
+ ),
16
+ ]
@@ -0,0 +1,19 @@
1
+ # Generated by Django 4.2.11 on 2024-03-26 10:07
2
+
3
+ from django.db import migrations, models
4
+
5
+
6
+ class Migration(migrations.Migration):
7
+ dependencies = [
8
+ ("wbcrm", "0008_alter_activity_options"),
9
+ ]
10
+
11
+ operations = [
12
+ migrations.AlterField(
13
+ model_name="account",
14
+ name="is_public",
15
+ field=models.BooleanField(
16
+ default=True, help_text="If True, all internal users can access this account", verbose_name="Public"
17
+ ),
18
+ ),
19
+ ]
@@ -0,0 +1,17 @@
1
+ # Generated by Django 5.0.7 on 2024-08-02 13:37
2
+
3
+ from django.db import migrations, models
4
+
5
+
6
+ class Migration(migrations.Migration):
7
+ dependencies = [
8
+ ("wbcrm", "0009_alter_account_is_public"),
9
+ ]
10
+
11
+ operations = [
12
+ migrations.AlterField(
13
+ model_name="account",
14
+ name="reference_id",
15
+ field=models.PositiveIntegerField(blank=True, unique=True),
16
+ ),
17
+ ]
@@ -0,0 +1,22 @@
1
+ # Generated by Django 5.0.8 on 2024-10-02 07:34
2
+
3
+ from django.db import migrations, models
4
+
5
+
6
+ class Migration(migrations.Migration):
7
+ dependencies = [
8
+ ("wbcrm", "0010_alter_account_reference_id"),
9
+ ]
10
+
11
+ operations = [
12
+ migrations.AddField(
13
+ model_name="activity",
14
+ name="summary",
15
+ field=models.TextField(blank=True, default=""),
16
+ ),
17
+ migrations.AddField(
18
+ model_name="activity",
19
+ name="heat",
20
+ field=models.PositiveIntegerField(blank=True, null=True),
21
+ ),
22
+ ]
@@ -0,0 +1,17 @@
1
+ # Generated by Django 5.0.9 on 2024-10-18 13:46
2
+
3
+ from django.db import migrations, models
4
+
5
+
6
+ class Migration(migrations.Migration):
7
+ dependencies = [
8
+ ("wbcrm", "0011_activity_summary"),
9
+ ]
10
+
11
+ operations = [
12
+ migrations.AlterField(
13
+ model_name="activity",
14
+ name="summary",
15
+ field=models.TextField(blank=True, default="", verbose_name="LLM Summary"),
16
+ ),
17
+ ]
@@ -0,0 +1,34 @@
1
+ # Generated by Django 5.0.9 on 2024-10-28 16:07
2
+
3
+ import django.core.validators
4
+ from django.db import migrations, models
5
+
6
+
7
+ class Migration(migrations.Migration):
8
+ dependencies = [
9
+ ("wbcrm", "0012_alter_activity_summary"),
10
+ ]
11
+
12
+ operations = [
13
+ migrations.AddField(
14
+ model_name="account",
15
+ name="action_plan",
16
+ field=models.TextField(blank=True, default=""),
17
+ ),
18
+ migrations.AddField(
19
+ model_name="account",
20
+ name="relationship_status",
21
+ field=models.PositiveIntegerField(
22
+ blank=True,
23
+ default=1,
24
+ help_text="The Relationship Status from 1 to 5. 1 being the cold and 5 being the hot.",
25
+ validators=[django.core.validators.MinValueValidator(1), django.core.validators.MaxValueValidator(5)],
26
+ verbose_name="Relationship Status",
27
+ ),
28
+ ),
29
+ migrations.AddField(
30
+ model_name="account",
31
+ name="relationship_summary",
32
+ field=models.TextField(blank=True, default=""),
33
+ ),
34
+ ]
@@ -0,0 +1,24 @@
1
+ # Generated by Django 5.0.9 on 2024-11-19 14:11
2
+
3
+ import django.core.validators
4
+ from django.db import migrations, models
5
+
6
+
7
+ class Migration(migrations.Migration):
8
+ dependencies = [
9
+ ("wbcrm", "0013_account_action_plan_account_relationship_status_and_more"),
10
+ ]
11
+
12
+ operations = [
13
+ migrations.AlterField(
14
+ model_name="account",
15
+ name="relationship_status",
16
+ field=models.PositiveIntegerField(
17
+ blank=True,
18
+ help_text="The Relationship Status from 1 to 5. 1 being the cold and 5 being the hot.",
19
+ null=True,
20
+ validators=[django.core.validators.MinValueValidator(1), django.core.validators.MaxValueValidator(5)],
21
+ verbose_name="Relationship Status",
22
+ ),
23
+ ),
24
+ ]
@@ -0,0 +1,23 @@
1
+ # Generated by Django 5.0.9 on 2024-12-03 08:41
2
+
3
+ import django.db.models.deletion
4
+ from django.db import migrations, models
5
+
6
+
7
+ class Migration(migrations.Migration):
8
+ dependencies = [
9
+ ("wbcrm", "0014_alter_account_relationship_status"),
10
+ ]
11
+
12
+ operations = [
13
+ migrations.AlterField(
14
+ model_name="activity",
15
+ name="type",
16
+ field=models.ForeignKey(
17
+ on_delete=django.db.models.deletion.PROTECT,
18
+ related_name="activity",
19
+ to="wbcrm.activitytype",
20
+ verbose_name="Type",
21
+ ),
22
+ ),
23
+ ]
@@ -0,0 +1,106 @@
1
+ # Generated by Django 5.0.9 on 2024-12-05 09:15
2
+
3
+ import django.db.models.deletion
4
+ from django.db import migrations, models
5
+ from tqdm import tqdm
6
+ from wbcore.contrib.directory.preferences import get_main_company
7
+
8
+
9
+ def clean_main_company(apps, schema_editor):
10
+ Activity = apps.get_model("wbcrm", "Activity")
11
+ main_company = get_main_company()
12
+ Activity.companies.through.objects.filter(company_id=main_company.id).delete()
13
+
14
+
15
+ def compute_str(company):
16
+ rep = company.computed_str
17
+ if company.customer_status:
18
+ rep += f" ({company.customer_status.title})"
19
+ return rep
20
+
21
+
22
+ def create_through_relations(apps, schema_editor):
23
+ Activity = apps.get_model("wbcrm", "Activity")
24
+ ActivityCompanyThroughModel = apps.get_model("wbcrm", "ActivityCompanyThroughModel")
25
+ qs = Activity.objects.all()
26
+ for a in tqdm(qs, total=qs.count()):
27
+ for c in a.companies.all():
28
+ ActivityCompanyThroughModel.objects.create(
29
+ activity=a, company=c, customer_status=c.customer_status, computed_str=compute_str(c)
30
+ )
31
+
32
+
33
+ class Migration(migrations.Migration):
34
+ dependencies = [
35
+ ("directory", "0009_remove_entry_external_identfier_and_more"),
36
+ ("wbcrm", "0015_alter_activity_type"),
37
+ ]
38
+
39
+ operations = [
40
+ migrations.AlterField(
41
+ model_name="activity",
42
+ name="companies",
43
+ field=models.ManyToManyField(
44
+ blank=True,
45
+ help_text="The list of companies other than the main company that participate in this activity",
46
+ related_name="company_participates",
47
+ to="directory.company",
48
+ verbose_name="Participating Companies",
49
+ ),
50
+ ),
51
+ migrations.RunPython(clean_main_company),
52
+ migrations.CreateModel(
53
+ name="ActivityCompanyThroughModel",
54
+ fields=[
55
+ ("id", models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name="ID")),
56
+ (
57
+ "activity",
58
+ models.ForeignKey(
59
+ on_delete=django.db.models.deletion.CASCADE,
60
+ related_name="activity_companies",
61
+ to="wbcrm.activity",
62
+ verbose_name="Activity",
63
+ ),
64
+ ),
65
+ (
66
+ "company",
67
+ models.ForeignKey(
68
+ on_delete=django.db.models.deletion.CASCADE,
69
+ related_name="activity_companies",
70
+ to="directory.company",
71
+ verbose_name="Company",
72
+ ),
73
+ ),
74
+ (
75
+ "customer_status",
76
+ models.ForeignKey(
77
+ blank=True,
78
+ help_text="The Customer Status at activity creation time",
79
+ null=True,
80
+ on_delete=django.db.models.deletion.SET_NULL,
81
+ related_name="activity_companies",
82
+ to="directory.customerstatus",
83
+ verbose_name="Initial Customer Status",
84
+ ),
85
+ ),
86
+ ("computed_str", models.CharField(blank=True, max_length=512, null=True, verbose_name="Name")),
87
+ ],
88
+ ),
89
+ migrations.RunPython(create_through_relations),
90
+ migrations.RemoveField(
91
+ model_name="activity",
92
+ name="companies",
93
+ ),
94
+ migrations.AddField(
95
+ model_name="activity",
96
+ name="companies",
97
+ field=models.ManyToManyField(
98
+ blank=True,
99
+ help_text="The list of companies other than the main company that participate in this activity",
100
+ related_name="company_participates",
101
+ through="wbcrm.ActivityCompanyThroughModel",
102
+ to="directory.company",
103
+ verbose_name="Participating Companies",
104
+ ),
105
+ ),
106
+ ]
@@ -0,0 +1,40 @@
1
+ # Generated by Django 5.0.10 on 2024-12-06 16:01
2
+
3
+ import django_fsm
4
+ from django.db import migrations, models
5
+
6
+
7
+ class Migration(migrations.Migration):
8
+ dependencies = [
9
+ ("wbcrm", "0016_auto_20241205_1015"),
10
+ ]
11
+
12
+ operations = [
13
+ migrations.CreateModel(
14
+ name="Event",
15
+ fields=[
16
+ ("id", models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name="ID")),
17
+ ("data", models.JSONField(blank=True, default=dict)),
18
+ ("result", models.JSONField(blank=True, default=dict)),
19
+ ("created", models.DateTimeField(auto_now_add=True)),
20
+ ("updated", models.DateTimeField(auto_now=True)),
21
+ ],
22
+ ),
23
+ migrations.AlterField(
24
+ model_name="activityparticipant",
25
+ name="participation_status",
26
+ field=django_fsm.FSMField(
27
+ choices=[
28
+ ("CANCELLED", "Cancelled"),
29
+ ("MAYBE", "Maybe"),
30
+ ("ATTENDS", "Attends"),
31
+ ("NOTRESPONDED", "Not Responded"),
32
+ ("ATTENDS_DIGITALLY", "Attends Digitally"),
33
+ ("PENDING_INVITATION", "Pending Invitation"),
34
+ ],
35
+ default="PENDING_INVITATION",
36
+ max_length=50,
37
+ verbose_name="Participation Status",
38
+ ),
39
+ ),
40
+ ]