eetlijst-python 0.0.1__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.
- eetlijst/__init__.py +3 -0
- eetlijst/eetlijst.py +37 -0
- eetlijst/exceptions.py +2 -0
- eetlijst/generated/__init__.py +1153 -0
- eetlijst/generated/all_attendances.py +13 -0
- eetlijst/generated/all_events.py +13 -0
- eetlijst/generated/all_expenses.py +13 -0
- eetlijst/generated/all_groups.py +27 -0
- eetlijst/generated/all_settlements.py +13 -0
- eetlijst/generated/all_users_in_group.py +20 -0
- eetlijst/generated/app_status.py +16 -0
- eetlijst/generated/async_base_client.py +393 -0
- eetlijst/generated/automatic_events.py +18 -0
- eetlijst/generated/base_model.py +28 -0
- eetlijst/generated/client.py +1748 -0
- eetlijst/generated/create_expense.py +15 -0
- eetlijst/generated/create_group.py +15 -0
- eetlijst/generated/create_list_item.py +15 -0
- eetlijst/generated/create_many_list_items.py +20 -0
- eetlijst/generated/create_settlement.py +15 -0
- eetlijst/generated/enums.py +555 -0
- eetlijst/generated/exceptions.py +83 -0
- eetlijst/generated/fragments.py +237 -0
- eetlijst/generated/get_attendance.py +17 -0
- eetlijst/generated/get_event.py +15 -0
- eetlijst/generated/get_group.py +20 -0
- eetlijst/generated/get_user.py +13 -0
- eetlijst/generated/get_user_in_group.py +20 -0
- eetlijst/generated/group_total_expense.py +45 -0
- eetlijst/generated/input_types.py +4702 -0
- eetlijst/generated/join_group.py +17 -0
- eetlijst/generated/list_items.py +13 -0
- eetlijst/generated/remove_account.py +16 -0
- eetlijst/generated/settle_unsettled_expenses.py +21 -0
- eetlijst/generated/settlement_expenses.py +13 -0
- eetlijst/generated/update_attendance.py +17 -0
- eetlijst/generated/update_event.py +15 -0
- eetlijst/generated/update_expense.py +20 -0
- eetlijst/generated/update_expense_distribution.py +23 -0
- eetlijst/generated/update_group.py +15 -0
- eetlijst/generated/update_list_item.py +15 -0
- eetlijst/generated/update_many_attendance.py +22 -0
- eetlijst/generated/update_user.py +15 -0
- eetlijst/generated/update_user_in_group.py +17 -0
- eetlijst/generated/update_users_in_group.py +25 -0
- eetlijst/services/__init__.py +9 -0
- eetlijst/services/app/__init__.py +1 -0
- eetlijst/services/app/app.py +20 -0
- eetlijst/services/app/transformers.py +10 -0
- eetlijst/services/event_attendance/__init__.py +1 -0
- eetlijst/services/event_attendance/event_attendance.py +94 -0
- eetlijst/services/event_attendance/transformers.py +58 -0
- eetlijst/services/events/__init__.py +1 -0
- eetlijst/services/events/events.py +148 -0
- eetlijst/services/events/transformers.py +67 -0
- eetlijst/services/expenses/__init__.py +1 -0
- eetlijst/services/expenses/expenses.py +98 -0
- eetlijst/services/expenses/transformers.py +73 -0
- eetlijst/services/expenses/utils.py +31 -0
- eetlijst/services/group_list/__init__.py +1 -0
- eetlijst/services/group_list/group_list.py +95 -0
- eetlijst/services/group_list/transformers.py +38 -0
- eetlijst/services/group_users/__init__.py +1 -0
- eetlijst/services/group_users/group_users.py +130 -0
- eetlijst/services/group_users/transformers.py +84 -0
- eetlijst/services/groups/__init__.py +1 -0
- eetlijst/services/groups/groups.py +84 -0
- eetlijst/services/groups/transformers.py +140 -0
- eetlijst/services/settlements/__init__.py +1 -0
- eetlijst/services/settlements/settlements.py +225 -0
- eetlijst/services/settlements/transformers.py +95 -0
- eetlijst/services/settlements/utils.py +84 -0
- eetlijst/services/users/__init__.py +1 -0
- eetlijst/services/users/transformers.py +103 -0
- eetlijst/services/users/users.py +44 -0
- eetlijst/utils/__init__.py +0 -0
- eetlijst/utils/datetime.py +25 -0
- eetlijst_python-0.0.1.dist-info/METADATA +80 -0
- eetlijst_python-0.0.1.dist-info/RECORD +81 -0
- eetlijst_python-0.0.1.dist-info/WHEEL +5 -0
- eetlijst_python-0.0.1.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
from datetime import datetime
|
|
2
|
+
from typing import Optional
|
|
3
|
+
|
|
4
|
+
from eetlijst.generated.automatic_events import (
|
|
5
|
+
AutomaticEvents,
|
|
6
|
+
AutomaticEventsQueryTodaysEvents,
|
|
7
|
+
)
|
|
8
|
+
from eetlijst.generated.base_model import BaseModel
|
|
9
|
+
from eetlijst.generated.fragments import (
|
|
10
|
+
EventFields,
|
|
11
|
+
EventFieldsLinkedExpenses,
|
|
12
|
+
EventFieldsUser,
|
|
13
|
+
)
|
|
14
|
+
from eetlijst.generated.update_event import UpdateEvent
|
|
15
|
+
|
|
16
|
+
from eetlijst.exceptions import EetlijstException
|
|
17
|
+
|
|
18
|
+
from eetlijst.services.event_attendance.transformers import (
|
|
19
|
+
Attendance,
|
|
20
|
+
transform_attendance,
|
|
21
|
+
)
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
class Event(BaseModel):
|
|
25
|
+
id: str
|
|
26
|
+
group_id: str
|
|
27
|
+
open: bool
|
|
28
|
+
start_date: datetime
|
|
29
|
+
closed_by: str | None
|
|
30
|
+
signup_deadline: datetime | None
|
|
31
|
+
changed_signup_time: bool
|
|
32
|
+
name: str
|
|
33
|
+
description: str | None
|
|
34
|
+
user: EventFieldsUser | None
|
|
35
|
+
created_at: datetime | None
|
|
36
|
+
updated_at: datetime | None
|
|
37
|
+
expenses: list[EventFieldsLinkedExpenses] | None = None
|
|
38
|
+
attendees: list[Attendance] | None = None
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
def transform_automatic_events(
|
|
42
|
+
events: AutomaticEvents,
|
|
43
|
+
) -> AutomaticEventsQueryTodaysEvents:
|
|
44
|
+
if not events or not events.query_todays_events:
|
|
45
|
+
raise EetlijstException("Failed to populate dinners")
|
|
46
|
+
|
|
47
|
+
return events.query_todays_events
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
def transform_event(event: Optional[EventFields]) -> Event:
|
|
51
|
+
if not event:
|
|
52
|
+
raise EetlijstException("Event not found")
|
|
53
|
+
|
|
54
|
+
data = event.model_dump(exclude={"linked_expenses", "event_attendees"})
|
|
55
|
+
data["expenses"] = event.linked_expenses # TODO: add transform_expense
|
|
56
|
+
data["attendees"] = [
|
|
57
|
+
transform_attendance(attendee) for attendee in (event.event_attendees or [])
|
|
58
|
+
]
|
|
59
|
+
|
|
60
|
+
return Event(**data)
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
def transform_update_event(event: UpdateEvent) -> Event:
|
|
64
|
+
if not event or not event.update_eetschema_event_by_pk:
|
|
65
|
+
raise EetlijstException("Failed to update event")
|
|
66
|
+
|
|
67
|
+
return transform_event(event.update_eetschema_event_by_pk)
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
from .expenses import Expenses
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
from dataclasses import dataclass
|
|
2
|
+
from typing import Optional
|
|
3
|
+
|
|
4
|
+
from eetlijst.generated import GraphQlClient, order_by
|
|
5
|
+
from eetlijst.generated.input_types import (
|
|
6
|
+
Boolean_comparison_exp,
|
|
7
|
+
eetschema_expense_bool_exp,
|
|
8
|
+
eetschema_expense_distribution_insert_input,
|
|
9
|
+
eetschema_expense_insert_input,
|
|
10
|
+
eetschema_expense_order_by,
|
|
11
|
+
eetschema_expense_set_input,
|
|
12
|
+
uuid_comparison_exp,
|
|
13
|
+
)
|
|
14
|
+
|
|
15
|
+
from eetlijst.services.expenses.transformers import (
|
|
16
|
+
transform_create_expense,
|
|
17
|
+
transform_expense,
|
|
18
|
+
transform_group_total_expense,
|
|
19
|
+
transform_update_expense,
|
|
20
|
+
)
|
|
21
|
+
from eetlijst.services.settlements import Settlements
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
@dataclass
|
|
25
|
+
class Expenses:
|
|
26
|
+
_client: GraphQlClient
|
|
27
|
+
settlements: Settlements
|
|
28
|
+
|
|
29
|
+
async def get(self, expense_id: str):
|
|
30
|
+
result = await self._client.all_expenses(
|
|
31
|
+
where=eetschema_expense_bool_exp(id=uuid_comparison_exp(_eq=expense_id))
|
|
32
|
+
)
|
|
33
|
+
|
|
34
|
+
return transform_expense(result.eetschema_expense[0])
|
|
35
|
+
|
|
36
|
+
async def all(
|
|
37
|
+
self,
|
|
38
|
+
group_id: str,
|
|
39
|
+
where: Optional[eetschema_expense_bool_exp] = None,
|
|
40
|
+
order: Optional[list[eetschema_expense_order_by]] = None,
|
|
41
|
+
limit: Optional[int] = None,
|
|
42
|
+
):
|
|
43
|
+
if where is not None:
|
|
44
|
+
where_data = where.model_copy(
|
|
45
|
+
update={
|
|
46
|
+
"deleted": Boolean_comparison_exp(_eq=False),
|
|
47
|
+
"group_id": uuid_comparison_exp(_eq=group_id),
|
|
48
|
+
}
|
|
49
|
+
)
|
|
50
|
+
else:
|
|
51
|
+
where_data = eetschema_expense_bool_exp(
|
|
52
|
+
deleted=Boolean_comparison_exp(_eq=False),
|
|
53
|
+
group_id=uuid_comparison_exp(_eq=group_id),
|
|
54
|
+
)
|
|
55
|
+
|
|
56
|
+
order_data = order
|
|
57
|
+
if order_data is None:
|
|
58
|
+
order_data = [eetschema_expense_order_by(created_at=order_by.desc)]
|
|
59
|
+
|
|
60
|
+
result = await self._client.all_expenses(
|
|
61
|
+
where=where_data,
|
|
62
|
+
order=order_data,
|
|
63
|
+
limit=limit,
|
|
64
|
+
)
|
|
65
|
+
|
|
66
|
+
return [transform_expense(expense) for expense in result.eetschema_expense]
|
|
67
|
+
|
|
68
|
+
async def create(self, data: eetschema_expense_insert_input):
|
|
69
|
+
result = await self._client.create_expense(*data)
|
|
70
|
+
return transform_create_expense(result)
|
|
71
|
+
|
|
72
|
+
async def update(self, expense_id: str, data: eetschema_expense_set_input):
|
|
73
|
+
result = await self._client.update_expense(
|
|
74
|
+
expense_id=expense_id,
|
|
75
|
+
set_=data,
|
|
76
|
+
)
|
|
77
|
+
|
|
78
|
+
return transform_update_expense(result)
|
|
79
|
+
|
|
80
|
+
async def update_distribution(
|
|
81
|
+
self,
|
|
82
|
+
expense_id: str,
|
|
83
|
+
data: list[eetschema_expense_distribution_insert_input],
|
|
84
|
+
):
|
|
85
|
+
await self._client.update_expense_distribution(
|
|
86
|
+
expense_id=expense_id,
|
|
87
|
+
objects=data,
|
|
88
|
+
)
|
|
89
|
+
|
|
90
|
+
async def delete(self, expense_id: str):
|
|
91
|
+
return await self.update(
|
|
92
|
+
expense_id=expense_id,
|
|
93
|
+
data=eetschema_expense_set_input(deleted=True),
|
|
94
|
+
)
|
|
95
|
+
|
|
96
|
+
async def group_total(self, group_id: str):
|
|
97
|
+
result = await self._client.group_total_expense(group_id=group_id)
|
|
98
|
+
return transform_group_total_expense(result)
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
from typing import Optional, TypedDict
|
|
2
|
+
|
|
3
|
+
from eetlijst.generated.create_expense import CreateExpense
|
|
4
|
+
from eetlijst.generated.fragments import ExpenseFields
|
|
5
|
+
from eetlijst.generated.group_total_expense import GroupTotalExpense
|
|
6
|
+
from eetlijst.generated.update_expense import UpdateExpense
|
|
7
|
+
|
|
8
|
+
from eetlijst.exceptions import EetlijstException
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class GroupTotalExpenseDict(TypedDict):
|
|
12
|
+
total: int
|
|
13
|
+
expenses: int
|
|
14
|
+
imported: int
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
def transform_expense(expense: Optional[ExpenseFields]) -> ExpenseFields:
|
|
18
|
+
if not expense:
|
|
19
|
+
raise EetlijstException("Expense not found")
|
|
20
|
+
|
|
21
|
+
return expense
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
def transform_create_expense(expense: CreateExpense) -> ExpenseFields:
|
|
25
|
+
if not expense or not expense.insert_eetschema_expense_one:
|
|
26
|
+
raise EetlijstException("Failed to create expense")
|
|
27
|
+
|
|
28
|
+
return transform_expense(expense.insert_eetschema_expense_one)
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
def transform_update_expense(expense: UpdateExpense) -> ExpenseFields:
|
|
32
|
+
if (
|
|
33
|
+
not expense
|
|
34
|
+
or not expense.update_eetschema_expense
|
|
35
|
+
or not expense.update_eetschema_expense.returning
|
|
36
|
+
):
|
|
37
|
+
raise EetlijstException("Failed to update expense")
|
|
38
|
+
|
|
39
|
+
return transform_expense(expense.update_eetschema_expense.returning[0])
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
def transform_group_total_expense(
|
|
43
|
+
result: Optional[GroupTotalExpense],
|
|
44
|
+
) -> GroupTotalExpenseDict:
|
|
45
|
+
if not result:
|
|
46
|
+
return {"total": 0, "expenses": 0, "imported": 0}
|
|
47
|
+
|
|
48
|
+
expenses_total = 0
|
|
49
|
+
if (
|
|
50
|
+
result.eetschema_expense_aggregate
|
|
51
|
+
and result.eetschema_expense_aggregate.aggregate
|
|
52
|
+
and result.eetschema_expense_aggregate.aggregate.sum
|
|
53
|
+
and result.eetschema_expense_aggregate.aggregate.sum.payed_amount is not None
|
|
54
|
+
):
|
|
55
|
+
expenses_total = result.eetschema_expense_aggregate.aggregate.sum.payed_amount
|
|
56
|
+
|
|
57
|
+
imports_total = 0
|
|
58
|
+
if (
|
|
59
|
+
result.eetschema_expense_eetlijst_import_aggregate
|
|
60
|
+
and result.eetschema_expense_eetlijst_import_aggregate.aggregate
|
|
61
|
+
and result.eetschema_expense_eetlijst_import_aggregate.aggregate.sum
|
|
62
|
+
and result.eetschema_expense_eetlijst_import_aggregate.aggregate.sum.payed_amount
|
|
63
|
+
is not None
|
|
64
|
+
):
|
|
65
|
+
expenses_total = (
|
|
66
|
+
result.eetschema_expense_eetlijst_import_aggregate.aggregate.sum.payed_amount
|
|
67
|
+
)
|
|
68
|
+
|
|
69
|
+
return {
|
|
70
|
+
"total": expenses_total + imports_total,
|
|
71
|
+
"expenses": expenses_total,
|
|
72
|
+
"imported": imports_total,
|
|
73
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
from typing import TypedDict
|
|
2
|
+
|
|
3
|
+
from eetlijst.generated.fragments import (
|
|
4
|
+
ExpenseFields,
|
|
5
|
+
ExpenseFieldsExpenseDistributionsUser,
|
|
6
|
+
)
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class UserBalance(TypedDict):
|
|
10
|
+
user: ExpenseFieldsExpenseDistributionsUser
|
|
11
|
+
balance: int
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
def calculate_balances_from_expenses(
|
|
15
|
+
expenses: list[ExpenseFields],
|
|
16
|
+
) -> list[UserBalance]:
|
|
17
|
+
balances: dict[str, UserBalance] = {}
|
|
18
|
+
|
|
19
|
+
for expense in expenses:
|
|
20
|
+
for distribution in expense.expense_distributions:
|
|
21
|
+
user_id = distribution.user.id
|
|
22
|
+
payed_amount = distribution.payed_amount
|
|
23
|
+
|
|
24
|
+
if user_id in balances:
|
|
25
|
+
balances[user_id]["balance"] += payed_amount
|
|
26
|
+
else:
|
|
27
|
+
balances[user_id] = {"user": distribution.user, "balance": payed_amount}
|
|
28
|
+
|
|
29
|
+
result = list(balances.values())
|
|
30
|
+
result.sort(key=lambda item: item["balance"], reverse=True)
|
|
31
|
+
return result
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
from .group_list import GroupList
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
from dataclasses import dataclass
|
|
2
|
+
from typing import Optional
|
|
3
|
+
|
|
4
|
+
from eetlijst.generated import GraphQlClient
|
|
5
|
+
from eetlijst.generated.input_types import (
|
|
6
|
+
eetschema_list_bool_exp,
|
|
7
|
+
eetschema_list_insert_input,
|
|
8
|
+
eetschema_list_order_by,
|
|
9
|
+
eetschema_list_set_input,
|
|
10
|
+
uuid_comparison_exp,
|
|
11
|
+
)
|
|
12
|
+
|
|
13
|
+
from eetlijst.exceptions import EetlijstException
|
|
14
|
+
|
|
15
|
+
from eetlijst.services.group_list.transformers import (
|
|
16
|
+
transform_create_list_item,
|
|
17
|
+
transform_create_many_list_items,
|
|
18
|
+
transform_list_item,
|
|
19
|
+
transform_update_list_item,
|
|
20
|
+
)
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
@dataclass
|
|
24
|
+
class GroupList:
|
|
25
|
+
_client: GraphQlClient
|
|
26
|
+
|
|
27
|
+
async def get(self, item_id: str):
|
|
28
|
+
result = await self._client.list_items(
|
|
29
|
+
where=eetschema_list_bool_exp(id=uuid_comparison_exp(_eq=item_id))
|
|
30
|
+
)
|
|
31
|
+
|
|
32
|
+
return transform_list_item(result.eetschema_list[0])
|
|
33
|
+
|
|
34
|
+
async def items(
|
|
35
|
+
self,
|
|
36
|
+
group_id: str,
|
|
37
|
+
where: Optional[eetschema_list_bool_exp] = None,
|
|
38
|
+
order: Optional[list[eetschema_list_order_by]] = None,
|
|
39
|
+
limit: Optional[int] = None,
|
|
40
|
+
):
|
|
41
|
+
if where is not None:
|
|
42
|
+
where_data = where.model_copy(
|
|
43
|
+
update={
|
|
44
|
+
"group_id": uuid_comparison_exp(_eq=group_id),
|
|
45
|
+
}
|
|
46
|
+
)
|
|
47
|
+
else:
|
|
48
|
+
where_data = eetschema_list_bool_exp(
|
|
49
|
+
group_id=uuid_comparison_exp(_eq=group_id),
|
|
50
|
+
)
|
|
51
|
+
|
|
52
|
+
result = await self._client.list_items(
|
|
53
|
+
where=where_data,
|
|
54
|
+
order=order,
|
|
55
|
+
limit=limit,
|
|
56
|
+
)
|
|
57
|
+
|
|
58
|
+
return [transform_list_item(item) for item in result.eetschema_list]
|
|
59
|
+
|
|
60
|
+
async def create_item(self, data: eetschema_list_insert_input):
|
|
61
|
+
result = await self._client.create_list_item(*data)
|
|
62
|
+
return transform_create_list_item(result)
|
|
63
|
+
|
|
64
|
+
async def create_many_items(self, items: list[eetschema_list_insert_input]):
|
|
65
|
+
result = await self._client.create_many_list_items(items=items)
|
|
66
|
+
return transform_create_many_list_items(result)
|
|
67
|
+
|
|
68
|
+
async def update_item(self, item_id: str, data: eetschema_list_set_input):
|
|
69
|
+
result = await self._client.update_list_item(
|
|
70
|
+
id=item_id,
|
|
71
|
+
set_=data,
|
|
72
|
+
)
|
|
73
|
+
return transform_update_list_item(result)
|
|
74
|
+
|
|
75
|
+
async def toggle_item(self, item_id: str):
|
|
76
|
+
item = await self.get(item_id)
|
|
77
|
+
if not item:
|
|
78
|
+
raise EetlijstException("List item not found")
|
|
79
|
+
|
|
80
|
+
return await self.update_item(
|
|
81
|
+
item_id=item_id,
|
|
82
|
+
data=eetschema_list_set_input(checked=not item.checked),
|
|
83
|
+
)
|
|
84
|
+
|
|
85
|
+
async def check_item(self, item_id: str, state: bool = True):
|
|
86
|
+
return await self.update_item(
|
|
87
|
+
item_id=item_id,
|
|
88
|
+
data=eetschema_list_set_input(checked=state),
|
|
89
|
+
)
|
|
90
|
+
|
|
91
|
+
async def remove_item(self, item_id: str):
|
|
92
|
+
return await self.update_item(
|
|
93
|
+
item_id=item_id,
|
|
94
|
+
data=eetschema_list_set_input(active=False),
|
|
95
|
+
)
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
from typing import Optional
|
|
2
|
+
|
|
3
|
+
from eetlijst.generated.create_list_item import CreateListItem
|
|
4
|
+
from eetlijst.generated.create_many_list_items import CreateManyListItems
|
|
5
|
+
from eetlijst.generated.fragments import ItemFields
|
|
6
|
+
from eetlijst.generated.update_list_item import UpdateListItem
|
|
7
|
+
|
|
8
|
+
from eetlijst.exceptions import EetlijstException
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
def transform_list_item(item: Optional[ItemFields]) -> ItemFields:
|
|
12
|
+
if not item:
|
|
13
|
+
raise EetlijstException("List item not found")
|
|
14
|
+
|
|
15
|
+
return item
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
def transform_create_many_list_items(result: CreateManyListItems):
|
|
19
|
+
if not result.insert_eetschema_list:
|
|
20
|
+
raise EetlijstException("Failed to create list items")
|
|
21
|
+
|
|
22
|
+
return [
|
|
23
|
+
transform_list_item(item) for item in result.insert_eetschema_list.returning
|
|
24
|
+
]
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
def transform_create_list_item(result: CreateListItem):
|
|
28
|
+
if not result.insert_eetschema_list_one:
|
|
29
|
+
raise EetlijstException("Failed to create list item")
|
|
30
|
+
|
|
31
|
+
return transform_list_item(result.insert_eetschema_list_one)
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
def transform_update_list_item(result: UpdateListItem):
|
|
35
|
+
if not result.update_eetschema_list_by_pk:
|
|
36
|
+
raise EetlijstException("Failed to update list item")
|
|
37
|
+
|
|
38
|
+
return transform_list_item(result.update_eetschema_list_by_pk)
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
from .group_users import GroupUsers
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
from dataclasses import dataclass
|
|
2
|
+
from typing import Optional, TypedDict, Union
|
|
3
|
+
|
|
4
|
+
from eetlijst.generated import GraphQlClient, order_by
|
|
5
|
+
from eetlijst.generated.input_types import (
|
|
6
|
+
Boolean_comparison_exp,
|
|
7
|
+
String_comparison_exp,
|
|
8
|
+
eetschema_users_in_group_bool_exp,
|
|
9
|
+
eetschema_users_in_group_order_by,
|
|
10
|
+
eetschema_users_in_group_set_input,
|
|
11
|
+
eetschema_users_in_group_updates,
|
|
12
|
+
uuid_comparison_exp,
|
|
13
|
+
)
|
|
14
|
+
|
|
15
|
+
from eetlijst.services.group_users.transformers import (
|
|
16
|
+
transform_all_users_in_group,
|
|
17
|
+
transform_get_user_in_group,
|
|
18
|
+
transform_join_group,
|
|
19
|
+
transform_update_user_in_group,
|
|
20
|
+
transform_update_users_in_group,
|
|
21
|
+
)
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
class UserOrderItem(TypedDict):
|
|
25
|
+
user_id: str
|
|
26
|
+
order: int
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
@dataclass
|
|
30
|
+
class GroupUsers:
|
|
31
|
+
_client: GraphQlClient
|
|
32
|
+
|
|
33
|
+
async def get(self, group_id: str, user_id: str):
|
|
34
|
+
result = await self._client.get_user_in_group(
|
|
35
|
+
group_id=group_id, user_id=user_id
|
|
36
|
+
)
|
|
37
|
+
return transform_get_user_in_group(result)
|
|
38
|
+
|
|
39
|
+
async def all(
|
|
40
|
+
self,
|
|
41
|
+
group_id: str,
|
|
42
|
+
include_inactive_users: bool = False,
|
|
43
|
+
where: Optional[eetschema_users_in_group_bool_exp] = None,
|
|
44
|
+
order: Optional[list[eetschema_users_in_group_order_by]] = None,
|
|
45
|
+
limit: Optional[int] = None,
|
|
46
|
+
):
|
|
47
|
+
if where is not None:
|
|
48
|
+
update_data: dict[
|
|
49
|
+
str, Union[uuid_comparison_exp, Boolean_comparison_exp]
|
|
50
|
+
] = {"group_id": uuid_comparison_exp(_eq=group_id)}
|
|
51
|
+
if not include_inactive_users:
|
|
52
|
+
update_data["active"] = Boolean_comparison_exp(_eq=True)
|
|
53
|
+
|
|
54
|
+
where_data = where.model_copy(update=update_data)
|
|
55
|
+
else:
|
|
56
|
+
where_data = eetschema_users_in_group_bool_exp(
|
|
57
|
+
group_id=uuid_comparison_exp(_eq=group_id),
|
|
58
|
+
active=(
|
|
59
|
+
None if include_inactive_users else Boolean_comparison_exp(_eq=True)
|
|
60
|
+
),
|
|
61
|
+
)
|
|
62
|
+
|
|
63
|
+
order_data = order or [eetschema_users_in_group_order_by(order=order_by.asc)]
|
|
64
|
+
|
|
65
|
+
result = await self._client.all_users_in_group(
|
|
66
|
+
group_id=group_id,
|
|
67
|
+
where=where_data,
|
|
68
|
+
order=order_data,
|
|
69
|
+
limit=limit,
|
|
70
|
+
)
|
|
71
|
+
|
|
72
|
+
return transform_all_users_in_group(result)
|
|
73
|
+
|
|
74
|
+
async def add(self, group_id: str, user_id: str, invite_id: str):
|
|
75
|
+
result = await self._client.join_group(group_id, user_id, invite_id)
|
|
76
|
+
return transform_join_group(result)
|
|
77
|
+
|
|
78
|
+
async def update(
|
|
79
|
+
self,
|
|
80
|
+
group_id: str,
|
|
81
|
+
user_id: str,
|
|
82
|
+
data: eetschema_users_in_group_set_input,
|
|
83
|
+
):
|
|
84
|
+
result = await self._client.update_user_in_group(
|
|
85
|
+
group_id=group_id, user_id=user_id, set_=data
|
|
86
|
+
)
|
|
87
|
+
|
|
88
|
+
return transform_update_user_in_group(result)
|
|
89
|
+
|
|
90
|
+
async def update_many(
|
|
91
|
+
self,
|
|
92
|
+
updates: list[eetschema_users_in_group_updates],
|
|
93
|
+
):
|
|
94
|
+
result = await self._client.update_users_in_group(updates=updates)
|
|
95
|
+
return transform_update_users_in_group(result)
|
|
96
|
+
|
|
97
|
+
async def remove(self, group_id: str, user_id: str):
|
|
98
|
+
return await self.update(
|
|
99
|
+
group_id=group_id,
|
|
100
|
+
user_id=user_id,
|
|
101
|
+
data=eetschema_users_in_group_set_input(active=False),
|
|
102
|
+
)
|
|
103
|
+
|
|
104
|
+
async def order(
|
|
105
|
+
self,
|
|
106
|
+
group_id: str,
|
|
107
|
+
user_order: list[Union[str, UserOrderItem]],
|
|
108
|
+
offset: int = 0,
|
|
109
|
+
):
|
|
110
|
+
updates: list[eetschema_users_in_group_updates] = []
|
|
111
|
+
|
|
112
|
+
for index, item in enumerate(user_order):
|
|
113
|
+
if isinstance(item, str):
|
|
114
|
+
target_user_id = item
|
|
115
|
+
target_order = index + offset
|
|
116
|
+
else:
|
|
117
|
+
target_user_id = item["user_id"]
|
|
118
|
+
target_order = item["order"] + offset
|
|
119
|
+
|
|
120
|
+
updates.append(
|
|
121
|
+
eetschema_users_in_group_updates(
|
|
122
|
+
where=eetschema_users_in_group_bool_exp(
|
|
123
|
+
group_id=uuid_comparison_exp(_eq=group_id),
|
|
124
|
+
user_id=String_comparison_exp(_eq=target_user_id),
|
|
125
|
+
),
|
|
126
|
+
_set=eetschema_users_in_group_set_input(order=target_order),
|
|
127
|
+
)
|
|
128
|
+
)
|
|
129
|
+
|
|
130
|
+
return await self.update_many(updates)
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
from typing import Optional, TypedDict
|
|
2
|
+
|
|
3
|
+
from eetlijst.generated.all_users_in_group import AllUsersInGroup
|
|
4
|
+
from eetlijst.generated.get_user_in_group import GetUserInGroup
|
|
5
|
+
from eetlijst.generated.join_group import JoinGroup
|
|
6
|
+
from eetlijst.generated.update_user_in_group import UpdateUserInGroup
|
|
7
|
+
from eetlijst.generated.update_users_in_group import UpdateUsersInGroup
|
|
8
|
+
|
|
9
|
+
from eetlijst.exceptions import EetlijstException
|
|
10
|
+
|
|
11
|
+
from eetlijst.services.groups.transformers import (
|
|
12
|
+
UserInGroupResult,
|
|
13
|
+
transform_user_in_group,
|
|
14
|
+
)
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
class JoinGroupResult(TypedDict):
|
|
18
|
+
accepted: bool
|
|
19
|
+
error: Optional[str]
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
class UpdateUsersInGroupResult(TypedDict):
|
|
23
|
+
number_users_in_group: int
|
|
24
|
+
users_in_group: list[UserInGroupResult]
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
def transform_join_group(result: JoinGroup) -> JoinGroupResult:
|
|
28
|
+
if not result.join_group:
|
|
29
|
+
raise EetlijstException("Failed to join group")
|
|
30
|
+
|
|
31
|
+
return {
|
|
32
|
+
"accepted": result.join_group.accepted,
|
|
33
|
+
"error": result.join_group.error,
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
def transform_update_users_in_group(
|
|
38
|
+
result: UpdateUsersInGroup,
|
|
39
|
+
) -> UpdateUsersInGroupResult:
|
|
40
|
+
if not result.update_eetschema_users_in_group_many:
|
|
41
|
+
raise EetlijstException("Failed to update users in group")
|
|
42
|
+
|
|
43
|
+
valid_results = [
|
|
44
|
+
item for item in result.update_eetschema_users_in_group_many if item is not None
|
|
45
|
+
]
|
|
46
|
+
|
|
47
|
+
updated_users_in_group = sum(item.number_users_in_group for item in valid_results)
|
|
48
|
+
users_in_group = [
|
|
49
|
+
transform_user_in_group(user)
|
|
50
|
+
for item in valid_results
|
|
51
|
+
for user in (item.users_in_group or [])
|
|
52
|
+
]
|
|
53
|
+
|
|
54
|
+
return {
|
|
55
|
+
"number_users_in_group": updated_users_in_group,
|
|
56
|
+
"users_in_group": users_in_group,
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
def transform_update_user_in_group(result: UpdateUserInGroup) -> UserInGroupResult:
|
|
61
|
+
if not result.update_eetschema_users_in_group_by_pk:
|
|
62
|
+
raise EetlijstException("Failed to update user in group")
|
|
63
|
+
|
|
64
|
+
return transform_user_in_group(result.update_eetschema_users_in_group_by_pk)
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
def transform_all_users_in_group(result: AllUsersInGroup) -> list[UserInGroupResult]:
|
|
68
|
+
if not result.eetschema_group_by_pk:
|
|
69
|
+
raise EetlijstException("Failed to get users")
|
|
70
|
+
|
|
71
|
+
return [
|
|
72
|
+
transform_user_in_group(user)
|
|
73
|
+
for user in result.eetschema_group_by_pk.users_in_groups
|
|
74
|
+
]
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
def transform_get_user_in_group(result: GetUserInGroup) -> UserInGroupResult:
|
|
78
|
+
if (
|
|
79
|
+
not result.eetschema_group_by_pk
|
|
80
|
+
or not result.eetschema_group_by_pk.users_in_groups
|
|
81
|
+
):
|
|
82
|
+
raise EetlijstException("Failed to get user")
|
|
83
|
+
|
|
84
|
+
return transform_user_in_group(result.eetschema_group_by_pk.users_in_groups[0])
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
from .groups import Groups
|