wbintegrator_office365 1.43.1__py2.py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- wbintegrator_office365/__init__.py +1 -0
- wbintegrator_office365/admin.py +209 -0
- wbintegrator_office365/apps.py +5 -0
- wbintegrator_office365/configurations/__init__.py +0 -0
- wbintegrator_office365/configurations/configurations/__init__.py +23 -0
- wbintegrator_office365/dynamic_preferences_registry.py +15 -0
- wbintegrator_office365/factories.py +102 -0
- wbintegrator_office365/filters.py +237 -0
- wbintegrator_office365/importer/__init__.py +3 -0
- wbintegrator_office365/importer/api.py +403 -0
- wbintegrator_office365/importer/disable_signals.py +43 -0
- wbintegrator_office365/importer/parser.py +135 -0
- wbintegrator_office365/kpi_handlers/__init__.py +1 -0
- wbintegrator_office365/kpi_handlers/calls.py +114 -0
- wbintegrator_office365/migrations/0001_initial_squashed_squashed_0003_alter_calendar_owner_alter_calendarevent_organizer_and_more.py +677 -0
- wbintegrator_office365/migrations/0002_remove_calendar_owner_remove_calendarevent_activity_and_more.py +85 -0
- wbintegrator_office365/migrations/0003_alter_event_options.py +20 -0
- wbintegrator_office365/migrations/__init__.py +0 -0
- wbintegrator_office365/models/__init__.py +3 -0
- wbintegrator_office365/models/event.py +623 -0
- wbintegrator_office365/models/subscription.py +144 -0
- wbintegrator_office365/models/tenant.py +62 -0
- wbintegrator_office365/serializers.py +266 -0
- wbintegrator_office365/tasks.py +108 -0
- wbintegrator_office365/templates/admin/tenant_change_list.html +12 -0
- wbintegrator_office365/tests/__init__.py +0 -0
- wbintegrator_office365/tests/conftest.py +28 -0
- wbintegrator_office365/tests/test_admin.py +86 -0
- wbintegrator_office365/tests/test_models.py +65 -0
- wbintegrator_office365/tests/test_tasks.py +318 -0
- wbintegrator_office365/tests/test_views.py +128 -0
- wbintegrator_office365/tests/tests.py +12 -0
- wbintegrator_office365/urls.py +46 -0
- wbintegrator_office365/viewsets/__init__.py +31 -0
- wbintegrator_office365/viewsets/display.py +306 -0
- wbintegrator_office365/viewsets/endpoints.py +52 -0
- wbintegrator_office365/viewsets/menu.py +65 -0
- wbintegrator_office365/viewsets/titles.py +49 -0
- wbintegrator_office365/viewsets/viewsets.py +745 -0
- wbintegrator_office365-1.43.1.dist-info/METADATA +10 -0
- wbintegrator_office365-1.43.1.dist-info/RECORD +42 -0
- wbintegrator_office365-1.43.1.dist-info/WHEEL +5 -0
@@ -0,0 +1 @@
|
|
1
|
+
__version__ = "1.0.0"
|
@@ -0,0 +1,209 @@
|
|
1
|
+
from django.contrib import admin
|
2
|
+
from django.shortcuts import redirect
|
3
|
+
from django.urls import path
|
4
|
+
from wbcore.admin import ExportCsvMixin, ImportCsvMixin
|
5
|
+
from wbintegrator_office365.models.event import fetch_tenantusers
|
6
|
+
from wbintegrator_office365.models.subscription import (
|
7
|
+
resubscribe_as_task,
|
8
|
+
verification_subscriptions,
|
9
|
+
)
|
10
|
+
|
11
|
+
from .models import CallEvent, CallUser, Event, EventLog, Subscription, TenantUser
|
12
|
+
|
13
|
+
|
14
|
+
@admin.register(TenantUser)
|
15
|
+
class TenantUserAdmin(admin.ModelAdmin, ImportCsvMixin, ExportCsvMixin):
|
16
|
+
search_fields = ("tenant_id", "display_name", "mail", "phone", "profile__computed_str", "tenant_organization_id")
|
17
|
+
list_display = (
|
18
|
+
"tenant_id",
|
19
|
+
"display_name",
|
20
|
+
"mail",
|
21
|
+
"phone",
|
22
|
+
"profile",
|
23
|
+
"tenant_organization_id",
|
24
|
+
)
|
25
|
+
change_list_template = "admin/tenant_change_list.html"
|
26
|
+
list_filter = ("is_internal_organization",)
|
27
|
+
readonly_fields = ("is_internal_organization",)
|
28
|
+
|
29
|
+
def get_urls(self):
|
30
|
+
urls = super().get_urls()
|
31
|
+
my_urls = [path("fetch_tenantusers/", self._fetch_tenantusers)]
|
32
|
+
return my_urls + urls
|
33
|
+
|
34
|
+
def _fetch_tenantusers(self, request):
|
35
|
+
datum, count_added = fetch_tenantusers()
|
36
|
+
self.message_user(
|
37
|
+
request, str(len(datum)) + " tenants users found " + str(count_added) + " new tenants users added"
|
38
|
+
)
|
39
|
+
return redirect("..")
|
40
|
+
|
41
|
+
|
42
|
+
@admin.register(EventLog)
|
43
|
+
class EventLogAdmin(admin.ModelAdmin):
|
44
|
+
search_fields = ("id", "change_type", "last_event__resource", "last_event__subscription_id", "id_event")
|
45
|
+
list_display = (
|
46
|
+
"id",
|
47
|
+
"order_received",
|
48
|
+
"change_type",
|
49
|
+
"is_handled",
|
50
|
+
"resource",
|
51
|
+
"created",
|
52
|
+
"changed",
|
53
|
+
"last_event",
|
54
|
+
"id_event",
|
55
|
+
)
|
56
|
+
ordering = ["-id", "-order_received"]
|
57
|
+
list_filter = ("change_type", "created", "changed")
|
58
|
+
|
59
|
+
|
60
|
+
class EventLogTabularInline(admin.TabularInline):
|
61
|
+
model = EventLog
|
62
|
+
fields = ["id", "order_received", "change_type", "is_handled", "resource", "created", "changed"]
|
63
|
+
readonly_fields = ("id", "order_received", "change_type", "resource", "created", "changed")
|
64
|
+
extra = 0
|
65
|
+
autocomplete_fields = ["last_event"]
|
66
|
+
ordering = ["-id", "-order_received"]
|
67
|
+
|
68
|
+
|
69
|
+
@admin.register(Event)
|
70
|
+
class EventAdmin(admin.ModelAdmin):
|
71
|
+
search_fields = (
|
72
|
+
"id",
|
73
|
+
"id_event",
|
74
|
+
"resource",
|
75
|
+
"subscription_id",
|
76
|
+
"tenant_user__display_name",
|
77
|
+
"tenant_user__mail",
|
78
|
+
"tenant_user__phone",
|
79
|
+
"tenant_user__profile__computed_str",
|
80
|
+
"tenant_user__tenant_organization_id",
|
81
|
+
)
|
82
|
+
list_display = (
|
83
|
+
"id",
|
84
|
+
"auto_inc_id",
|
85
|
+
"nb_received",
|
86
|
+
"type",
|
87
|
+
"change_type",
|
88
|
+
"tenant_user",
|
89
|
+
"is_handled",
|
90
|
+
"created",
|
91
|
+
"changed",
|
92
|
+
"uuid_event",
|
93
|
+
"id_event",
|
94
|
+
"subscription_id",
|
95
|
+
)
|
96
|
+
raw_id_fields = ["tenant_user"]
|
97
|
+
ordering = ["-auto_inc_id"]
|
98
|
+
inlines = [EventLogTabularInline]
|
99
|
+
list_filter = ("type", "change_type", "created", "changed")
|
100
|
+
|
101
|
+
|
102
|
+
@admin.register(CallEvent)
|
103
|
+
class CallEventAdmin(admin.ModelAdmin):
|
104
|
+
search_fields = (
|
105
|
+
"id",
|
106
|
+
"event__id",
|
107
|
+
"organizer__tenant_user__display_name",
|
108
|
+
"organizer__tenant_user__mail",
|
109
|
+
"organizer__tenant_user__phone",
|
110
|
+
"organizer__tenant_user__profile__computed_str",
|
111
|
+
"organizer__tenant_user__tenant_organization_id",
|
112
|
+
)
|
113
|
+
list_display = (
|
114
|
+
"id",
|
115
|
+
"event",
|
116
|
+
"organizer",
|
117
|
+
"version",
|
118
|
+
"start",
|
119
|
+
"end",
|
120
|
+
"created",
|
121
|
+
"last_modified",
|
122
|
+
"is_internal_call",
|
123
|
+
)
|
124
|
+
list_filter = ("is_internal_call", "created", "last_modified", "start", "end")
|
125
|
+
|
126
|
+
|
127
|
+
@admin.register(CallUser)
|
128
|
+
class CallUserAdmin(admin.ModelAdmin):
|
129
|
+
search_fields = (
|
130
|
+
"tenant_user__display_name",
|
131
|
+
"tenant_user__mail",
|
132
|
+
"tenant_user__phone",
|
133
|
+
"tenant_user__profile__computed_str",
|
134
|
+
"tenant_user__tenant_organization_id",
|
135
|
+
)
|
136
|
+
list_display = ("id", "tenant_user", "is_guest", "is_phone")
|
137
|
+
list_filter = ("is_guest", "is_phone")
|
138
|
+
|
139
|
+
|
140
|
+
@admin.register(Subscription)
|
141
|
+
class SubscriptionAdmin(admin.ModelAdmin):
|
142
|
+
search_fields = (
|
143
|
+
"id",
|
144
|
+
"subscription_id",
|
145
|
+
"resource",
|
146
|
+
"tenant_user__display_name",
|
147
|
+
"tenant_user__mail",
|
148
|
+
"tenant_user__phone",
|
149
|
+
"tenant_user__profile__computed_str",
|
150
|
+
"tenant_user__tenant_organization_id",
|
151
|
+
)
|
152
|
+
list_display = (
|
153
|
+
"id",
|
154
|
+
"subscription_id",
|
155
|
+
"expiration_date",
|
156
|
+
"type_resource",
|
157
|
+
"tenant_user",
|
158
|
+
"is_enable",
|
159
|
+
"created",
|
160
|
+
"change_type",
|
161
|
+
"resource",
|
162
|
+
"notification_url",
|
163
|
+
)
|
164
|
+
list_filter = ("is_enable", "type_resource", "expiration_date", "created")
|
165
|
+
|
166
|
+
def disable_selected_subscriptions(self, request, queryset):
|
167
|
+
for subscription in queryset:
|
168
|
+
subscription.is_enable = False
|
169
|
+
subscription.save()
|
170
|
+
|
171
|
+
self.message_user(
|
172
|
+
request,
|
173
|
+
"Operation completed, we unsubscribe the subscriptions selected",
|
174
|
+
)
|
175
|
+
|
176
|
+
def verification_selected_subscriptions(self, request, queryset):
|
177
|
+
for subscription in queryset:
|
178
|
+
verification_subscriptions.delay(subscription.id)
|
179
|
+
self.message_user(
|
180
|
+
request,
|
181
|
+
"Verification completed for the subscriptions selected",
|
182
|
+
)
|
183
|
+
|
184
|
+
def renew_selected_subscriptions(self, request, queryset):
|
185
|
+
for subscription in queryset:
|
186
|
+
resubscribe_as_task.delay(subscription.id)
|
187
|
+
self.message_user(request, "Active subscriptions are renewed on microsoft")
|
188
|
+
return redirect("..")
|
189
|
+
|
190
|
+
actions = [disable_selected_subscriptions, verification_selected_subscriptions, renew_selected_subscriptions]
|
191
|
+
|
192
|
+
readonly_fields = [
|
193
|
+
"subscription_id",
|
194
|
+
"change_type",
|
195
|
+
"expiration_date",
|
196
|
+
"notification_url",
|
197
|
+
"resource",
|
198
|
+
"application_id",
|
199
|
+
"creator_id",
|
200
|
+
"client_state",
|
201
|
+
"latest_supported_tls_version",
|
202
|
+
"notification_content_type",
|
203
|
+
"odata_context",
|
204
|
+
"encryption_certificate_id",
|
205
|
+
"encryption_certificate",
|
206
|
+
"include_resource_data",
|
207
|
+
"notification_query_options",
|
208
|
+
"is_enable",
|
209
|
+
]
|
File without changes
|
@@ -0,0 +1,23 @@
|
|
1
|
+
from os import environ
|
2
|
+
|
3
|
+
from configurations import values
|
4
|
+
|
5
|
+
|
6
|
+
class Office365:
|
7
|
+
WBINTEGRATOR_OFFICE365_TENANT_ID = values.Value("", environ_prefix=None)
|
8
|
+
WBINTEGRATOR_OFFICE365_CLIENT_ID = values.Value("", environ_prefix=None)
|
9
|
+
WBINTEGRATOR_OFFICE365_CLIENT_SECRET = values.Value("", environ_prefix=None)
|
10
|
+
WBINTEGRATOR_OFFICE365_REDIRECT_URI = values.Value("", environ_prefix=None)
|
11
|
+
WBINTEGRATOR_OFFICE365_TOKEN_ENDPOINT = values.Value("", environ_prefix=None)
|
12
|
+
WBINTEGRATOR_OFFICE365_NOTIFICATION_URL = values.Value("", environ_prefix=None)
|
13
|
+
WBINTEGRATOR_OFFICE365_GRAPH_API_VERSION = values.Value("", environ_prefix=None)
|
14
|
+
WBINTEGRATOR_OFFICE365_AUTHORITY_PREFIX = values.Value("", environ_prefix=None)
|
15
|
+
WBINTEGRATOR_OFFICE365_GRAPH_URL_PREFIX = values.Value("", environ_prefix=None)
|
16
|
+
|
17
|
+
@property
|
18
|
+
def WBINTEGRATOR_OFFICE365_AUTHORITY(self):
|
19
|
+
return self.WBINTEGRATOR_OFFICE365_AUTHORITY_PREFIX + self.WBINTEGRATOR_OFFICE365_TENANT_ID
|
20
|
+
|
21
|
+
@property
|
22
|
+
def WBINTEGRATOR_OFFICE365_GRAPH_URL(self):
|
23
|
+
return self.WBINTEGRATOR_OFFICE365_GRAPH_URL_PREFIX + self.WBINTEGRATOR_OFFICE365_GRAPH_API_VERSION
|
@@ -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 StringPreference
|
4
|
+
|
5
|
+
general = Section("wbintegrator_office365")
|
6
|
+
|
7
|
+
|
8
|
+
@global_preferences_registry.register
|
9
|
+
class AccesTokenPreference(StringPreference):
|
10
|
+
section = general
|
11
|
+
name = "access_token"
|
12
|
+
default = "0"
|
13
|
+
|
14
|
+
verbose_name = "Access Token"
|
15
|
+
help_text = "The access token obtained from subscriptions Microsoft for authentication"
|
@@ -0,0 +1,102 @@
|
|
1
|
+
import random
|
2
|
+
|
3
|
+
import factory
|
4
|
+
import pytz
|
5
|
+
|
6
|
+
|
7
|
+
class TenantUserFactory(factory.django.DjangoModelFactory):
|
8
|
+
class Meta:
|
9
|
+
model = "wbintegrator_office365.TenantUser"
|
10
|
+
|
11
|
+
tenant_id = factory.Sequence(lambda n: "user_tenant_%d" % n)
|
12
|
+
display_name = factory.Faker("name")
|
13
|
+
mail = factory.Faker("email")
|
14
|
+
phone = factory.Faker("phone_number")
|
15
|
+
profile = factory.SubFactory("wbcore.contrib.directory.factories.PersonFactory")
|
16
|
+
tenant_organization_id = factory.Faker("pystr")
|
17
|
+
|
18
|
+
|
19
|
+
class SubscriptionFactory(factory.django.DjangoModelFactory):
|
20
|
+
class Meta:
|
21
|
+
model = "wbintegrator_office365.Subscription"
|
22
|
+
|
23
|
+
subscription_id = factory.Sequence(lambda n: "subscription%d" % n)
|
24
|
+
expiration_date = factory.Faker("date_time_between", start_date="+2d", end_date="+3d", tzinfo=pytz.utc)
|
25
|
+
change_type = factory.Faker("pystr")
|
26
|
+
notification_url = factory.Faker("url")
|
27
|
+
resource = factory.Faker("uri")
|
28
|
+
application_id = factory.Faker("pystr")
|
29
|
+
creator_id = factory.Faker("pystr")
|
30
|
+
client_state = factory.Faker("pystr")
|
31
|
+
latest_supported_tls_version = factory.Faker("pystr")
|
32
|
+
notification_content_type = factory.Faker("pystr")
|
33
|
+
odata_context = factory.Faker("pystr")
|
34
|
+
encryption_certificate_id = factory.Faker("pystr")
|
35
|
+
encryption_certificate = factory.Faker("pystr")
|
36
|
+
include_resource_data = factory.Faker("pystr")
|
37
|
+
notification_query_options = factory.Faker("pystr")
|
38
|
+
tenant_user = factory.SubFactory(TenantUserFactory)
|
39
|
+
|
40
|
+
|
41
|
+
class EventFactory(factory.django.DjangoModelFactory):
|
42
|
+
class Meta:
|
43
|
+
model = "wbintegrator_office365.Event"
|
44
|
+
|
45
|
+
uuid_event = factory.Sequence(lambda n: "UID%d" % n)
|
46
|
+
id_event = factory.Sequence(lambda n: "ID%d" % n)
|
47
|
+
# type = "CALLRECORD"
|
48
|
+
subscription_id = factory.Sequence(lambda n: "subscription%d" % n)
|
49
|
+
# change_type = "CREATED" #"UPDATED"
|
50
|
+
resource = factory.Faker("uri")
|
51
|
+
tenant_user = factory.SubFactory(TenantUserFactory)
|
52
|
+
|
53
|
+
|
54
|
+
class EventLogFactory(factory.django.DjangoModelFactory):
|
55
|
+
class Meta:
|
56
|
+
model = "wbintegrator_office365.EventLog"
|
57
|
+
|
58
|
+
last_event = factory.SubFactory(EventFactory)
|
59
|
+
id_event = factory.Sequence(lambda n: "event%d" % n)
|
60
|
+
|
61
|
+
|
62
|
+
class CallUserFactory(factory.django.DjangoModelFactory):
|
63
|
+
class Meta:
|
64
|
+
model = "wbintegrator_office365.CallUser"
|
65
|
+
|
66
|
+
acs_user = factory.Faker("pystr")
|
67
|
+
splool_user = factory.Faker("pystr")
|
68
|
+
encrypted = factory.Faker("pystr")
|
69
|
+
on_premises = factory.Faker("pystr")
|
70
|
+
acs_application_instance = factory.Faker("pystr")
|
71
|
+
spool_application_instance = factory.Faker("pystr")
|
72
|
+
application_instance = factory.Faker("pystr")
|
73
|
+
application = factory.Faker("pystr")
|
74
|
+
device = factory.Faker("pystr")
|
75
|
+
tenant_user = factory.SubFactory(TenantUserFactory)
|
76
|
+
is_guest = factory.Faker("pybool")
|
77
|
+
is_phone = factory.Faker("pybool")
|
78
|
+
|
79
|
+
|
80
|
+
class CallEventFactory(factory.django.DjangoModelFactory):
|
81
|
+
class Meta:
|
82
|
+
model = "wbintegrator_office365.CallEvent"
|
83
|
+
django_get_or_create = ["activity"]
|
84
|
+
|
85
|
+
event = factory.SubFactory(EventFactory)
|
86
|
+
version = random.randint(1, 4)
|
87
|
+
type = factory.Faker("pystr")
|
88
|
+
start = factory.Faker("date_time_between", start_date="+2d", end_date="+3d", tzinfo=pytz.utc)
|
89
|
+
end = factory.Faker("date_time_between", start_date="+2d", end_date="+3d", tzinfo=pytz.utc)
|
90
|
+
last_modified = factory.Faker("date_time_between", start_date="+4d", end_date="+5d", tzinfo=pytz.utc)
|
91
|
+
join_web_url = factory.Faker("url")
|
92
|
+
organizer = factory.SubFactory(CallUserFactory)
|
93
|
+
activity = factory.SubFactory("wbcrm.factories.ActivityFactory")
|
94
|
+
is_internal_call = factory.Faker("pybool")
|
95
|
+
|
96
|
+
@factory.post_generation
|
97
|
+
def participants(self, create, extracted, **kwargs):
|
98
|
+
if not create:
|
99
|
+
return
|
100
|
+
if extracted:
|
101
|
+
for participant in extracted:
|
102
|
+
self.participants.add(participant)
|
@@ -0,0 +1,237 @@
|
|
1
|
+
from datetime import date, timedelta
|
2
|
+
|
3
|
+
from psycopg.types.range import DateRange
|
4
|
+
from wbcore import filters as wb_filters
|
5
|
+
from wbhuman_resources.models import EmployeeHumanResource
|
6
|
+
from wbintegrator_office365.models import (
|
7
|
+
CallEvent,
|
8
|
+
CallUser,
|
9
|
+
Event,
|
10
|
+
EventLog,
|
11
|
+
Subscription,
|
12
|
+
TenantUser,
|
13
|
+
)
|
14
|
+
|
15
|
+
|
16
|
+
class TenantUserFilter(wb_filters.FilterSet):
|
17
|
+
class Meta:
|
18
|
+
model = TenantUser
|
19
|
+
fields = {
|
20
|
+
"profile": ["exact"],
|
21
|
+
"display_name": ["exact", "icontains"],
|
22
|
+
"mail": ["exact", "icontains"],
|
23
|
+
"phone": ["exact", "icontains"],
|
24
|
+
"tenant_id": ["exact", "icontains"],
|
25
|
+
"tenant_organization_id": ["exact", "icontains"],
|
26
|
+
"is_internal_organization": ["exact"],
|
27
|
+
}
|
28
|
+
|
29
|
+
|
30
|
+
class SubscriptionFilter(wb_filters.FilterSet):
|
31
|
+
class Meta:
|
32
|
+
model = Subscription
|
33
|
+
fields = {
|
34
|
+
"change_type": ["exact", "icontains"],
|
35
|
+
"subscription_id": ["exact", "icontains"],
|
36
|
+
"expiration_date": ["lte", "gte"],
|
37
|
+
"type_resource": ["exact"],
|
38
|
+
"tenant_user": ["exact"],
|
39
|
+
"is_enable": ["exact"],
|
40
|
+
"created": ["lte", "gte"],
|
41
|
+
}
|
42
|
+
|
43
|
+
|
44
|
+
def current_year(field, request, view):
|
45
|
+
today = date.today()
|
46
|
+
return date(today.year, 1, 1)
|
47
|
+
|
48
|
+
|
49
|
+
class EventFilter(wb_filters.FilterSet):
|
50
|
+
created__gte = wb_filters.DateFilter(
|
51
|
+
label="Created",
|
52
|
+
lookup_expr="gte",
|
53
|
+
field_name="created",
|
54
|
+
method="created_filter",
|
55
|
+
default=current_year,
|
56
|
+
)
|
57
|
+
|
58
|
+
def created_filter(self, queryset, name, value):
|
59
|
+
if value:
|
60
|
+
return queryset.filter(created__gte=value)
|
61
|
+
return queryset
|
62
|
+
|
63
|
+
class Meta:
|
64
|
+
model = Event
|
65
|
+
fields = {
|
66
|
+
"id": ["exact"],
|
67
|
+
"nb_received": ["exact"],
|
68
|
+
"type": ["exact"],
|
69
|
+
"change_type": ["exact"],
|
70
|
+
"created": ["gte", "lte"],
|
71
|
+
"changed": ["gte", "lte"],
|
72
|
+
"tenant_user": ["exact"],
|
73
|
+
"subscription_id": ["icontains", "exact"],
|
74
|
+
"id_event": ["icontains", "exact"],
|
75
|
+
"is_handled": ["exact"],
|
76
|
+
}
|
77
|
+
|
78
|
+
|
79
|
+
class EventLogFilter(wb_filters.FilterSet):
|
80
|
+
class Meta:
|
81
|
+
model = EventLog
|
82
|
+
fields = {
|
83
|
+
"id": ["exact"],
|
84
|
+
"order_received": ["exact"],
|
85
|
+
"last_event": ["exact"],
|
86
|
+
"change_type": ["exact"],
|
87
|
+
"id_event": ["icontains", "exact"],
|
88
|
+
"created": ["gte", "lte"],
|
89
|
+
"changed": ["gte", "lte"],
|
90
|
+
}
|
91
|
+
|
92
|
+
|
93
|
+
class CallEventFilter(wb_filters.FilterSet):
|
94
|
+
change_type = wb_filters.CharFilter(label="Type", lookup_expr="icontains")
|
95
|
+
participants = wb_filters.ModelMultipleChoiceFilter(
|
96
|
+
label="Participants",
|
97
|
+
queryset=CallUser.objects.all(),
|
98
|
+
endpoint=CallUser.get_representation_endpoint(),
|
99
|
+
value_key=CallUser.get_representation_value_key(),
|
100
|
+
label_key=CallUser.get_representation_label_key(),
|
101
|
+
method="filter_participants",
|
102
|
+
)
|
103
|
+
start__gte = wb_filters.DateFilter(
|
104
|
+
label="Start",
|
105
|
+
lookup_expr="gte",
|
106
|
+
field_name="start",
|
107
|
+
method="start_filter",
|
108
|
+
default=current_year,
|
109
|
+
)
|
110
|
+
|
111
|
+
def filter_participants(self, queryset, name, value):
|
112
|
+
if value:
|
113
|
+
return queryset.filter(participants__in=value)
|
114
|
+
return queryset
|
115
|
+
|
116
|
+
def start_filter(self, queryset, name, value):
|
117
|
+
if value:
|
118
|
+
return queryset.filter(start__gte=value)
|
119
|
+
return queryset
|
120
|
+
|
121
|
+
class Meta:
|
122
|
+
model = CallEvent
|
123
|
+
fields = {
|
124
|
+
"event": ["exact"],
|
125
|
+
"organizer": ["exact"],
|
126
|
+
"start": ["gte", "exact", "lte"],
|
127
|
+
"end": ["gte", "exact", "lte"],
|
128
|
+
"created": ["gte", "exact", "lte"],
|
129
|
+
"is_internal_call": ["exact"],
|
130
|
+
}
|
131
|
+
|
132
|
+
|
133
|
+
class CallUserFilter(wb_filters.FilterSet):
|
134
|
+
name_user = wb_filters.CharFilter(label="Question", lookup_expr="icontains")
|
135
|
+
phone = wb_filters.CharFilter(label="Question", lookup_expr="icontains")
|
136
|
+
mail = wb_filters.CharFilter(label="Question", lookup_expr="icontains")
|
137
|
+
|
138
|
+
class Meta:
|
139
|
+
model = CallUser
|
140
|
+
fields = {
|
141
|
+
"tenant_user": ["exact"],
|
142
|
+
"is_phone": ["exact"],
|
143
|
+
"is_guest": ["exact"],
|
144
|
+
}
|
145
|
+
|
146
|
+
|
147
|
+
def previous_month(*args, **kwargs):
|
148
|
+
return date.today() - timedelta(days=30)
|
149
|
+
|
150
|
+
|
151
|
+
def next_day(*args, **kwargs):
|
152
|
+
return date.today() + timedelta(days=1)
|
153
|
+
|
154
|
+
|
155
|
+
class CallEventSummaryGraphFilter(wb_filters.FilterSet):
|
156
|
+
date_range = wb_filters.DateTimeRangeFilter(
|
157
|
+
method="filter_date_range",
|
158
|
+
label="Date Range",
|
159
|
+
required=True,
|
160
|
+
clearable=False,
|
161
|
+
default=lambda f, v, q: DateRange(previous_month(f, v, q), next_day(f, v, q)),
|
162
|
+
)
|
163
|
+
|
164
|
+
employee = wb_filters.ModelChoiceFilter(
|
165
|
+
label="Employee",
|
166
|
+
queryset=EmployeeHumanResource.objects.all(),
|
167
|
+
endpoint=EmployeeHumanResource.get_representation_endpoint(),
|
168
|
+
value_key=EmployeeHumanResource.get_representation_value_key(),
|
169
|
+
label_key=EmployeeHumanResource.get_representation_label_key(),
|
170
|
+
method="filter_employee",
|
171
|
+
)
|
172
|
+
|
173
|
+
call_type = wb_filters.ChoiceFilter(
|
174
|
+
label="Type of call",
|
175
|
+
choices=[("groupCall", "Group Call"), ("peerToPeer", "Peer To Peer")],
|
176
|
+
method="filter_call_type",
|
177
|
+
)
|
178
|
+
|
179
|
+
call_area = wb_filters.ChoiceFilter(
|
180
|
+
label="Call area",
|
181
|
+
choices=[("True", "Internal Call"), ("False", "External Call")],
|
182
|
+
method="filter_call_area",
|
183
|
+
)
|
184
|
+
|
185
|
+
compare_employee = wb_filters.ModelChoiceFilter(
|
186
|
+
label="Compare to an employee",
|
187
|
+
queryset=EmployeeHumanResource.objects.all(),
|
188
|
+
endpoint=EmployeeHumanResource.get_representation_endpoint(),
|
189
|
+
value_key=EmployeeHumanResource.get_representation_value_key(),
|
190
|
+
label_key=EmployeeHumanResource.get_representation_label_key(),
|
191
|
+
method="filter_compare_employee",
|
192
|
+
)
|
193
|
+
|
194
|
+
call_duration = wb_filters.NumberFilter(
|
195
|
+
label="Include calls of at least how many secondes", default=30, method="filter_call_duration", required=False
|
196
|
+
)
|
197
|
+
|
198
|
+
business_day_without_call = wb_filters.BooleanFilter(
|
199
|
+
label="Include business day without call", default=False, method="filter_business_day_without_call"
|
200
|
+
)
|
201
|
+
|
202
|
+
def filter_date_range(self, queryset, name, value):
|
203
|
+
if value:
|
204
|
+
return queryset.filter(start__gte=value.lower, end__lte=value.upper)
|
205
|
+
return queryset
|
206
|
+
|
207
|
+
def filter_employee(self, queryset, name, value):
|
208
|
+
if value:
|
209
|
+
return queryset.filter(
|
210
|
+
participants__tenant_user__profile__computed_str__icontains=value.profile.computed_str
|
211
|
+
)
|
212
|
+
return queryset
|
213
|
+
|
214
|
+
def filter_call_duration(self, queryset, name, value):
|
215
|
+
if value:
|
216
|
+
return queryset.filter(duration_seconds__gte=timedelta(seconds=float(value)))
|
217
|
+
return queryset
|
218
|
+
|
219
|
+
def filter_call_type(self, queryset, name, value):
|
220
|
+
if value:
|
221
|
+
return queryset.filter(type=value)
|
222
|
+
return queryset
|
223
|
+
|
224
|
+
def filter_call_area(self, queryset, name, value):
|
225
|
+
if value is not None:
|
226
|
+
return queryset.filter(is_internal_call=value)
|
227
|
+
return queryset
|
228
|
+
|
229
|
+
def filter_compare_employee(self, queryset, name, value):
|
230
|
+
return queryset
|
231
|
+
|
232
|
+
def filter_business_day_without_call(self, queryset, name, value):
|
233
|
+
return queryset
|
234
|
+
|
235
|
+
class Meta:
|
236
|
+
model = CallEvent
|
237
|
+
fields = {}
|