def get_forms_reps( cls, baseuser = None, # mandatory. private = False, ids = True, user = None, visit = None, # user or visit. usercats = None, loccats = None, # common. upnodes = None, itemcats = None, items = None, # visit. ): # print 'get_forms_reps', private, user or visit if not baseuser: error if visit if user else not visit: error repdict_items = dict() repdict_usercats = dict() types = [] _any = utils.tree_any def _doreps(form): def _reps(isitems, repdict, reps): # print '_doreps > reps', reps if len(reps): # must check, even if empty after the below filter. # user will get ALL reps (items / usercats) without any filtering, as opposed to visit. isvisititems = isitems and not user if isvisititems: reps = reps.filter(id__in=items).all() for erep in reps: if _any(usercats, erep.visits_usercats) or _any(loccats, erep.visits_loccats) if isvisititems else True: ''' repdict: @ visit = dict[erep] = forms @ user = dict[form] = reps (items / usercats) ''' k = form.id if user else erep.id rforms = repdict.get(k) or [] repdict[k] = rforms rforms.append(erep if user else form) return True return False def _reps_items(): reps1 = form.repitems.all() repcats = utils.tree_all_downs(form.repitemcats.all()) reps2 = ItemCat.els_get(repcats) nreps = (reps1 | reps2).distinct() return _reps(True, repdict_items, nreps) def _reps_usercats(): ucats = utils.tree_all_downs(form.repusercats.all()) ucats2 = baseuser.allcats() nreps = ucats & ucats2 # print '_reps_usercats', baseuser, len(ucats), len(ucats2), len(nreps) return _reps(False, repdict_usercats, nreps) # priority to repitems, then (if none) repusercats. types.extend(form.types.all()) return not (_reps_items() or _reps_usercats()) forms = Form.objects.filter(scope='users' if user else 'visits') forms = [ form for form in forms if ( form.private is private and ( False or (user and ( False or _any(usercats, form.users_usercats) or _any(loccats, form.users_loccats) )) or (visit and ( False or _any(usercats, form.visits_usercats) or _any(loccats, form.visits_loccats) or visit.loc.addr().area.zip.brick in form.visits_bricks.all() or _any(upnodes, form.visits_forcenodes, ups=False) or _any(itemcats, form.visits_itemcats) )) ) ) and _doreps(form) ] if ids: forms = utils.db_ids(forms) for repdict in [ repdict_items, repdict_usercats ]: for erep, erepforms in repdict.items(): erepforms[:] = utils.db_ids(erepforms) types = [ dict(id=form.id, name=form.name) for form in sorted(set(types), key=lambda form: (form.order, form.name)) ] # print 'get_forms_reps', private, user or visit, types, forms, repdict_items, repdict_usercats return types, forms, repdict_items, repdict_usercats