def sync_org_contacts(org_id): """ Syncs all contacts for the given org """ from tracpro.groups.models import Region, Group from tracpro.orgs_ext.constants import TaskType from .models import Contact org = Org.objects.get(pk=org_id) logger.info('Starting contact sync task for org #%d' % org.id) sync_groups = [r.uuid for r in Region.get_all(org)] + [g.uuid for g in Group.get_all(org)] most_recent_contact = Contact.objects.by_org(org).active().exclude(temba_modified_on=None) most_recent_contact = most_recent_contact.order_by('-temba_modified_on').first() if most_recent_contact: last_time = most_recent_contact.temba_modified_on else: last_time = None created, updated, deleted, failed = sync_pull_contacts( org, Contact, fields=(), groups=sync_groups, last_time=last_time, delete_blocked=True) task_result = dict(time=datetime_to_ms(timezone.now()), counts=dict(created=len(created), updated=len(updated), deleted=len(deleted), failed=len(failed))) org.set_task_result(TaskType.sync_contacts, task_result) logger.info("Finished contact sync for org #%d (%d created, " "%d updated, %d deleted, %d failed)" % (org.id, len(created), len(updated), len(deleted), len(failed)))
def kwargs_from_temba(cls, org, temba_contact): name = temba_contact.name or "" org_region_uuids = [r.uuid for r in Region.get_all(org)] region_uuids = intersection(org_region_uuids, temba_contact.groups) region = Region.objects.get(org=org, uuid=region_uuids[0]) if region_uuids else None if not region: # pragma: no cover raise ValueError("No region with UUID in %s" % ", ".join(temba_contact.groups)) org_group_uuids = [g.uuid for g in Group.get_all(org)] group_uuids = intersection(org_group_uuids, temba_contact.groups) group = Group.objects.get(org=org, uuid=group_uuids[0]) if group_uuids else None facility_code = temba_contact.fields.get(org.facility_code_field, None) return { 'org': org, 'name': name, 'urn': temba_contact.urns[0], 'region': region, 'group': group, 'language': temba_contact.language, 'facility_code': facility_code, 'uuid': temba_contact.uuid, }
def sync_org_contacts(org_id): """ Syncs all contacts for the given org """ from tracpro.groups.models import Region, Group from tracpro.orgs_ext import TaskType from .models import Contact org = Org.objects.get(pk=org_id) logger.info('Starting contact sync task for org #%d' % org.id) sync_groups = [r.uuid for r in Region.get_all(org)] + [g.uuid for g in Group.get_all(org)] created, updated, deleted, failed = sync_pull_contacts(org, Contact, fields=(), groups=sync_groups) task_result = dict(time=datetime_to_ms(timezone.now()), counts=dict(created=len(created), updated=len(updated), deleted=len(deleted), failed=len(failed))) org.set_task_result(TaskType.sync_contacts, task_result) logger.info("Finished contact sync for org #%d (%d created, %d updated, %d deleted, %d failed)" % (org.id, len(created), len(updated), len(deleted), len(failed)))
def __init__(self, *args, **kwargs): self.user = kwargs.pop('user') super(UserForm, self).__init__(*args, **kwargs) if self.user.get_org(): self.fields['regions'].queryset = Region.get_all(self.user.get_org()).order_by('name')
def sync_org_contacts(org_id): """ Syncs all contacts for the given org """ from tracpro.groups.models import Region, Group from tracpro.orgs_ext.constants import TaskType from .models import Contact org = Org.objects.get(pk=org_id) logger.info('Starting contact sync task for org #%d' % org.id) sync_groups = [r.uuid for r in Region.get_all(org)] + [g.uuid for g in Group.get_all(org)] created, updated, deleted, failed = sync_pull_contacts( org, Contact, fields=(), groups=sync_groups) task_result = dict(time=datetime_to_ms(timezone.now()), counts=dict(created=len(created), updated=len(updated), deleted=len(deleted), failed=len(failed))) org.set_task_result(TaskType.sync_contacts, task_result) logger.info("Finished contact sync for org #%d (%d created, " "%d updated, %d deleted, %d failed)" % (org.id, len(created), len(updated), len(deleted), len(failed)))
def test_create(self): zabul = Region.create(self.unicef, "Zabul", 'G-101') jan = self.create_contact(self.unicef, "Jan", 'tel:1234', zabul, self.group1, 'C-101') bob = User.create(self.unicef, "Bob", "*****@*****.**", "pass", False, [zabul]) self.assertEqual(zabul.org, self.unicef) self.assertEqual(zabul.name, "Zabul") self.assertEqual(zabul.uuid, 'G-101') self.assertEqual(list(zabul.get_contacts()), [jan]) self.assertEqual(list(zabul.get_users()), [bob])
def push_contact_change(contact_id, change_type): """ Task to push a local contact change to RapidPro """ from tracpro.groups.models import Group, Region from .models import Contact contact = Contact.objects.select_related('org', 'region').get(pk=contact_id) org = contact.org logger.info("Pushing %s change to contact %s" % (change_type.name.upper(), contact.uuid)) region_uuids = set([r.uuid for r in Region.get_all(org)]) group_uuids = set([r.uuid for r in Group.get_all(org)]) sync_push_contact(org, contact, change_type, [region_uuids, group_uuids])
def kwargs_from_temba(cls, org, temba_contact): name = temba_contact.name if temba_contact.name is not None else "" org_region_uuids = [r.uuid for r in Region.get_all(org)] region_uuids = intersection(org_region_uuids, temba_contact.groups) region = Region.objects.get(org=org, uuid=region_uuids[0]) if region_uuids else None if not region: # pragma: no cover raise ValueError("No region with UUID in %s" % ", ".join(temba_contact.groups)) org_group_uuids = [g.uuid for g in Group.get_all(org)] group_uuids = intersection(org_group_uuids, temba_contact.groups) group = Group.objects.get(org=org, uuid=group_uuids[0]) if group_uuids else None facility_code = temba_contact.fields.get(org.get_facility_code_field(), None) return dict(org=org, name=name, urn=temba_contact.urns[0], region=region, group=group, language=temba_contact.language, facility_code=facility_code, uuid=temba_contact.uuid)
def sync(self, org): recent_contacts = Contact.objects.by_org(org).active() recent_contacts = recent_contacts.exclude(temba_modified_on=None) recent_contacts = recent_contacts.order_by('-temba_modified_on') most_recent = recent_contacts.first() sync_regions = [r.uuid for r in Region.get_all(org)] sync_groups = [g.uuid for g in Group.get_all(org)] created, updated, deleted, failed = sync_pull_contacts( org=org, contact_class=Contact, fields=(), delete_blocked=True, groups=sync_regions + sync_groups, last_time=most_recent.temba_modified_on if most_recent else None) org.set_task_result(TaskType.sync_contacts, { 'time': datetime_to_ms(timezone.now()), 'counts': { 'created': len(created), 'updated': len(updated), 'deleted': len(deleted), 'failed': len(failed), }, })
def __init__(self, *args, **kwargs): self.user = kwargs.pop('user') super(UserForm, self).__init__(*args, **kwargs) if self.user.get_org(): regions = Region.get_all(self.user.get_org()) self.fields['regions'].queryset = regions
def create_region(self, org, name, uuid): return Region.create(org, name, uuid)
def test_get_all(self): self.assertEqual(len(Region.get_all(self.unicef)), 3) self.assertEqual(len(Region.get_all(self.nyaruka)), 1)
def calculate(): # org admins have implicit access to all regions if user.is_admin_for(org): return Region.get_all(org) else: return user.regions.filter(is_active=True)
def test_sync_with_groups(self, mock_get_contacts, mock_get_groups): mock_get_groups.return_value = [ TembaGroup.create(uuid='G-101', name="New region", size=2), TembaGroup.create(uuid='G-102', name="Other region", size=1) ] mock_get_contacts.return_value = [ TembaContact.create(uuid='C-101', name="Jan", urns=['tel:123'], groups=['G-101', 'G-005'], fields=dict(chat_name="jan"), language='eng', modified_on=timezone.now()), TembaContact.create(uuid='C-102', name="Ken", urns=['tel:234'], groups=['G-101', 'G-006'], fields=dict(chat_name="ken"), language='eng', modified_on=timezone.now()) ] # select one new group Region.sync_with_groups(self.unicef, ['G-101']) self.assertEqual(self.unicef.regions.filter(is_active=True).count(), 1) self.assertEqual( self.unicef.regions.filter(is_active=False).count(), 3) # existing de-activated new_region = Region.objects.get(uuid='G-101') self.assertEqual(new_region.name, "New region") self.assertTrue(new_region.is_active) # check contact changes self.assertEqual( self.unicef.contacts.filter(is_active=True).count(), 2) self.assertEqual( self.unicef.contacts.filter(is_active=False).count(), 5) # existing de-activated jan = Contact.objects.get(uuid='C-101') self.assertEqual(jan.name, "Jan") self.assertEqual(jan.urn, 'tel:123') self.assertEqual(jan.region, new_region) self.assertTrue(jan.is_active) # change group and contacts on chatpro side Region.objects.filter(name="New region").update(name="Huh?", is_active=False) jan.name = "Janet" jan.save() Contact.objects.filter(name="Ken").update(is_active=False) # re-select new group Region.sync_with_groups(self.unicef, ['G-101']) # local changes should be overwritten self.assertEqual( self.unicef.regions.get(is_active=True).name, 'New region') self.assertEqual( self.unicef.contacts.filter(is_active=True).count(), 2) Contact.objects.get(name="Jan", is_active=True)