Ejemplo n.º 1
0
    def __init__(self, *args, **kwargs):
        self.user = kwargs.pop('user')
        org = self.user.get_org()
        super(ContactForm, self).__init__(*args, **kwargs)

        self.instance.org = org
        self.instance.modified_by = self.user
        if not self.instance.pk:
            self.instance.created_by = self.user

        self.fields['name'].required = True
        self.fields['group'].required = True

        self.fields['region'].queryset = self.user.get_all_regions(org)
        self.fields['group'].empty_label = ""
        self.fields['group'].queryset = Group.get_all(org).order_by('name')

        # Add form fields to update contact's DataField values.
        self.data_field_keys = []
        values = {
            v.field.key: v.get_value()
            for v in self.instance.contactfield_set.all()
        }
        for field in org.datafield_set.visible():
            self.data_field_keys.append(field.key)
            initial = values.get(field.key, None)
            self.fields[field.key] = field.get_form_field(initial=initial)
Ejemplo n.º 2
0
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)))
Ejemplo n.º 3
0
    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,
        }
Ejemplo n.º 4
0
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)))
Ejemplo n.º 5
0
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)))
Ejemplo n.º 6
0
    def __init__(self, *args, **kwargs):
        self.user = kwargs.pop('user')
        org = self.user.get_org()

        super(ContactForm, self).__init__(*args, **kwargs)

        self.fields['region'].queryset = self.user.get_regions(org).order_by(
            'name')
        self.fields['group'].queryset = Group.get_all(org).order_by('name')
Ejemplo n.º 7
0
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])
Ejemplo n.º 8
0
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])
Ejemplo n.º 9
0
        def get_context_data(self, **kwargs):
            context = super(PollRunCRUDL.Participation, self).get_context_data(**kwargs)
            reporting_groups = Group.get_all(self.request.org).order_by("name")
            responses = self.object.get_responses(self.request.region)

            # initialize an ordered dict of group to response counts
            per_group_counts = OrderedDict()
            for reporting_group in reporting_groups:
                per_group_counts[reporting_group] = dict(E=0, P=0, C=0)

            no_group_counts = dict(E=0, P=0, C=0)
            overall_counts = dict(E=0, P=0, C=0)

            reporting_groups_by_id = {g.pk: g for g in reporting_groups}
            for response in responses:
                group_id = response.contact.group_id
                group = reporting_groups_by_id[group_id] if group_id else None
                status = response.status

                if group:
                    per_group_counts[group][status] += 1
                else:
                    no_group_counts[status] += 1

                overall_counts[status] += 1

            def calc_completion(counts):
                total = counts["E"] + counts["P"] + counts["C"]
                return "%d%%" % int(100 * counts["C"] / total) if total else ""

            # for each set of counts, also calculate the completion percentage
            for group, counts in per_group_counts.iteritems():
                counts["X"] = calc_completion(counts)

            no_group_counts["X"] = calc_completion(no_group_counts)
            overall_counts["X"] = calc_completion(overall_counts)

            # participation table counts
            context["per_group_counts"] = per_group_counts
            context["no_group_counts"] = no_group_counts
            context["overall_counts"] = overall_counts

            # message recipient counts
            context["all_participants_count"] = sum((overall_counts["E"], overall_counts["P"], overall_counts["C"]))
            context["incomplete_count"] = sum((overall_counts["E"], overall_counts["P"]))
            context["complete_count"] = overall_counts["C"]
            return context
Ejemplo n.º 10
0
    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)
Ejemplo n.º 11
0
    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),
            },
        })
Ejemplo n.º 12
0
    def __init__(self, *args, **kwargs):
        self.user = kwargs.pop("user")
        org = self.user.get_org()
        super(ContactForm, self).__init__(*args, **kwargs)

        self.instance.org = org
        self.instance.modified_by = self.user
        if not self.instance.pk:
            self.instance.created_by = self.user

        self.fields["name"].required = True
        self.fields["group"].required = True

        self.fields["region"].queryset = self.user.get_all_regions(org)
        self.fields["group"].empty_label = ""
        self.fields["group"].queryset = Group.get_all(org).order_by("name")

        # Add form fields to update contact's DataField values.
        self.data_field_keys = []
        values = {v.field.key: v.get_value() for v in self.instance.contactfield_set.all()}
        for field in org.datafield_set.visible():
            self.data_field_keys.append(field.key)
            initial = values.get(field.key, None)
            self.fields[field.key] = field.get_form_field(initial=initial)
