Revision 05617ab9 snf-astakos-app/astakos/im/models.py

b/snf-astakos-app/astakos/im/models.py
683 683
    def owns_project(self, project):
684 684
        return project.owner == self
685 685

  
686
    def is_project_member(self, project):
687
        return project.user_status(self) in [0,1,2,3]
686
    def is_project_member(self, project_or_application):
687
        return self.get_status_in_project(project_or_application) in \
688
                                        ProjectMembership.ASSOCIATED_STATES
688 689

  
689
    def is_project_accepted_member(self, project):
690
        return project.user_status(self) == 2
690
    def is_project_accepted_member(self, project_or_application):
691
        return self.get_status_in_project(project_or_application) in \
692
                                            ProjectMembership.ACCEPTED_STATES
693

  
694
    def get_status_in_project(self, project_or_application):
695
        application = project_or_application
696
        if isinstance(project_or_application, Project):
697
            application = project_or_application.project
698
        return application.user_status(self)
691 699

  
692 700

  
693 701
class AstakosUserAuthProviderManager(models.Manager):
......
1148 1156

  
1149 1157
class ProjectApplicationManager(ForUpdateManager):
1150 1158

  
1151
    def user_projects(self, user):
1159
    def user_visible_projects(self, *filters, **kw_filters):
1160
        return self.filter(Q(state=ProjectApplication.PENDING)|\
1161
                           Q(state=ProjectApplication.APPROVED))
1162

  
1163
    def user_visible_by_last_of_chain(self, *filters, **kw_filters):
1164
        by_chain = self.user_visible_projects(*filters, **kw_filters).values('chain')
1165
        by_chain = by_chain.annotate(last_id=models.Min('id')).values_list('last_id', flat=True)
1166
        return self.filter(id__in=by_chain)
1167

  
1168
    def user_accessible_projects(self, user):
1152 1169
        """
1153 1170
        Return projects accessed by specified user.
1154 1171
        """
1155
        participates_fitlers = Q(owner=user) | Q(applicant=user) | \
1172
        participates_filters = Q(owner=user) | Q(applicant=user) | \
1156 1173
                               Q(project__projectmembership__person=user)
1157
        state_filters = (Q(state=ProjectApplication.PENDING) & \
1158
                        Q(precursor_application__isnull=True)) | \
1159
                        Q(state=ProjectApplication.APPROVED)
1160
        return self.filter(participates_fitlers & state_filters).order_by('issue_date').distinct()
1174

  
1175
        return self.user_visible_by_last_of_chain(participates_filters).order_by('issue_date').distinct()
1161 1176

  
1162 1177
    def search_by_name(self, *search_strings):
1163 1178
        q = Q()
......
1253 1268
        q.create(resource=resource, member_capacity=uplimit)
1254 1269

  
1255 1270
    def user_status(self, user):
1256
        """
1257
        100 OWNER
1258
        0   REQUESTED
1259
        1   PENDING
1260
        2   ACCEPTED
1261
        3   REMOVING
1262
        4   REMOVED
1263
       -1   User has no association with the project
1264
        """
1265 1271
        try:
1266
            membership = self.project.projectmembership_set.get(person=user)
1272
            project = self.get_project()
1273
            if not project:
1274
                return -1
1275
            membership = project.projectmembership_set.get(person=user)
1276
            membership = membership.exclude(state=ProjectMembership.REMOVED)
1267 1277
            status = membership.state
1268
        except Project.DoesNotExist:
1269
            status = -1
1270 1278
        except ProjectMembership.DoesNotExist:
1271 1279
            status = -1
1272 1280

  
......
1303 1311
            return
1304 1312

  
1305 1313
    def followers(self):
1306
        current = self
1307
        try:
1308
            while current.projectapplication:
1309
                yield current.follower
1310
                current = current.follower
1311
        except:
1312
            pass
1314
        followers = ProjectApplication.objects.filter(chain=self.chain)
1315
        return followers.exclude(pk=self.pk).order_by('id')
1313 1316

  
1314 1317
    def last_follower(self):
1315 1318
        try:
1316
            return list(self.followers())[-1]
1319
            return self.followers().filter(
1320
                          state__in=[self.PENDING, self.APPROVED]).order_by('-id')[0]
1317 1321
        except IndexError:
1322
            import traceback; print traceback.print_exc()
1323
            return None
1324

  
1325
    def has_pending_modifications(self):
1326
        return bool(self.last_follower())
1327

  
1328
    def get_project(self):
1329
        try:
1330
            return Project.objects.get(id=self.chain)
1331
        except Project.DoesNotExist:
1318 1332
            return None
1319 1333

  
1320 1334
    def _get_project_for_update(self):
......
1599 1613
    TERMINATED  =   100
1600 1614
    REMOVED     =   200
1601 1615

  
1616
    ASSOCIATED_STATES   =   set([REQUESTED, ACCEPTED, SUSPENDED, TERMINATED])
1617
    ACCEPTED_STATES     =   set([ACCEPTED, SUSPENDED, TERMINATED])
1618

  
1602 1619
    state               =   models.IntegerField(default=REQUESTED,
1603 1620
                                                db_index=True)
1604 1621
    is_pending          =   models.BooleanField(default=False, db_index=True)

Also available in: Unified diff