wbcrm 1.55.9__py2.py3-none-any.whl → 1.55.10rc0__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 wbcrm might be problematic. Click here for more details.

Files changed (30) hide show
  1. wbcrm/factories/activities.py +0 -2
  2. wbcrm/factories/groups.py +1 -1
  3. wbcrm/models/accounts.py +1 -1
  4. wbcrm/models/activities.py +4 -1
  5. wbcrm/models/events.py +3 -0
  6. wbcrm/models/products.py +3 -0
  7. wbcrm/models/recurrence.py +3 -3
  8. wbcrm/synchronization/activity/backend.py +1 -1
  9. wbcrm/synchronization/activity/backends/google/google_calendar_backend.py +14 -8
  10. wbcrm/synchronization/activity/backends/google/request_utils/internal_to_external/update.py +2 -1
  11. wbcrm/synchronization/activity/backends/google/tests/test_data.py +24 -24
  12. wbcrm/synchronization/activity/backends/google/tests/test_google_backend.py +7 -7
  13. wbcrm/synchronization/activity/backends/outlook/backend.py +6 -2
  14. wbcrm/synchronization/activity/backends/outlook/msgraph.py +5 -7
  15. wbcrm/synchronization/activity/backends/outlook/tests/fixtures.py +1 -1
  16. wbcrm/synchronization/activity/backends/outlook/tests/test_admin.py +4 -4
  17. wbcrm/synchronization/activity/backends/outlook/tests/test_backend.py +18 -18
  18. wbcrm/synchronization/activity/backends/outlook/tests/test_controller.py +2 -2
  19. wbcrm/synchronization/activity/controller.py +4 -2
  20. wbcrm/synchronization/activity/utils.py +1 -1
  21. wbcrm/tasks.py +1 -1
  22. wbcrm/tests/disable_signals.py +11 -1
  23. wbcrm/tests/e2e/test_e2e.py +3 -3
  24. wbcrm/tests/test_recurrence.py +1 -1
  25. wbcrm/tests/test_viewsets.py +0 -1
  26. wbcrm/tests/tests.py +1 -1
  27. wbcrm/workflows/assignee_methods.py +1 -1
  28. {wbcrm-1.55.9.dist-info → wbcrm-1.55.10rc0.dist-info}/METADATA +1 -1
  29. {wbcrm-1.55.9.dist-info → wbcrm-1.55.10rc0.dist-info}/RECORD +30 -30
  30. {wbcrm-1.55.9.dist-info → wbcrm-1.55.10rc0.dist-info}/WHEEL +0 -0
@@ -105,8 +105,6 @@ class ActivityCompanyFactory(ActivityFactory):
105
105
  company = CompanyFactory()
106
106
  # Set global config main_company=company.id
107
107
  global_preferences_registry.manager()["directory__main_company"] = company.id
108
- global_preferences = global_preferences_registry.manager()
109
- assert global_preferences
110
108
  self.companies.add(company)
111
109
 
112
110
 
wbcrm/factories/groups.py CHANGED
@@ -20,5 +20,5 @@ class GroupFactory(factory.django.DjangoModelFactory):
20
20
  for member in extracted:
21
21
  self.members.add(member)
22
22
  else:
23
- for i in range(1, random.randrange(2, 10)):
23
+ for _ in range(1, random.randrange(2, 10)):
24
24
  self.members.add(EntryFactory())
wbcrm/models/accounts.py CHANGED
@@ -480,7 +480,7 @@ class AccountRoleManager(models.Manager):
480
480
  return self.get_queryset().filter_for_user(user, validity_date=validity_date, strict=strict)
481
481
 
482
482
 
483
- class AccountRole(ComplexToStringMixin, models.Model):
483
+ class AccountRole(ComplexToStringMixin):
484
484
  """Model for Account Roles"""
485
485
 
486
486
  class Meta:
@@ -179,7 +179,7 @@ class Activity(Recurrence):
179
179
  WBColor.BLUE_LIGHT.value,
180
180
  WBColor.GREEN_LIGHT.value,
181
181
  ]
182
- return [choice for choice in zip(cls, colors)]
182
+ return [choice for choice in zip(cls, colors, strict=False)]
183
183
 
184
184
  class Importance(models.TextChoices):
185
185
  LOW = "LOW", _("Low")
@@ -1036,6 +1036,9 @@ class ActivityCompanyThroughModel(ComplexToStringMixin, models.Model):
1036
1036
  blank=True,
1037
1037
  )
1038
1038
 
1039
+ def __str__(self) -> str:
1040
+ return f"{self.activity} - {self.company} ({self.customer_status})"
1041
+
1039
1042
  def save(self, *args, **kwargs):
1040
1043
  self.customer_status = self.company.customer_status
1041
1044
  super().save(*args, **kwargs)
wbcrm/models/events.py CHANGED
@@ -10,3 +10,6 @@ class Event(models.Model):
10
10
  result = models.JSONField(default=dict, blank=True)
11
11
  created = models.DateTimeField(auto_now_add=True)
12
12
  updated = models.DateTimeField(auto_now=True)
13
+
14
+ def __str__(self) -> str:
15
+ return str(self.id)
wbcrm/models/products.py CHANGED
@@ -26,6 +26,9 @@ class ProductCompanyRelationship(models.Model):
26
26
  verbose_name = _("Company-Product Relationship")
27
27
  verbose_name_plural = _("Company-Product Relationships")
28
28
 
29
+ def __str__(self) -> str:
30
+ return f"{self.product} - {self.company}"
31
+
29
32
 
30
33
  class Product(ComplexToStringMixin, WBModel):