Ejemplo n.º 13
0
 def create_group(self, org, name, uuid):
     return Group.create(org, name, uuid)
Ejemplo n.º 14
0
 def create_group(self, org, name, uuid):
     return Group.create(org, name, uuid)
Ejemplo n.º 15
0
        def get_context_data(self, **kwargs):
            context = super(PollRunCRUDL.Participation,
                            self).get_context_data(**kwargs)
            responses = self.object.get_responses(
                self.request.region, self.request.include_subregions)
            group_by = self.request.GET.get('group-by', 'reporter')
            if group_by == "reporter":
                group_by_reporter_group = True
                groups_or_regions = Group.get_all(
                    self.request.org).order_by('name')
            else:
                group_by_reporter_group = False
                if self.request.data_regions:
                    groups_or_regions = self.request.data_regions
                else:
                    groups_or_regions = Region.objects.filter(
                        org=self.request.org)

            # initialize an ordered dict of group to response counts
            per_group_counts = OrderedDict()
            no_group_counts = {'E': 0, 'P': 0, 'C': 0}
            overall_counts = {'E': 0, 'P': 0, 'C': 0}

            # Calculate all reporter group or region activity per group or region
            for group_or_region in groups_or_regions:
                if group_by_reporter_group:
                    responses_group = responses.filter(
                        contact__group=group_or_region)
                else:
                    responses_group = responses.filter(
                        contact__region=group_or_region)
                if responses_group:
                    per_group_counts[group_or_region] = {
                        "E":
                        responses_group.filter(
                            status=Response.STATUS_EMPTY).count(),
                        "P":
                        responses_group.filter(
                            status=Response.STATUS_PARTIAL).count(),
                        "C":
                        responses_group.filter(
                            status=Response.STATUS_COMPLETE).count()
                    }
                    overall_counts['E'] = overall_counts[
                        'E'] + per_group_counts[group_or_region]['E']
                    overall_counts['P'] = overall_counts[
                        'P'] + per_group_counts[group_or_region]['P']
                    overall_counts['C'] = overall_counts[
                        'C'] + per_group_counts[group_or_region]['C']

            # Calculate all no-group or no-region activity
            if group_by_reporter_group:
                responses_no_group = responses.filter(
                    contact__group__isnull=True)
            else:
                responses_no_group = responses.filter(
                    contact__region__isnull=True)
            if responses_no_group:
                no_group_counts = {
                    "E":
                    responses_no_group.filter(
                        status=Response.STATUS_EMPTY).count(),
                    "P":
                    responses_no_group.filter(
                        status=Response.STATUS_PARTIAL).count(),
                    "C":
                    responses_no_group.filter(
                        status=Response.STATUS_COMPLETE).count()
                }
                overall_counts[
                    'E'] = overall_counts['E'] + no_group_counts['E']
                overall_counts[
                    'P'] = overall_counts['P'] + no_group_counts['P']
                overall_counts[
                    'C'] = overall_counts['C'] + no_group_counts['C']

            def calc_completion(counts):
                total = counts['E'] + counts['P'] + counts['C']
                return "%d%%" % int(100 * counts['C'] / total) if total else ''

            # for each set of counts, also calculate the completion percentage
            for group, counts in per_group_counts.iteritems():
                counts['X'] = calc_completion(counts)

            no_group_counts['X'] = calc_completion(no_group_counts)
            overall_counts['X'] = calc_completion(overall_counts)

            # participation table counts
            context['per_group_counts'] = per_group_counts
            context['no_group_counts'] = no_group_counts
            context['overall_counts'] = overall_counts

            # message recipient counts
            context['all_participants_count'] = sum((
                overall_counts['E'],
                overall_counts['P'],
                overall_counts['C'],
            ))
            context['incomplete_count'] = sum((
                overall_counts['E'],
                overall_counts['P'],
            ))
            context['complete_count'] = overall_counts['C']
            context['group_by_reporter_group'] = group_by_reporter_group
            return context
