wbintegrator_office365 1.43.1__py2.py3-none-any.whl
Sign up to get free protection for your applications and to get access to all the features.
- 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 = {}
|