class GroupMembershipForm(forms.Form): selected_ids = forms.Field( label=ugettext_lazy("Group Membership"), required=False, widget=Select2AjaxV4(multiple=True), ) def __init__(self, group_api_url, *args, **kwargs): submit_label = kwargs.pop('submit_label', "Update") fieldset_title = kwargs.pop( 'fieldset_title', ugettext_lazy("Edit Group Membership")) super(GroupMembershipForm, self).__init__(*args, **kwargs) self.fields['selected_ids'].widget.set_url(group_api_url) self.helper = FormHelper() self.helper.label_class = 'col-sm-3 col-md-2' self.helper.field_class = 'col-sm-9 col-md-8 col-lg-6' self.helper.form_tag = False self.helper.layout = crispy.Layout( crispy.Fieldset( fieldset_title, crispy.Field('selected_ids'), ), hqcrispy.FormActions( crispy.ButtonHolder( Submit('submit', submit_label) ) ) )
class UsersAtLocationForm(forms.Form): selected_ids = forms.Field( label=ugettext_lazy("Workers at Location"), required=False, widget=Select2AjaxV4(multiple=True), ) def __init__(self, domain_object, location, *args, **kwargs): self.domain_object = domain_object self.location = location super(UsersAtLocationForm, self).__init__( initial={'selected_ids': self.get_users_at_location()}, prefix="users", *args, **kwargs) from corehq.apps.reports.filters.api import MobileWorkersOptionsView self.fields['selected_ids'].widget.set_url( reverse(MobileWorkersOptionsView.urlname, args=(self.domain_object.name, ))) self.fields['selected_ids'].widget.set_initial( self.get_users_at_location()) self.helper = FormHelper() self.helper.label_class = 'col-sm-3 col-md-2' self.helper.field_class = 'col-sm-9 col-md-8 col-lg-6' self.helper.form_tag = False self.helper.layout = crispy.Layout( crispy.Fieldset( _("Specify Workers at this Location"), crispy.Field('selected_ids'), ), hqcrispy.FormActions( crispy.ButtonHolder( Submit('submit', ugettext_lazy("Update Location Membership"))))) # Adding a 5 second timeout because that is the elasticsearch refresh interval. @memoized @quickcache(['self.domain_object.name', 'self.location.location_id'], memoize_timeout=0, timeout=5) def get_users_at_location(self): user_query = UserES().domain( self.domain_object.name).mobile_users().location( self.location.location_id).fields( ['_id', 'username', 'first_name', 'last_name']) return [ dict(id=u['_id'], text=user_display_string(u['username'], u.get('first_name', ''), u.get('last_name', ''))) for u in user_query.run().hits ] def unassign_users(self, users): for doc in iter_docs(CommCareUser.get_db(), users): # This could probably be sped up by bulk saving, but there's a lot # of stuff going on - seems tricky. CommCareUser.wrap(doc).unset_location_by_id( self.location.location_id, fall_back_to_next=True) def assign_users(self, users): for doc in iter_docs(CommCareUser.get_db(), users): CommCareUser.wrap(doc).add_to_assigned_locations(self.location) def clean_selected_ids(self): # Django uses get by default, but selected_ids is actually a list return self.data.getlist('users-selected_ids') def save(self): selected_users = set(self.cleaned_data['selected_ids']) previous_users = set([u['id'] for u in self.get_users_at_location()]) to_remove = previous_users - selected_users to_add = selected_users - previous_users self.unassign_users(to_remove) self.assign_users(to_add) self.cache_users_at_location(selected_users) def cache_users_at_location(self, selected_users): user_cache_list = [] for doc in iter_docs(CommCareUser.get_db(), selected_users): display_username = user_display_string(doc['username'], doc.get('first_name', ''), doc.get('last_name', '')) user_cache_list.append({ 'text': display_username, 'id': doc['_id'] }) self.get_users_at_location.set_cached_value(self).to(user_cache_list)