31
34
  title = models.CharField(
@@ -220,7 +220,7 @@ class Recurrence(CalendarItem):
220
220
  def forward_change(
221
221
  self,
222
222
  allow_reclaiming_root: bool = True,
223
- fields_to_forward: list = [
223
+ fields_to_forward: tuple[str, ...] = (
224
224
  "online_meeting",
225
225
  "visibility",
226
226
  "conference_room",
@@ -233,7 +233,7 @@ class Recurrence(CalendarItem):
233
233
  "location_longitude",
234
234
  "location_latitude",
235
235
  "assigned_to",
236
- ],
236
+ ),
237
237
  period_time_changed: bool = False,
238
238
  ):
239
239
  """
@@ -261,7 +261,7 @@ class Recurrence(CalendarItem):
261
261
  self._handle_recurrence_m2m_forwarding(child)
262
262
  self._meta.model.objects.filter(id=self.id).update(propagate_for_all_children=False)
263
263
 
264
- def forward_deletion(self, child_ids: list["str"] = []):
264
+ def forward_deletion(self, child_ids: tuple["str", ...] = ()):
265
265
  if self.is_recurrent:
266
266
  if self.is_root:
267
267
  occurrences = self.get_recurrent_valid_children()
@@ -83,7 +83,7 @@ class SyncBackend:
83
83
  activity_dto: ActivityDTO,
84
84
  activity_dict: dict[str, Any],
85
85
  only_participants_changed: bool = False,
86
- external_participants: list = [],
86
+ external_participants: list | None = None,
87
87
  keep_external_description: bool = False,
88
88
  ) -> tuple[ActivityDTO, dict[str, Any]]:
89
89
  """
@@ -103,7 +103,9 @@ class GoogleCalendarBackend:
103
103
  credentials = Credentials.from_service_account_info(serivce_account_file, scopes=cls.SCOPES)
104
104
  return build(cls.API_SERVICE_NAME, cls.API_VERSION, credentials=credentials.with_subject(user_email))
105
105
  except Exception as e:
106
- raise ValueError("{msg}{exception}".format(msg=cls.error_messages["service_build_error"], exception=e))
106
+ raise ValueError(
107
+ "{msg}{exception}".format(msg=cls.error_messages["service_build_error"], exception=e)
108
+ ) from e
107
109
 
108
110
  @classmethod
109
111
  def create_external_activity(cls, activity: Activity) -> None:
@@ -127,7 +129,7 @@ class GoogleCalendarBackend:
127
129
  GoogleSyncUtils.add_instance_metadata(activity, google_event_items, metadata, True)
128
130
 
129
131
  except Exception as e:
130
- raise ValueError("{msg}{exception}".format(msg=cls.error_messages["create_error"], exception=e))
132
+ raise ValueError("{msg}{exception}".format(msg=cls.error_messages["create_error"], exception=e)) from e
131
133
 
132
134
  @classmethod
133
135
  def delete_external_activity(cls, activity: Activity) -> None:
@@ -153,7 +155,7 @@ class GoogleCalendarBackend:
153
155
  external_id = google_backend.get("instance", {}).get("id")
154
156
  service.events().delete(calendarId=service_user_mail, eventId=external_id).execute()
155
157
  except Exception as e:
156
- warnings.warn("{msg}{exception}".format(msg=cls.error_messages["delete_error"], exception=e))
158
+ warnings.warn("{msg}{exception}".format(msg=cls.error_messages["delete_error"], exception=e), stacklevel=2)
157
159
 
158
160
  @classmethod
159
161
  def update_external_activity(cls, activity: Activity) -> None:
@@ -186,7 +188,7 @@ class GoogleCalendarBackend:
186
188
  else:
187
189
  update_single_event(service_user_mail, service, activity, updated_event_body)
188
190
  except Exception as e:
189
- raise ValueError("{msg}{exception}".format(msg=cls.error_messages["update_error"], exception=e))
191
+ raise ValueError("{msg}{exception}".format(msg=cls.error_messages["update_error"], exception=e)) from e
190
192
 
191
193
  @classmethod
192
194
  def send_participant_response_external_activity(
@@ -228,7 +230,7 @@ class GoogleCalendarBackend:
228
230
  except Exception as e:
229
231
  raise ValueError(
230
232
  "{msg}{exception}".format(msg=cls.error_messages["send_participant_response_error"], exception=e)
231
- )
233
+ ) from e
232
234
 
233
235
  @classmethod
234
236
  def sync_with_external_calendar(cls, request: HttpRequest) -> HttpResponse:
@@ -293,7 +295,9 @@ class GoogleCalendarBackend:
293
295
  try:
294
296
  events: Dict = request.execute()
295
297
  except Exception as e:
296
- warnings.warn("{msg}{exception}".format(msg=cls.error_messages["could_not_sync"], exception=e))
298
+ warnings.warn(
299
+ "{msg}{exception}".format(msg=cls.error_messages["could_not_sync"], exception=e), stacklevel=2
300
+ )
297
301
  external_event_list += events.get("items", [])
298
302
  page_token = events.get("nextPageToken")
299
303
  if not page_token:
@@ -370,7 +374,7 @@ class GoogleCalendarBackend:
370
374
  user=user.profile.computed_str,
371
375
  exception=e, # type: ignore
372
376
  )
373
- )
377
+ ) from e
374
378
 
375
379
  @classmethod
376
380
  def stop_web_hook(cls, user: User) -> None:
@@ -391,7 +395,9 @@ class GoogleCalendarBackend:
391
395
  user_google_backend: Dict = user.metadata.get("google_backend", {})
392
396
  expiration: str | None = user_google_backend.get("watch", {}).get("expiration")
393
397
  if expiration and datetime.fromtimestamp(int(expiration) / 1000) > now:
394
- warnings.warn(_("Timestamp valid until:") + str(datetime.fromtimestamp(int(expiration) / 1000)))
398
+ warnings.warn(
399
+ _("Timestamp valid until:") + str(datetime.fromtimestamp(int(expiration) / 1000)), stacklevel=2
400
+ )
395
401
  else:
396
402
  raise Exception(_("No valid web hook found"))
397
403
 
@@ -112,7 +112,8 @@ def update_all_recurring_events_from_new_parent(
112
112
  ).first()
113
113
  ):
114
114
  return warnings.warn(
115
- "Could not update the recurring events on google, because the old parent activity was already deleted."
115
+ "Could not update the recurring events on google, because the old parent activity was already deleted.",
116
+ stacklevel=2,
116
117
  )
117
118
 
118
119
  # Get the current parent event from google
@@ -33,38 +33,38 @@ event_list = [
33
33
  ]
34
34
 
35
35
 
36
- class event_service:
37
- def insert(calendarId, body):
38
- return execute_service(calendarId, body)
36
+ class EventService:
37
+ def insert(self, calendarId, body):
38
+ return ExecuteService(calendarId, body)
39
39
 
40
- def instances(calendarId, eventId):
41
- return execute_service(calendarId, eventId)
40
+ def instances(self, calendarId, eventId):
41
+ return ExecuteService(calendarId, eventId)
42
42
 
43
- def delete(calendarId, eventId):
44
- return execute_service(calendarId, eventId)
43
+ def delete(self, calendarId, eventId):
44
+ return ExecuteService(calendarId, eventId)
45
45
 
46
- def update(calendarId, eventId, body=event):
47
- return execute_service(calendarId, eventId)
46
+ def update(self, calendarId, eventId, body=event):
47
+ return ExecuteService(calendarId, eventId)
48
48
 
49
- def patch(calendarId, eventId, body=event):
50
- return execute_service(calendarId, eventId)
49
+ def patch(self, calendarId, eventId, body=event):
50
+ return ExecuteService(calendarId, eventId)
51
51
 
52
- def get(calendarId, eventId, body=event):
53
- return execute_service(calendarId, eventId)
52
+ def get(self, calendarId, eventId, body=event):
53
+ return ExecuteService(calendarId, eventId)
54
54
 
55
- def list(calendarId, pageToken, syncToken):
56
- return execute_service(calendarId, pageToken)
55
+ def list(self, calendarId, pageToken, syncToken):
56
+ return ExecuteService(calendarId, pageToken)
57
57
 
58
- def watch(calendarId, body=event):
59
- return execute_service(calendarId, event)
58
+ def watch(self, calendarId, body=event):
59
+ return ExecuteService(calendarId, event)
60
60
 
61
61
 
62
- class channels_service:
63
- def stop(body):
64
- return execute_service("", body)
62
+ class ChannelsService:
63
+ def stop(self, body):
64
+ return ExecuteService("", body)
65
65
 
66
66
 
67
- class execute_service:
67
+ class ExecuteService:
68
68
  def __init__(self, calendarId, body):
69
69
  self.calendarId = calendarId
70
70
  self.body = body
@@ -73,9 +73,9 @@ class execute_service:
73
73
  return event_data
74
74
 
75
75
 
76
- class service_data:
76
+ class ServiceData:
77
77
  def events(self):
78
- return event_service
78
+ return EventService
79
79
 
80
80
  def channels(self):
