/
models.py
188 lines (146 loc) · 5.54 KB
/
models.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
from django.contrib.auth.models import Group, User
from django.db import models
from django.utils.translation import ugettext_lazy as _
class Organization(models.Model):
"""
Representation of an organization,
such as FSMPI, FSMB or ASTA.
An organization is defined by a list of user groups,
in our case LDAP groups. It is managed by a list of
users and has a list of depots.
:author: Leo Tappe
:author: Benedikt Seidl
"""
name = models.CharField(max_length=32)
groups = models.ManyToManyField(Group, blank=True)
managers = models.ManyToManyField(User, blank=True)
def managed_by(self, user):
"""
Organizations are managed by superusers and organization managers.
"""
return user.is_superuser or self.managers.filter(id=user.id).exists()
def is_member(self, user):
"""
Checks if the user is in one of the groups defined in this organization.
"""
return self.groups.filter(id__in=user.groups.all()).exists()
@property
def active_depots(self):
"""
Returns all depots in this organization which have the active flag set.
"""
return self.depot_set.filter(active=True)
@staticmethod
def filter_by_user(user):
"""
Filter for organizations managed by the given user
"""
return models.Q(managers__id=user.id)
def __str__(self):
return self.name
class Depot(models.Model):
"""
A depot has a name and many depot managers.
:author: Leo Tappe
:author: Benedikt Seidl
"""
name = models.CharField(max_length=32)
description = models.CharField(max_length=256, blank=True)
organization = models.ForeignKey(Organization, on_delete=models.CASCADE)
manager_users = models.ManyToManyField(User, blank=True)
manager_groups = models.ManyToManyField(Group, blank=True)
active = models.BooleanField(default=True)
def managed_by(self, user):
"""
Depots are managed by superusers, the organization's managers,
any manager user and any user in a manager group.
"""
return (user.is_superuser
or self.organization.managed_by(user)
or self.manager_users.filter(id=user.id).exists()
or self.manager_groups.filter(id__in=user.groups.all()).exists())
def show_internal_items(self, user):
"""
Internal items can be seen by superusers and organization members.
"""
return user.is_superuser or self.organization.is_member(user)
def visible_items(self, user):
"""
Return the list of items the user is allowed to see in this depot.
"""
if self.show_internal_items(user):
return self.active_items.all()
else:
return self.public_items.all()
@property
def managers(self):
"""
The list of users explicitly listed as managers of this depot.
Does not include any organization managers or superusers which are
not added to the depot.
"""
return User.objects.filter(
models.Q(id__in=self.manager_users.all())
| models.Q(groups__in=self.manager_groups.all())
).distinct()
@property
def public_items(self):
"""
List all items with the visibility set to public.
"""
return self.item_set.filter(visibility=Item.VISIBILITY_PUBLIC)
@property
def active_items(self):
return self.item_set.filter(
models.Q(visibility=Item.VISIBILITY_PUBLIC)
| models.Q(visibility=Item.VISIBILITY_INTERNAL)
)
@staticmethod
def filter_by_user(user):
"""
Filter for depots managed by the given user
"""
return (models.Q(organization__managers__id=user.id)
| models.Q(manager_users__id=user.id)
| models.Q(manager_groups__id__in=user.groups.all()))
def __str__(self):
return self.name
class Item(models.Model):
"""
An item describes one or more instances of an object in a depot.
It always belongs to a single depot and has a unique name within the depot.
The location field can be used to roughly describe where
the item can be found in the depot.
Items can either be public or internal which affects the visibility
of the item to users outside of the organization connected to the depot.
The quantity describes how many version of the item exist in the depot.
:author: Leo Tappe
"""
VISIBILITY_PUBLIC = '1'
VISIBILITY_INTERNAL = '2'
VISIBILITY_DELETED = '3'
VISIBILITY_LEVELS = (
(VISIBILITY_PUBLIC, _('public')),
(VISIBILITY_INTERNAL, _('internal')),
(VISIBILITY_DELETED, _('deleted')),
)
name = models.CharField(max_length=32)
description = models.CharField(max_length=1024, blank=True)
quantity = models.PositiveSmallIntegerField()
visibility = models.CharField(max_length=1, choices=VISIBILITY_LEVELS)
location = models.CharField(max_length=256, blank=True)
depot = models.ForeignKey(Depot, on_delete=models.CASCADE)
@staticmethod
def filter_by_user(user):
"""
Filter for items managed by the given user
"""
return (models.Q(depot__organization__managers__id=user.id)
| models.Q(depot__manager_users__id=user.id)
| models.Q(depot__manager_groups__id__in=user.groups.all()))
class Meta:
unique_together = (
('name', 'depot'),
)
def __str__(self):
return self.name