Esempio n. 1
0
def calculate_totals_for_cases(apps, schema_editor):
    from casepro.statistics.models import datetime_to_date
    Case = apps.get_model('cases', 'Case')
    CaseAction = apps.get_model('cases', 'CaseAction')
    DailyCount = apps.get_model('statistics', 'DailyCount')

    cases = list(Case.objects.all().order_by('id'))
    num_updated = 0

    for case in cases:
        open_action = case.actions.filter(action='O').first()
        org = open_action.case.org
        user = open_action.created_by
        partner = open_action.case.assignee
        case = open_action.case

        day = datetime_to_date(open_action.created_on, org)
        DailyCount.objects.create(day=day,
                                  item_type='C',
                                  scope='org:%d' % org.pk,
                                  count=1)
        DailyCount.objects.create(day=day,
                                  item_type='C',
                                  scope='org:%d:user:%d' % (org.pk, user.pk),
                                  count=1)
        DailyCount.objects.create(day=day,
                                  item_type='C',
                                  scope='partner:%d' % partner.pk,
                                  count=1)

        try:
            # only check the first close action, don't count reopens
            close_action = case.actions.filter(
                action='C').earliest('created_on')
            DailyCount.objects.create(day=day,
                                      item_type='D',
                                      scope='org:%d' %
                                      close_action.case.org.pk,
                                      count=1)
            DailyCount.objects.create(
                day=day,
                item_type='D',
                scope='org:%d:user:%d' %
                (close_action.case.org.pk, close_action.created_by.pk),
                count=1)
            DailyCount.objects.create(day=day,
                                      item_type='D',
                                      scope='partner:%d' %
                                      close_action.case.assignee.pk,
                                      count=1)

            num_updated += 1
            if num_updated % 100 == 0:
                print("Created daily counts for %d of %d cases" %
                      (num_updated, len(cases)))

        except CaseAction.DoesNotExist:
            # no close action means to close totals to count for this case
            pass
Esempio n. 2
0
    def clear_labels(self):
        """
        Removes all labels from this message
        """
        from casepro.statistics.models import DailyCount, datetime_to_date

        day = datetime_to_date(self.created_on, self.org)
        for label in self.labels.all():
            DailyCount.record_removal(day, DailyCount.TYPE_INCOMING, label)

        Labelling.objects.filter(message=self).delete()
Esempio n. 3
0
    def unlabel(self, *labels):
        """
        Removes the given labels from this message
        """
        from casepro.statistics.models import DailyCount, datetime_to_date

        existing_labellings = Labelling.objects.filter(
            message=self, label__in=labels).select_related("label")

        day = datetime_to_date(self.created_on, self.org)
        for labelling in existing_labellings:
            DailyCount.record_removal(day, DailyCount.TYPE_INCOMING,
                                      labelling.label)

        Labelling.objects.filter(
            id__in=[l.id for l in existing_labellings]).delete()
Esempio n. 4
0
    def label(self, *labels):
        """
        Adds the given labels to this message
        """
        from casepro.profiles.models import Notification
        from casepro.statistics.models import DailyCount, datetime_to_date

        existing_label_ids = Labelling.objects.filter(
            message=self, label__in=labels).values_list("label", flat=True)
        add_labels = [l for l in labels if l.id not in existing_label_ids]
        new_labellings = [Labelling(message=self, label=l) for l in add_labels]
        Labelling.objects.bulk_create(new_labellings)

        day = datetime_to_date(self.created_on, self.org)
        for label in add_labels:
            DailyCount.record_item(day, DailyCount.TYPE_INCOMING, label)

        # notify all users who watch these labels
        for watcher in set(User.objects.filter(watched_labels__in=labels)):
            Notification.new_message_labelling(self.org, watcher, self)
def calculate_totals_for_cases(apps, schema_editor):
    from casepro.statistics.models import datetime_to_date
    Case = apps.get_model('cases', 'Case')
    CaseAction = apps.get_model('cases', 'CaseAction')
    DailyCount = apps.get_model('statistics', 'DailyCount')

    cases = list(Case.objects.all().order_by('id'))
    num_updated = 0

    for case in cases:
        open_action = case.actions.filter(action='O').first()
        org = open_action.case.org
        user = open_action.created_by
        partner = open_action.case.assignee
        case = open_action.case

        day = datetime_to_date(open_action.created_on, org)
        DailyCount.objects.create(day=day, item_type='C', scope='org:%d' % org.pk, count=1)
        DailyCount.objects.create(day=day, item_type='C', scope='org:%d:user:%d' % (org.pk, user.pk), count=1)
        DailyCount.objects.create(day=day, item_type='C', scope='partner:%d' % partner.pk, count=1)

        try:
            # only check the first close action, don't count reopens
            close_action = case.actions.filter(action='C').earliest('created_on')
            DailyCount.objects.create(day=day, item_type='D', scope='org:%d' % close_action.case.org.pk, count=1)
            DailyCount.objects.create(day=day, item_type='D',
                                      scope='org:%d:user:%d' % (close_action.case.org.pk, close_action.created_by.pk),
                                      count=1)
            DailyCount.objects.create(day=day, item_type='D',
                                      scope='partner:%d' % close_action.case.assignee.pk, count=1)

            num_updated += 1
            if num_updated % 100 == 0:
                print("Created daily counts for %d of %d cases" % (num_updated, len(cases)))

        except CaseAction.DoesNotExist:
            # no close action means to close totals to count for this case
            pass