81
- return channels_service
81
+ return ChannelsService
@@ -10,7 +10,7 @@
10
10
  # from wbcrm.models import ActivityParticipant
11
11
 
12
12
  # from ..google_calendar_backend import GoogleCalendarBackend
13
- # from .test_data import credentials, event_data, execute_service, service_data
13
+ # from .test_data import credentials, event_data, ExecuteService, ServiceData
14
14
 
15
15
 
16
16
  # class TestInitialisationGoogleCalendarBackend:
@@ -128,7 +128,7 @@
128
128
  # )
129
129
 
130
130
  # mock_service.return_value = service_data()
131
- # with patch.object(execute_service, "execute", return_value=event):
131
+ # with patch.object(ExecuteService, "execute", return_value=event):
132
132
 
133
133
  # backend = GoogleCalendarBackend()
134
134
  # if event:
@@ -186,7 +186,7 @@
186
186
  # )
187
187
 
188
188
  # mock_service.return_value = service_data()
189
- # with patch.object(execute_service, "execute", return_value=None):
189
+ # with patch.object(ExecuteService, "execute", return_value=None):
190
190
 
191
191
  # backend = GoogleCalendarBackend()
192
192
  # backend.delete_external_activity(activity_passed)
@@ -220,7 +220,7 @@
220
220
  # )
221
221
 
222
222
  # mock_service.return_value = service_data()
223
- # with patch.object(execute_service, "execute", return_value=event if event else {"id": None}):
223
+ # with patch.object(ExecuteService, "execute", return_value=event if event else {"id": None}):
224
224
  # backend = GoogleCalendarBackend()
225
225
  # backend.update_external_activity(activity_no_metadata)
226
226
  # backend.update_external_activity(activity_passed)
@@ -253,7 +253,7 @@
253
253
  # activity=activity, participant=activity.creator
254
254
  # ).first()
255
255
  # mock_service.return_value = service_data()
256
- # with patch.object(execute_service, "execute", return_value=event if event else {"id": None}) as mock_execute:
256
+ # with patch.object(ExecuteService, "execute", return_value=event if event else {"id": None}) as mock_execute:
257
257
  # backend = GoogleCalendarBackend()
258
258
  # activityparticipant = activity.activity_participants.filter(participant=person).first()
259
259
  # backend.send_participant_response_external_activity(activityparticipant, response_status)
@@ -295,7 +295,7 @@
295
295
  # user = get_or_create_superuser()
296
296
  # watch = {"id": "fake_id"}
297
297
  # mock_service.return_value = service_data()
298
- # with patch.object(execute_service, "execute", return_value=watch):
298
+ # with patch.object(ExecuteService, "execute", return_value=watch):
299
299
  # GoogleCalendarBackend().set_web_hook(user)
300
300
  # assert user.metadata["google_backend"]["watch"] == watch
301
301
 
@@ -305,7 +305,7 @@
305
305
  # user.save()
306
306
  # watch = {"id": "fake_id"}
307
307
  # mock_service.return_value = service_data()
308
- # with patch.object(execute_service, "execute", return_value=watch):
308
+ # with patch.object(ExecuteService, "execute", return_value=watch):
309
309
  # GoogleCalendarBackend().stop_web_hook(user)
310
310
  # assert user.metadata["google_backend"] == {}
311
311
 
@@ -239,9 +239,11 @@ class OutlookSyncBackend(SyncBackend):
239
239
  activity_dto: ActivityDTO,
240
240
  activity_dict: dict[str, Any] | None = None,
241
241
  only_participants_changed: bool = False,
242
- external_participants: list = [],
242
+ external_participants: list | None = None,
243
243
  keep_external_description: bool = False,
244
244
  ) -> tuple[ActivityDTO, dict[str, Any]]:
245
+ if external_participants is None:
246
+ external_participants = []
245
247
  if old_event := self.get_external_event(activity_dto):
246
248
  if tenant_id := self.msgraph.get_tenant_id(activity_dto.creator.email):
247
249
  activity_dict = activity_dict or old_event
@@ -521,7 +523,9 @@ class OutlookSyncBackend(SyncBackend):
521
523
  except Exception:
522
524
  return False
523
525
 
524
- def _generate_event_metadata(self, tenant_id: str, master_event: dict, occurrence_event: dict = {}):
526
+ def _generate_event_metadata(self, tenant_id: str, master_event: dict, occurrence_event: dict | None = None):
527
+ if occurrence_event is None:
528
+ occurrence_event = {}
525
529
  resource = f"Users/{tenant_id}/Events/{master_event['id']}"