Ejemplo n.º 16
0
 def test_create(self):
     group = Group.create(self.unicef, "Male Teachers", 'G-101')
     self.assertEqual(group.org, self.unicef)
     self.assertEqual(group.name, "Male Teachers")
     self.assertEqual(group.uuid, 'G-101')
Ejemplo n.º 17
0
        def get_context_data(self, **kwargs):
            context = super(PollRunCRUDL.Participation, self).get_context_data(**kwargs)
            responses = self.object.get_responses(
                self.request.region,
                self.request.include_subregions)
            group_by = self.request.GET.get('group-by', 'reporter')
            if group_by == "reporter":
                group_by_reporter_group = True
                groups_or_regions = Group.get_all(self.request.org).order_by('name')
            else:
                group_by_reporter_group = False
                if self.request.data_regions:
                    groups_or_regions = self.request.data_regions
                else:
                    groups_or_regions = Region.objects.filter(org=self.request.org)

            # initialize an ordered dict of group to response counts
            per_group_counts = OrderedDict()
            no_group_counts = {'E': 0, 'P': 0, 'C': 0}
            overall_counts = {'E': 0, 'P': 0, 'C': 0}

            # Calculate all reporter group or region activity per group or region
            for group_or_region in groups_or_regions:
                if group_by_reporter_group:
                    responses_group = responses.filter(contact__group=group_or_region)
                else:
                    responses_group = responses.filter(contact__region=group_or_region)
                if responses_group:
                    per_group_counts[group_or_region] = {
                        "E": responses_group.filter(status=Response.STATUS_EMPTY).count(),
                        "P": responses_group.filter(status=Response.STATUS_PARTIAL).count(),
                        "C": responses_group.filter(status=Response.STATUS_COMPLETE).count()
                    }
                    overall_counts['E'] = overall_counts['E'] + per_group_counts[group_or_region]['E']
                    overall_counts['P'] = overall_counts['P'] + per_group_counts[group_or_region]['P']
                    overall_counts['C'] = overall_counts['C'] + per_group_counts[group_or_region]['C']

            # Calculate all no-group or no-region activity
            if group_by_reporter_group:
                responses_no_group = responses.filter(contact__group__isnull=True)
            else:
                responses_no_group = responses.filter(contact__region__isnull=True)
            if responses_no_group:
                no_group_counts = {
                    "E": responses_no_group.filter(status=Response.STATUS_EMPTY).count(),
                    "P": responses_no_group.filter(status=Response.STATUS_PARTIAL).count(),
                    "C": responses_no_group.filter(status=Response.STATUS_COMPLETE).count()
                }
                overall_counts['E'] = overall_counts['E'] + no_group_counts['E']
                overall_counts['P'] = overall_counts['P'] + no_group_counts['P']
                overall_counts['C'] = overall_counts['C'] + no_group_counts['C']

            def calc_completion(counts):
                total = counts['E'] + counts['P'] + counts['C']
                return "%d%%" % int(100 * counts['C'] / total) if total else ''

            # for each set of counts, also calculate the completion percentage
            for group, counts in per_group_counts.iteritems():
                counts['X'] = calc_completion(counts)

            no_group_counts['X'] = calc_completion(no_group_counts)
            overall_counts['X'] = calc_completion(overall_counts)

            # participation table counts
            context['per_group_counts'] = per_group_counts
            context['no_group_counts'] = no_group_counts
            context['overall_counts'] = overall_counts

            # message recipient counts
            context['all_participants_count'] = sum((
                overall_counts['E'],
                overall_counts['P'],
                overall_counts['C'],
            ))
            context['incomplete_count'] = sum((
                overall_counts['E'],
                overall_counts['P'],
            ))
            context['complete_count'] = overall_counts['C']
            context['group_by_reporter_group'] = group_by_reporter_group
            return context
Ejemplo n.º 18
0
 def test_get_all(self):
     self.assertEqual(len(Group.get_all(self.unicef)), 3)
     self.assertEqual(len(Group.get_all(self.nyaruka)), 1)
Ejemplo n.º 19
0
 def __init__(self, *args, **kwargs):
     self.user = kwargs.pop('user')
     super(ContactForm, self).__init__(*args, **kwargs)
     org = self.user.get_org()
     self.fields['region'].queryset = self.user.get_all_regions(org)
     self.fields['group'].queryset = Group.get_all(org).order_by('name')