def calculate_totals_for_cases(apps, schema_editor):
    from casepro.statistics.models import datetime_to_date
    Case = apps.get_model('cases', 'Case')
    CaseAction = apps.get_model('cases', 'CaseAction')
    Outgoing = apps.get_model('msgs', 'Outgoing')
    DailySecondTotalCount = apps.get_model('statistics', 'DailySecondTotalCount')

    qs = Case.objects.all().order_by('id')
    for case in qs:
        partner = case.assignee

        if case.closed_on is not None:
            # we only consider the first time a case was closed, not any subsequent reopenings
            close_action = case.actions.filter(action='C').earliest('created_on')
            org = close_action.case.org
            user = close_action.created_by
            partner = close_action.case.assignee
            case = close_action.case

            day = datetime_to_date(close_action.created_on, close_action.case.org)
            # count the time to close on an org level
            td = close_action.created_on - case.opened_on
            seconds_since_open = ceil(td.total_seconds())
            DailySecondTotalCount.objects.create(day=day, item_type='C', scope='org:%d' % org.pk,
                                                 count=1, seconds=seconds_since_open)

            # count the time since case was last assigned to this partner till it was closed
            if user.partners.filter(id=partner.id).exists():
                # count the time since this case was (re)assigned to this partner
                try:
                    action = case.actions.filter(action='A', assignee=partner).latest('created_on')
                    start_date = action.created_on
                except CaseAction.DoesNotExist:
                    start_date = case.opened_on

                td = close_action.created_on - start_date
                seconds_since_open = ceil(td.total_seconds())
                DailySecondTotalCount.objects.create(day=day, item_type='C', scope='partner:%d' % partner.pk,
                                                     count=1, seconds=seconds_since_open)

        # check if responded to
        if case.outgoing_messages.exists():
            # count the first reponse at an org level
            first_response = case.outgoing_messages.earliest('created_on')
            day = datetime_to_date(first_response.created_on, case.org)
            td = first_response.created_on - case.opened_on
            seconds_since_open = ceil(td.total_seconds())
            DailySecondTotalCount.objects.create(day=day, item_type='A', scope='org:%d' % case.org.pk,
                                                 count=1, seconds=seconds_since_open)
            try:
                first_response = case.outgoing_messages.filter(partner=partner).earliest('created_on')
            except Outgoing.DoesNotExist:
                continue

            day = datetime_to_date(first_response.created_on, case.org)

            # count the first response by this partner
            author_action = case.actions.filter(action='O').order_by('created_on').first()
            reassign_action = case.actions.filter(action='A', assignee=partner).order_by('created_on').first()

            if author_action and get_partner(org, author_action.created_by) != partner:
                # only count the time since this case was (re)assigned to this partner
                # or cases that were assigned during creation by another partner
                if reassign_action:
                    start_date = reassign_action.created_on
                else:
                    start_date = author_action.created_on

                td = first_response.created_on - start_date
                seconds_since_open = ceil(td.total_seconds())
                DailySecondTotalCount.objects.create(day=day, item_type='A', scope='partner:%d' % partner.pk,
                                                     count=1, seconds=seconds_since_open)
Esempio n. 7
0
    def create_msgs(self, orgs):
        self._log("Creating messages. Press Ctrl+C to stop...\n")

        # cache labels and contacts for each org
        for org in orgs:
            org._contacts = list(org.contacts.order_by("id"))
            org._labels = list(org.labels.order_by("id"))

        last_backend_id = Message.objects.order_by("backend_id").values_list("backend_id", flat=True).last()
        backend_id_start = last_backend_id + 1 if last_backend_id else 1

        BATCH_SIZE = 100

        num_created = 0
        try:
            msg_batch = []

            while True:
                org = self.random_choice(orgs, bias=BIASED)
                backend_id = backend_id_start + num_created

                msg, labels = self.generate_msg(org, backend_id)
                msg._labels = labels

                msg_batch.append(msg)

                num_created += 1

                if len(msg_batch) == BATCH_SIZE:
                    Message.objects.bulk_create(msg_batch)

                    labelling_batch = []
                    count_batch = []
                    for msg in msg_batch:
                        count_batch.append(
                            DailyCount(
                                day=datetime_to_date(msg.created_on, org),
                                item_type=DailyCount.TYPE_INCOMING,
                                scope=DailyCount.encode_scope(org),
                                count=1,
                            )
                        )

                        for label in msg._labels:
                            labelling_batch.append(Labelling.create(label, msg))
                            count_batch.append(
                                DailyCount(
                                    day=datetime_to_date(msg.created_on, org),
                                    item_type=DailyCount.TYPE_INCOMING,
                                    scope=DailyCount.encode_scope(label),
                                    count=1,
                                )
                            )

                    Labelling.objects.bulk_create(labelling_batch)
                    DailyCount.objects.bulk_create(count_batch)

                    msg_batch = []

                    self._log(f" > Created {num_created} messages\n")
        except KeyboardInterrupt:
            pass

        self._log(" > Squashing counts...\n")

        squash_counts()

        self._log(self.style.SUCCESS("OK") + "\n")