526
530
  metadata = {
527
531
  self.METADATA_KEY: {
@@ -210,11 +210,9 @@ class MicrosoftGraphAPI:
210
210
  return data
211
211
 
212
212
  def get_tenant_id(self, email: str) -> str | None:
213
- try:
213
+ with suppress(Exception):
214
214
  if msuser := self.user(email):
215
215
  return msuser.get("id", None)
216
- except Exception:
217
- pass
218
216
  return None
219
217
 
220
218
  def delta_changes_events(self, tenant_id: str, minutes: int) -> list:
@@ -428,11 +426,11 @@ class MicrosoftGraphAPI:
428
426
  global_preferences = global_preferences_registry.manager()
429
427
  headers["Authorization"] = f'Bearer {global_preferences["wbactivity_sync__outlook_sync_access_token"]}'
430
428
  if method == "POST":
431
- response = requests.post(url, data=data, headers=headers)
429
+ response = requests.post(url, data=data, headers=headers, timeout=10)
432
430
  elif method == "DELETE":
433
- response = requests.delete(url, headers=headers)
431
+ response = requests.delete(url, headers=headers, timeout=10)
434
432
  elif method == "PATCH":
435
- response = requests.patch(url, data=data, headers=headers)
433
+ response = requests.patch(url, data=data, headers=headers, timeout=10)
436
434
  else:
437
- response = requests.get(url, headers=headers, params=params)
435
+ response = requests.get(url, headers=headers, params=params, timeout=10)
438
436
  return response
@@ -5,7 +5,7 @@ from django.contrib.messages import storage
5
5
  from rest_framework.test import APIRequestFactory
6
6
 
7
7
 
8
- class msgraph_fixture:
8
+ class MSGraphFixture:
9
9
  token = None
10
10
  _subscriptions = []
11
11
  _subscription = None
@@ -10,7 +10,7 @@ from wbcore.contrib.authentication.factories import UserFactory
10
10
 
11
11
  from wbcrm.synchronization.activity.admin import UserSyncAdmin
12
12
 
13
- from .fixtures import TestOutlookSyncFixture, msgraph_fixture
13
+ from .fixtures import MSGraphFixture, TestOutlookSyncFixture
14
14
 
15
15
 
16
16
  @pytest.mark.parametrize(
@@ -36,11 +36,11 @@ class TestAdminUserWebhook(TestOutlookSyncFixture):
36
36
  "wbcrm.synchronization.activity.backends.outlook.backend.OutlookSyncBackend"
37
37
  )
38
38
  mock_msgraph.return_value.status_code = status.HTTP_200_OK
39
- mock_msgraph.return_value = msgraph_fixture()
39
+ mock_msgraph.return_value = MSGraphFixture()
40
40
  if credentials:
41
41
  preferences["wbactivity_sync__outlook_sync_credentials"] = credentials_fixture
42
- msgraph_fixture._subscription = subscription
43
- msgraph_fixture.tenant_id = tenant_id
42
+ MSGraphFixture._subscription = subscription
43
+ MSGraphFixture.tenant_id = tenant_id
44
44
  else:
45
45
  mock_msgraph.side_effect = AssertionError("Invalid URL")
46
46
  user = UserFactory(is_superuser=True)
@@ -9,7 +9,7 @@ from wbcore.contrib.authentication.factories import UserFactory
9
9
  from wbcrm.models.activities import Activity
10
10
  from wbcrm.synchronization.activity.backends.outlook.backend import OutlookSyncBackend
11
11
 
12
- from .fixtures import TestOutlookSyncFixture, msgraph_fixture
12
+ from .fixtures import MSGraphFixture, TestOutlookSyncFixture
13
13
 
14
14
 
15
15
  @pytest.mark.django_db
@@ -73,14 +73,14 @@ class TestOutlookSyncBackend(TestOutlookSyncFixture):
73
73
  "", data=json.dumps({"value": [notification_created_fixture]}), content_type="application/json"
74
74
  )
75
75
  self.backend.open()
76
- self.backend.msgraph = msgraph_fixture()
76
+ self.backend.msgraph = MSGraphFixture()
77
77
  if event_found:
78
78
  if is_organizer:
79
- msgraph_fixture.event = organizer_event_fixture_parsed
80
- msgraph_fixture.tenant_id = "fake_tenant_id"
79
+ MSGraphFixture.event = organizer_event_fixture_parsed
80
+ MSGraphFixture.tenant_id = "fake_tenant_id"
81
81
  else:
82
- msgraph_fixture.event = invitation_event_fixture_parsed
83
- msgraph_fixture.event_by_uid = organizer_event_fixture_parsed
82
+ MSGraphFixture.event = invitation_event_fixture_parsed
83
+ MSGraphFixture.event_by_uid = organizer_event_fixture_parsed
84
84
  events = self.backend._get_events_from_request(request1)
85
85
  self.backend.close()
86
86
  assert len(events) == 1
@@ -166,9 +166,9 @@ class TestOutlookSyncBackend(TestOutlookSyncFixture):
166
166
  activity_dto = activity_factory(preceded_by=None)._build_dto()
167
167
  activity_dto2 = activity_factory(preceded_by=None, metadata={self.backend.METADATA_KEY: metadata})._build_dto()
168
168
  self.backend.open()
169
- self.backend.msgraph = msgraph_fixture()
170
- msgraph_fixture.tenant_id = "fake_tenant_id"
171
- msgraph_fixture.event_by_uid = msgraph_fixture.event = {"id": "event_id"}
169
+ self.backend.msgraph = MSGraphFixture()
170
+ MSGraphFixture.tenant_id = "fake_tenant_id"
171
+ MSGraphFixture.event_by_uid = MSGraphFixture.event = {"id": "event_id"}
172
172
  assert (
173
173
  self.backend.get_external_event(activity_dto, master_event)
174
174
  == self.backend.get_external_event(activity_dto, master_event)
@@ -198,9 +198,9 @@ class TestOutlookSyncBackend(TestOutlookSyncFixture):
198
198
  metadata={self.backend.METADATA_KEY: {"organizer_resource": "fake_resource"}},
199
199
  )._build_dto()
200
200
  self.backend.open()
201
- self.backend.msgraph = msgraph_fixture()
202
- msgraph_fixture.tenant_id = "fake_tenant_id"
203
- msgraph_fixture.event_by_uid = msgraph_fixture.event = {
201
+ self.backend.msgraph = MSGraphFixture()
202
+ MSGraphFixture.tenant_id = "fake_tenant_id"
203
+ MSGraphFixture.event_by_uid = MSGraphFixture.event = {
204
204
  "id": "event_id",
205
205
  "attendees": [{"emailAddress": {"address": person._build_dto().email}}],
206
206
  }
@@ -214,8 +214,8 @@ class TestOutlookSyncBackend(TestOutlookSyncFixture):
214
214
  user2 = UserFactory(is_superuser=True)
215
215
  user2.metadata = {self.backend.METADATA_KEY: {"subscription": {"id": "fake_subscription_id"}}}
216
216
  user2.save()
217
- msgraph_fixture._subscription = {"id": "fake_subscription_id"}
218
- mock_msgraph.return_value = msgraph_fixture()
217
+ MSGraphFixture._subscription = {"id": "fake_subscription_id"}
218
+ mock_msgraph.return_value = MSGraphFixture()
219
219
  assert self.backend._is_participant_valid(user2) is True
220
220
  assert self.backend._is_participant_valid(user) is False
221
221
 
@@ -240,8 +240,8 @@ class TestOutlookSyncBackend(TestOutlookSyncFixture):
240
240
  self, activity_factory, organizer_event_fixture_parsed, organizer_master_event_fixture_parsed
241
241
  ):
242
242
  self.backend.open()
243
- self.backend.msgraph = msgraph_fixture()
244
- msgraph_fixture.tenant_id = "fake_tenant_id"
243
+ self.backend.msgraph = MSGraphFixture()
244
+ MSGraphFixture.tenant_id = "fake_tenant_id"
245
245
  activity_dto = activity_factory(preceded_by=None)._build_dto()
246
246
  metadata_list = self.backend._get_metadata_from_event(activity_dto, organizer_event_fixture_parsed)
247
247
  # self.backend._get_metadata_from_event()
@@ -259,8 +259,8 @@ class TestOutlookSyncBackend(TestOutlookSyncFixture):
259
259
 
260
260
  @patch("wbcrm.synchronization.activity.backends.outlook.backend.MicrosoftGraphAPI")
261
261
  def test_renew_web_hooks(self, mock_msgraph):
262
- msgraph_fixture._subscription = {"id": "fake_id_new"}
263
- mock_msgraph.return_value = msgraph_fixture()
262
+ MSGraphFixture._subscription = {"id": "fake_id_new"}
263
+ mock_msgraph.return_value = MSGraphFixture()
264
264
 
265
265
  user1 = UserFactory(is_superuser=True)
266
266
  user2 = UserFactory(is_superuser=True)
@@ -15,7 +15,7 @@ from wbcrm.models import Activity, ActivityParticipant
15
15
  from wbcrm.synchronization.activity.shortcuts import get_backend
16
16
  from wbcrm.typings import User as UserDTO
17
17
 
18
- from .fixtures import TestOutlookSyncFixture, msgraph_fixture
18
+ from .fixtures import MSGraphFixture, TestOutlookSyncFixture
19
19
 
20
20
  User = get_user_model()
21
21
 
@@ -46,7 +46,7 @@ class TestController(TestOutlookSyncFixture):
46
46
  def controller(self, mock_msgraph):
47
47
  controller = get_backend()
48
48
  controller.backend.open()
49
- controller.backend.msgraph = msgraph_fixture()
49
+ controller.backend.msgraph = MSGraphFixture()
50
50
  return controller
51
51
 
52
52
  @pytest.mark.parametrize("type_request", [None, "validationToken", "admin_consent"])
@@ -241,8 +241,8 @@ class ActivityController:
241
241
  self,
242
242
  activity_dto: ActivityDTO,
243
243
  old_activity_dto: ActivityDTO,
244
- update_fields: list = [],
245
- exclude_fields: list = [],
244
+ update_fields: list | None = None,
245
+ exclude_fields: list | None = None,
246
246
  ) -> bool:
247
247
  """
248
248
  Comparison of 2 activities, returns false if they are identical
@@ -252,6 +252,8 @@ class ActivityController:
252
252
 
253
253
  :param exclude_fields: allows you to exclude fields from the comparison list
254
254
  """
255
+ if exclude_fields is None:
256
+ exclude_fields = []
255
257
  if not can_synchronize_activity_description():
256
258
  exclude_fields.append("description")
257
259
  update_fields = (
@@ -20,7 +20,7 @@ def merge_nested_dict(dct: dict, nested_to_merge: dict):
20
20
  """
21
21
  allows to merge 2 nested dictionaries
22
22
  """
23
- for k, v in nested_to_merge.items():
23
+ for k in nested_to_merge.keys():
24
24
  if k in dct:
25
25
  if isinstance(dct[k], dict) and isinstance(nested_to_merge[k], dict): # noqa
26
26
  merge_nested_dict(dct[k], nested_to_merge[k])
wbcrm/tasks.py CHANGED
@@ -144,7 +144,7 @@ def yesterdays_activity_summary(yesterday: date | None = None, report_receiver_u
144
144
  # Create the notification for each person with the right permission
145
145
  for user in User.objects.filter(id__in=report_receiver_user_ids).distinct():
146
146
  context = {
147
- "map_activities": zip(employee_names, activity_lists),
147
+ "map_activities": zip(employee_names, activity_lists, strict=False),
148
148
  "activities_count": internal_activities.count(),
149
149
  "report_date": yesterday.strftime("%d.%m.%Y"),
150
150
  }
@@ -2,7 +2,17 @@ import inspect
2
2
  import re
3
3
  from collections import defaultdict
4
4
 
5
- from django.db.models.signals import *
5
+ from django.db.models.signals import (
6
+ ModelSignal,
7
+ post_delete,
8
+ post_init,
9
+ post_migrate,
10
+ post_save,
11
+ pre_delete,
12
+ pre_init,
13
+ pre_migrate,
14
+ pre_save,
15
+ )
6
16
 
7
17
 
8
18
  class DisableSignals(object):
@@ -24,7 +24,7 @@ from wbcore.contrib.directory.tests.e2e import (
24
24
  set_up_companies,
25
25
  set_up_persons,
26
26
  )
27
- from wbcore.contrib.directory.viewsets.display import CMR_Color
27
+ from wbcore.contrib.directory.viewsets.display import ClientManagerRelationshipColor
28
28
  from wbcore.test import (
29
29
  click_button_by_label,
30
30
  click_close_all_widgets,
@@ -64,7 +64,7 @@ class TestCRMFilters:
64
64
  """
65
65
 
66
66
  # Creating a test user
67
- user: User = SuperUserFactory(plaintext_password=USER_PASSWORD)
67
+ user: User = SuperUserFactory(plaintext_password=USER_PASSWORD) # noqa
68
68
  # Creating three test companies with different last activities.
69
69
  companies = set_up_companies()
70
70
  now = timezone.now()
@@ -349,7 +349,7 @@ class TestCRMRelationShipManagement:
349
349
  assert is_counter_as_expected(selenium, 1)
350
350
  assert is_text_visible(selenium, cmr.client.computed_str)
351
351
  assert is_text_visible(selenium, cmr.relationship_manager.computed_str)
352
- assert does_background_color_match(cmr_element, CMR_Color.DRAFT.value)
352
+ assert does_background_color_match(cmr_element, ClientManagerRelationshipColor.DRAFT.value)
353
353
 
354
354
  # # -----> Edit <----- #
355
355
 
@@ -125,7 +125,7 @@ class TestRecurrenceModel(RecurrenceFixture):
125
125
  else:
126
126
  assert Activity.objects.count() == 3
127
127
  next_occ.refresh_from_db()
128
- next_occ.is_root == was_root
128
+ assert next_occ.is_root == was_root
129
129
 
130
130
  @pytest.mark.parametrize("include_self", [False, True])
131
131
  def test_get_occurrence_start_datetimes(self, occurrences_fixture, include_self, activity_factory):
@@ -388,7 +388,6 @@ class TestActivityModelViewSet:
388
388
  @pytest.mark.parametrize("mvs", [ActivityViewSet])
389
389
  def test_partial_update_activity_instance(self, mvs, activity_factory):
390
390
  activity = activity_factory()
391
- activity.title
392
391
  user = InternalUserFactory(is_active=True, is_superuser=True)
393
392
  request = self.api_factory.patch("", data={"title": "New Title"})
394
393
  request.user = user
wbcrm/tests/tests.py CHANGED
@@ -87,7 +87,7 @@ class ActivityParticipantTestViewSet(TestViewSet):
87
87
 
88
88
 
89
89
  class GenerateActivityParticipantTest(GenerateTest):
90
- def test_modelviewsets(_self, mvs, client):
90
+ def test_modelviewsets(self, mvs, client):
91
91
  my_test = ActivityParticipantTestViewSet(mvs)
92
92
  my_test.execute_test_list_endpoint(client)
93
93
  my_test.execute_test_detail_endpoint()
@@ -11,7 +11,7 @@ from wbcore.contrib.workflow.models import ProcessStep
11
11
  @register_assignee("Activity Assignee")
12
12
  def activity_assignee(process_step: ProcessStep, **kwargs) -> User | None:
13
13
  if hasattr(process_step.process.instance, "assigned_to"):
14
- assignee: Person = getattr(process_step.process.instance, "assigned_to")
14
+ assignee: Person = process_step.process.instance.assigned_to
15
15
  if hasattr(assignee, "user_account"):
16
16
  return assignee.user_account
17
17
  else:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: wbcrm
3
- Version: 1.55.9
3
+ Version: 1.55.10rc0
4
4
  Summary: A workbench module that contains all the functionality related to a customer relationship management.
5
5
  Author-email: Christopher Wittlinger <c.wittlinger@stainly.com>
6
6
  Requires-Dist: django-eventtools==1.*
@@ -2,7 +2,7 @@ wbcrm/__init__.py,sha256=J-j-u0itpEFT6irdmWmixQqYMadNl1X91TxUmoiLHMI,22
2
2
  wbcrm/apps.py,sha256=gT5ZryLzvq-ftpU48IzzQWM5XKn608lHwao7gCZW0Og,85
3
3
  wbcrm/dynamic_preferences_registry.py,sha256=Vy4VSfbHoZnQ71gdEMpZEz-mKWvmTGZfb1eO-UVBqo8,1490
4
4
  wbcrm/preferences.py,sha256=BhM_lWfFMZLhP3D1dE7Ja6ZXo-sF3q_YTyJtYkhPqxM,485
5
- wbcrm/tasks.py,sha256=nz8ng7i_JKDCLlxufPXCPx6ymPcGQfIPCKyDOfw9Q64,13020
5
+ wbcrm/tasks.py,sha256=aPpdsn8d_p4hHq51xu7RlokkODTu1z8JWK0I_Lb_2vo,13034
6
6
  wbcrm/typings.py,sha256=jMX666cYItSYHN9Cb55HoffyPRG49S1dh6xB8AZpBtE,3312
7
7
  wbcrm/urls.py,sha256=5_b4mYUy76KOgSEJL2ggnEnxZpEK7jFzQAAckLNOcxE,2573
8
8
  wbcrm/admin/__init__.py,sha256=P_r2hm3DjYhVik8j5t-bT2qJgi6ExMQ0Afg3BnLZ5yc,227
@@ -15,8 +15,8 @@ wbcrm/configurations/__init__.py,sha256=HxZqIBqrqKuq2jXqMcPhm6ifolRS68bPLqwGBXQ6
15
15
  wbcrm/configurations/base.py,sha256=qVFKdPTHlOgKGUqug5nJEJXcqmJXru9xHfNT1Oh4bpM,700
16
16
  wbcrm/factories/__init__.py,sha256=fwUa03U-RhiWNbfwFY4VBpcjnFiCu2KViAAalw4mOOQ,451
17
17
  wbcrm/factories/accounts.py,sha256=-oU9auFrwC3NuxRX1J4eC7IQVp1EUbEAiCH8J2GjtTc,1648
18
- wbcrm/factories/activities.py,sha256=Nb5ysYxhAguePn6aSdFrNqAScpaZ-OezH-q6ODFlLDE,4116
19
- wbcrm/factories/groups.py,sha256=OWmGk-H9zEnLOo_5oe4czSVvAUUOfrpUmVHgG9xvtak,621
18
+ wbcrm/factories/activities.py,sha256=k3qVuRf3r2jemqP2CiOheosBgMjjfameres8KoTQ_3U,4015
19
+ wbcrm/factories/groups.py,sha256=frjVUFR3OeQy9ItNHFhYuf6kdZXzC3-bx4wl2-7b7hk,621
20
20
  wbcrm/factories/products.py,sha256=UuhCaSZsrmIA8ccj80gAaNNlAmhcKLjwDwNOvE3BHro,244
21
21
  wbcrm/filters/__init__.py,sha256=ZX47xCq18N_FTvvFCk2mIlFoValKFaTcxw9xv8qdn0E,305
22
22
  wbcrm/filters/accounts.py,sha256=WwBNxXnyevdP_k7yHCgy-5eM-ILc8MgVTltPcAmu760,2738
@@ -52,12 +52,12 @@ wbcrm/migrations/0016_auto_20241205_1015.py,sha256=E82BmOegfyJmmmaKemL_bT2OEVywi
52
52
  wbcrm/migrations/0017_event.py,sha256=PzhAVAa2z4itzctQBz-6i__aRDh3TDe029F8leE34W0,1422
53
53
  wbcrm/migrations/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
54
54
  wbcrm/models/__init__.py,sha256=23U2eBeZStYgUKSGfi3q88JtfqfbNTk7MbnLEAGw1gk,287
55
- wbcrm/models/accounts.py,sha256=Wtr8QtHWSnkVmbdZqY64kQJaZ5UDqSfkIKSUaqxBirI,25435
56
- wbcrm/models/activities.py,sha256=f_BQ-NXCIILzK5C0ST287Ai78oHClAIVcsCCXHfln-w,53828
57
- wbcrm/models/events.py,sha256=jUHArKuZlPzMXpzwrtxM0fI6POF2-ETybtphjPQxqqA,393
55
+ wbcrm/models/accounts.py,sha256=Stqn4NIzCS7fxHmVkHea2fA6rL_ng3nrES804al3n88,25421
56
+ wbcrm/models/activities.py,sha256=oAsGIVc8CA97-JoP4qghWoe7at8ho7ySzT8TfuSwbLk,53949
57
+ wbcrm/models/events.py,sha256=JuGfmMZOVoszK3C6uHUVEWXNOUh8xOnoZAteCPRTAPM,452
58
58
  wbcrm/models/groups.py,sha256=att5YADwTLoI5NmSoiMhOBJ8qyBbdKubPGMI2dXUCf0,4345
59
- wbcrm/models/products.py,sha256=q7BOU3hPGZwolVfOPkkAFhGYYBRDGHU8ldKui9FAMPQ,2472
60
- wbcrm/models/recurrence.py,sha256=ZleraEXTzYzJmpIpRRBdzfKoyZClLGOAxcIwL3bsh44,11999
59
+ wbcrm/models/products.py,sha256=iz6eGDvZEglieWUJDpTAJwHEJLu_rXg_ciGx32haVSk,2553
60
+ wbcrm/models/recurrence.py,sha256=Qn-pUv7t2XW2jClB-yPwe5eQW28WFbuqZlnFqdjsO9o,12016
61
61
  wbcrm/models/llm/activity_summaries.py,sha256=o4qFb21YZxXP7wz3a_uCkbGCiz4ZGF_pz8RJzhfKfVo,1527
62
62
  wbcrm/models/llm/analyze_relationship.py,sha256=A4oXdOS1C1kydRjccptlsxBsAjFjkH6XV6F7HRmK7Zo,2310
63
63
  wbcrm/report/activity_report.py,sha256=Y2NveP9u6CeXImXtxR4XfZK-2CFBa5CnUG-jx35Msnc,4843
@@ -81,18 +81,18 @@ wbcrm/synchronization/tasks.py,sha256=c_5knbLqXjA7NJicXDU-KVx9Tgogk62vL5LAuEcTdZ
81
81
  wbcrm/synchronization/urls.py,sha256=3zhKivWitCw3BuaN6Ksi2e_WnHGRBL4DFqBx1LHWdmU,164
82
82
  wbcrm/synchronization/activity/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
83
83
  wbcrm/synchronization/activity/admin.py,sha256=QFgm5f1fimNPLRO8a8U1E34yxbs1qbpygj7Pr_5pCHY,2686
84
- wbcrm/synchronization/activity/backend.py,sha256=DVj27wLv5D6YMG_9xlh9CPN7wfgCABa8g9fIjcVMVC0,8299
85
- wbcrm/synchronization/activity/controller.py,sha256=I2kT7eQffTNr_wxPFAKIfy9wfiQKD60BXW9ON7srff4,31403
84
+ wbcrm/synchronization/activity/backend.py,sha256=UnZuOaH_F6R2z7ghcJ6tp_maEyOk9QPTbwfNdL_wLc4,8308
85
+ wbcrm/synchronization/activity/controller.py,sha256=cW8CO1opcv-P1gKaoC42rLJkBcTuvzO4WM2y_N79FeE,31488
86
86
  wbcrm/synchronization/activity/dynamic_preferences_registry.py,sha256=59K5Xq50IRg4yrBUevefi-0jDZtmT3JoVT3qbniJFDQ,4247
87
87
  wbcrm/synchronization/activity/preferences.py,sha256=7grSPy1oECqBK598UP8kO_t7sUNFCv6mRkEmz3LEYng,1009
88
88
  wbcrm/synchronization/activity/shortcuts.py,sha256=pj-HHna2IeD7g3X2U5RJLqXAerE_KW-xNALIDbNNSyo,576
89
89
  wbcrm/synchronization/activity/tasks.py,sha256=NrCjx8WMhdsFwe1PbLwV2tdFBLg-XrnuFJt4yjlv9Ow,607
90
90
  wbcrm/synchronization/activity/urls.py,sha256=yNld96CD88zeWimGbUmuiq5OjTBLEGKpwvF2I25oBD8,168
91
- wbcrm/synchronization/activity/utils.py,sha256=pNXtMRBr-u5vRaonyhkSIYHHzt7q3gEw-VGLBSFXrSI,1427
91
+ wbcrm/synchronization/activity/utils.py,sha256=tMp_Xm3PQ_9XVpqBX_EiUYT7uRSOWe9KN5n4eAecKY4,1423
92
92
  wbcrm/synchronization/activity/views.py,sha256=u-taYW9mdfG3p-GomoUWmRsTs86gxQSK1vT5CBkMidM,1373
93
93
  wbcrm/synchronization/activity/backends/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
94
94
  wbcrm/synchronization/activity/backends/google/__init__.py,sha256=jUjVGaW5aucqtCK-1_dm6M1bI65fwKUnJjxLgB02wD8,108
95
- wbcrm/synchronization/activity/backends/google/google_calendar_backend.py,sha256=4tY9bUoSGlHpoai5KlLW59uuoLo4tjUZzawOZJAbEoQ,19639
95
+ wbcrm/synchronization/activity/backends/google/google_calendar_backend.py,sha256=Qhjzb-97F-lXb_UFd-3lPF2mec5a3iVwkdge2iBqvrE,19814
96
96
  wbcrm/synchronization/activity/backends/google/tasks.py,sha256=vQ-_z6koyAQd6kjp3yCBwCWl5DCEc1iucw-BEobI908,805
97
97
  wbcrm/synchronization/activity/backends/google/typing_informations.py,sha256=7fDaQEok0kzm_5_vrRrMiakFAh2O3j4G09XWPwYSK1I,2655
98
98
  wbcrm/synchronization/activity/backends/google/utils.py,sha256=CN2ooUHf37XPjyV2c_QgGDKmDGrLYlRxVxXqxIotAPw,11577
@@ -100,22 +100,22 @@ wbcrm/synchronization/activity/backends/google/request_utils/__init__.py,sha256=
100
100
  wbcrm/synchronization/activity/backends/google/request_utils/external_to_internal/create.py,sha256=VyAg2iftSO_hyQthX6dtL299cogIFWsmrhE_xOwZQbs,3622
101
101
  wbcrm/synchronization/activity/backends/google/request_utils/external_to_internal/delete.py,sha256=AvhoJx-vzf2RlHtDPwXy4LXQtxSGaTWQXLiHlmlFCtE,3700
102
102
  wbcrm/synchronization/activity/backends/google/request_utils/external_to_internal/update.py,sha256=4AWhTV-Rdtp4RVijULw7JlIr7ewYVLWv4s6SBb4OKuI,7810
103
- wbcrm/synchronization/activity/backends/google/request_utils/internal_to_external/update.py,sha256=XqEfqrLzELrxhCCovP_qvL1FECeiqxhV6caVZHfwRvk,8990
103
+ wbcrm/synchronization/activity/backends/google/request_utils/internal_to_external/update.py,sha256=LAyv4QVNmHonBtzX5jQP9V1UFylUIMy2iXD24UiLIQ0,9017
104
104
  wbcrm/synchronization/activity/backends/google/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
105
105
  wbcrm/synchronization/activity/backends/google/tests/conftest.py,sha256=yLKwA_DjolyFXkU83ePpwxsVbtl5lrXJxYcUFLg-4fs,35
106
- wbcrm/synchronization/activity/backends/google/tests/test_data.py,sha256=X7uwRyRkfM1PWtZ5ycLD_ZY2sxm4V6vZ9L4DV4OAzbI,3156
107
- wbcrm/synchronization/activity/backends/google/tests/test_google_backend.py,sha256=WMhu5rWPBTm2Dh3SET0izTwyn7lx9tlWQtGOyq_Qvtw,15736
106
+ wbcrm/synchronization/activity/backends/google/tests/test_data.py,sha256=AQUmcWcyfAGVlZqKxfnB4wqf6ExAClCbykjpNXqQUd8,3195
107
+ wbcrm/synchronization/activity/backends/google/tests/test_google_backend.py,sha256=b7_ujhyT-rsoR914EFaAHx25G18HUmpE70kakm2tpPo,15728
108
108
  wbcrm/synchronization/activity/backends/google/tests/test_utils.py,sha256=Wv2ld5JrWLW47MzNbIkJCtuXcVGfjXSdWNreJyovXOQ,13521
109
109
  wbcrm/synchronization/activity/backends/outlook/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
110
- wbcrm/synchronization/activity/backends/outlook/backend.py,sha256=m7hsPkWCFYovveBdJHqh8pR1EnJKxrxZeqgLo26VcfY,30708
111
- wbcrm/synchronization/activity/backends/outlook/msgraph.py,sha256=FgczfAD0xvc12Wt1lu0kLQ7RqI4jQ_XTylKKIbSG2Fs,19335
110
+ wbcrm/synchronization/activity/backends/outlook/backend.py,sha256=Pc__TtzqA0bw4K7F_G1siWBEoTtcQY3XZXT5L9k2log,30878
111
+ wbcrm/synchronization/activity/backends/outlook/msgraph.py,sha256=_ND8gSvP-HngN_CDkSTzyVT78i_HRlpgncDuPGTdWWg,19361
112
112
  wbcrm/synchronization/activity/backends/outlook/parser.py,sha256=HWv5dgrltA-26vnBi5Mu8lrckvs5DSAOuQX8Wqmgz7o,19964
113
113
  wbcrm/synchronization/activity/backends/outlook/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
114
114
  wbcrm/synchronization/activity/backends/outlook/tests/conftest.py,sha256=yLKwA_DjolyFXkU83ePpwxsVbtl5lrXJxYcUFLg-4fs,35
115
- wbcrm/synchronization/activity/backends/outlook/tests/fixtures.py,sha256=a9IzbU0L7bWMmGN1fpyI2ddApYVp4HFbBofrsw9Xz1M,25862
116
- wbcrm/synchronization/activity/backends/outlook/tests/test_admin.py,sha256=RFW8rn_N4y0uG2LN0w77YX44s0_W6ej3bozcrk_QJUM,5606
117
- wbcrm/synchronization/activity/backends/outlook/tests/test_backend.py,sha256=7hOTXoRCvubTCE33e0y7FskdahidPFzwjE8cquTHFYk,12763
118
- wbcrm/synchronization/activity/backends/outlook/tests/test_controller.py,sha256=LEWVAuN61jH-no0ZGqZghkk9cUA8jxYvEu9u5hptc7I,11592
115
+ wbcrm/synchronization/activity/backends/outlook/tests/fixtures.py,sha256=0sN290rhSRlyj8CL3EwcRr-OT3UMz-cqcy-Wkrfskks,25861
116
+ wbcrm/synchronization/activity/backends/outlook/tests/test_admin.py,sha256=Xvso5NKYXQOL5GVmeBxpQeq224fhloOAaJM4GKWn0AU,5602
117
+ wbcrm/synchronization/activity/backends/outlook/tests/test_backend.py,sha256=ciyrz_CPvwKawzqeCnt7-PkMe-O9r__uPhmqhOvkpbU,12743
118
+ wbcrm/synchronization/activity/backends/outlook/tests/test_controller.py,sha256=RoguXJxMJrvRziychlvwALkigTRMMyWrZmqXlOPVqd4,11590
119
119
  wbcrm/synchronization/activity/backends/outlook/tests/test_parser.py,sha256=kidB9wMYQsFfyYQdJnip1ZsUEFVErV8t2MqVtBwELAU,8079
120
120
  wbcrm/templates/email/activity.html,sha256=uoIKNky57demmdZU-V3LlMJkRczZa7wOXFRv_8ro-TE,20984
121
121
  wbcrm/templates/email/activity_report.html,sha256=HtJ-vazpz9xy4Lz_EEGxVBZHUTqj4XhKwGu8SZFqU_M,392
@@ -123,24 +123,24 @@ wbcrm/templates/email/daily_summary.html,sha256=Hx-Exj76gNHB5LEGiINcSP6q3brT-NOE
123
123
  wbcrm/templates/email/global_daily_summary.html,sha256=AQIOiXIHRaZRV8lbVTZ3e6v0fhjTTCvYF7Zjj_kr6IE,21096
124
124
  wbcrm/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
125
125
  wbcrm/tests/conftest.py,sha256=3jUv26-_2rAAFFz1lWVQVzBFqg_2EA4LLP8x2S9mjN0,2018
126
- wbcrm/tests/disable_signals.py,sha256=1WboKAR2lETytjH7to-F9fUflI9NYZqHxoyuV6fYU8k,1582
126
+ wbcrm/tests/disable_signals.py,sha256=kgVeTtzItEtLJ7MOVo9KdnRABsMvKBTub-vhHIMKO_M,1727
127
127
  wbcrm/tests/test_assignee_methods.py,sha256=QJVga_qdb_HLVtlJ5C0EWKANr_fOjcRGrFxVrQmDJYs,1663
128
128
  wbcrm/tests/test_chartviewsets.py,sha256=g0wHUh3x9QUYuTq7-AMmEK7e57HMyhmXdV_JvbiywBA,3558
129
129
  wbcrm/tests/test_dto.py,sha256=4VknNYE0aqAUSoCNn-c5QDISHas8fcXuimHq6nk0dMI,2234
130
130
  wbcrm/tests/test_filters.py,sha256=F_IjmPyQhuznOWySedqZ7XxJgH5mGVvqkZhQ7GqOOx8,2569
131
131
  wbcrm/tests/test_models.py,sha256=y-rCwmBeDpkLWiuuxceNkDReDyCwCdh8UfXdJ7M9WiI,10115
132
- wbcrm/tests/test_recurrence.py,sha256=MvNN3ZkTgBBPoBLH8Le5qfkVL9rScIsuQ0--WAt0Ctw,14516
132
+ wbcrm/tests/test_recurrence.py,sha256=OqvzRulu165lHQusNjprnoI8vSSdi-lqQLEFLQjoCnY,14523
133
133
  wbcrm/tests/test_report.py,sha256=VMb_M9b955RgfAfFJ-r6xawnKvyApEq1CvriklRdfuo,825
134
134
  wbcrm/tests/test_serializers.py,sha256=MLdsOhVSwyUUQNrF_M5Um4jET0l74opCNuIzkpuDrBM,7484
135
135
  wbcrm/tests/test_tasks.py,sha256=GN7G_MWV2hCt_2dDTc1nCBE4VTmy5AgOyVqF6zxdUFE,4183
136
- wbcrm/tests/test_viewsets.py,sha256=Fc5nK7dl3h4Cdi9J2a3cjT2twroKWpV_hA3ylxQ3hHQ,50233
137
- wbcrm/tests/tests.py,sha256=dxqnbofgowiHaEZ6Mla8a3LmPelO6G16ZPKGHZSmEXc,4802
136
+ wbcrm/tests/test_viewsets.py,sha256=20vVc4AuEk2dYJ6sWDdfiULTrt11RZDwYWpwXeag3ik,50210
137
+ wbcrm/tests/tests.py,sha256=5Nkg9jOJwPgLYo-x-dNjV_Y9hGDJcAZ1lRahOttRxXU,4801
138
138
  wbcrm/tests/accounts/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
139
139
  wbcrm/tests/accounts/test_models.py,sha256=dxkqGhVqlkI1d9xqQUC-FgS3wUS66ugvw-dr3uIqQLc,18388
140
140
  wbcrm/tests/accounts/test_viewsets.py,sha256=QMaPHg7GZoExOlDYPnT0aPzzEi-mBZhBQP3psfN-HCk,3662
141
141
  wbcrm/tests/e2e/__init__.py,sha256=-6vGUXo06yKKvpNRO0Jy1eocIXblvn4-wWpTFuCNqRI,79
142
142
  wbcrm/tests/e2e/e2e_wbcrm_utility.py,sha256=NB2pQXEzr8-S7cMGOs6w5IrT3gdcuzwz5x3afJi_CJU,3314
143
- wbcrm/tests/e2e/test_e2e.py,sha256=p4elt_MWXWxBy6i8ayKdqTxHARiaozdd9xmi9_orQr4,16520
143
+ wbcrm/tests/e2e/test_e2e.py,sha256=NCAh-ZteI9yNRiS3xLd46HGBf_3zTs9XXwTVHP2VINI,16570
144
144
  wbcrm/viewsets/__init__.py,sha256=aoi2Hry7C6CixqV7ZIVrVPSjrcRcdRkE3zBmm1Va1Qo,668
145
145
  wbcrm/viewsets/accounts.py,sha256=gO7nb4cYtm4qZO5tpcQ2akoH54F6Uq01VFpshq5pdvQ,4458
146
146
  wbcrm/viewsets/activities.py,sha256=ifN6evcgYStW0hCN2v9rWrBQQynkysSTyF2Ccrh5754,12873
@@ -175,7 +175,7 @@ wbcrm/viewsets/titles/activities.py,sha256=4EIDCk1RD0BQxyW7frpO183YpIOHIfXPmXFNV
175
175
  wbcrm/viewsets/titles/products.py,sha256=cFAK5zljjybabk2U0KzPT2PVfV5vmO_UlJd6QlI-zjs,341
176
176
  wbcrm/viewsets/titles/utils.py,sha256=IaHQTmEG2OwIHS1bRv7sjuT950wefUJNi3yvPdrpNEs,1144
177
177
  wbcrm/workflows/__init__.py,sha256=biwXXPkVJugT9Vc1cwbInAUY8EnVmOauxdPz7e_2w_A,32
178
- wbcrm/workflows/assignee_methods.py,sha256=L7ymErtcpFgXdTMTj_lDOVJqsLAGLNT6qMlrkHGuXWM,999
179
- wbcrm-1.55.9.dist-info/METADATA,sha256=oO5cmafuCq6ASEwnMcveLwlrUDGuKtLZsEz8tEXekf8,450
180
- wbcrm-1.55.9.dist-info/WHEEL,sha256=tkmg4JIqwd9H8mL30xA7crRmoStyCtGp0VWshokd1Jc,105
181
- wbcrm-1.55.9.dist-info/RECORD,,
178
+ wbcrm/workflows/assignee_methods.py,sha256=xlCMnY07TVtVt1pqotARLKtYulQIY4qxdCXrbzP9lig,987
179
+ wbcrm-1.55.10rc0.dist-info/METADATA,sha256=A-vVWxzCd2nMrP4_dB2SerFvP30BF1fYkDxnQv7u_HM,454
180
+ wbcrm-1.55.10rc0.dist-info/WHEEL,sha256=tkmg4JIqwd9H8mL30xA7crRmoStyCtGp0VWshokd1Jc,105
181
+ wbcrm-1.55.10rc0.dist-info/RECORD,,