Beispiel #1
0
def _is_valid_status(facility, date, status_type):
    if status_type not in const.NEEDED_STATUS_TYPES:
        return False
    groups = HistoricalLocationGroup.objects.filter(
        date__month=date.month,
        date__year=date.year,
        location_id=facility.sql_location
    )
    if (not facility.metadata.get('group', None)) and (groups.count() == 0):
        return False

    if groups.count() > 0:
        codes = [group.group for group in groups]
    else:
        try:
            latest_group = HistoricalLocationGroup.objects.filter(
                location_id=facility.sql_location
            ).latest('date')
            if date.date() < latest_group.date:
                return False
            else:
                codes = [facility.metadata['group']]
        except HistoricalLocationGroup.DoesNotExist:
            codes = [facility.metadata['group']]
    dg = DeliveryGroups(date.month)
    if status_type == SupplyPointStatusTypes.R_AND_R_FACILITY:
        return dg.current_submitting_group() in codes
    elif status_type == SupplyPointStatusTypes.DELIVERY_FACILITY:
        return dg.current_delivering_group() in codes
    return True
Beispiel #2
0
def last_location_group(location):
    try:
        gs = GroupSummary.objects.filter(
            total=1, org_summary__location_id=location.get_id, title=SupplyPointStatusTypes.DELIVERY_FACILITY
        ).latest('org_summary__date')
    except GroupSummary.DoesNotExist:
        return

    delivery_groups = DeliveryGroups(gs.org_summary.date.month)
    return delivery_groups.current_delivering_group()
Beispiel #3
0
def _is_valid_status(facility, date, status_type):
    if status_type not in const.NEEDED_STATUS_TYPES:
        return False

    code = facility.metadata.get('group')
    if not code:
        return False
    dg = DeliveryGroups(date.month)
    if status_type == SupplyPointStatusTypes.R_AND_R_FACILITY:
        return dg.current_submitting_group() == code
    elif status_type == SupplyPointStatusTypes.DELIVERY_FACILITY:
        return dg.current_delivering_group() == code
    return True
Beispiel #4
0
    def rows(self):

        if self.config['org_summary']:

            def prepare_processing_info(data):
                return {
                    'total': data[0] - (data[1] + data[2]),
                    'complete': 0
                }

            org_summary = self.config['org_summary'][0]
            total = org_summary.total_orgs
            avg_lead_time = org_summary.average_lead_time_in_days
            if avg_lead_time:
                avg_lead_time = "%.1f" % avg_lead_time

            endmonth = self.config['enddate'].month
            dg = DeliveryGroups(month=endmonth)

            rr_data = RandRSubmissionData(config=self.config).rows[0]
            delivery_data = DeliverySubmissionData(config=self.config).rows[0]

            submitting_group = dg.current_submitting_group(month=endmonth)
            processing_group = dg.current_processing_group(month=endmonth)
            delivery_group = dg.current_delivering_group(month=endmonth)

            (rr_complete, rr_total) = (rr_data.complete, rr_data.total) if rr_data else (0, 0)
            if delivery_data:
                (delivery_complete, delivery_total) = (delivery_data.complete, delivery_data.total)
            else:
                (delivery_complete, delivery_total) = (0, 0)

            processing_numbers = prepare_processing_info([total, rr_total, delivery_total])

            return {
                "processing_total": processing_numbers['total'],
                "processing_complete": processing_numbers['complete'],
                "submitting_total": rr_total,
                "submitting_complete": rr_complete,
                "delivery_total": delivery_total,
                "delivery_complete": delivery_complete,
                "delivery_group": delivery_group,
                "submitting_group": submitting_group,
                "processing_group": processing_group,
                "total": total,
                "avg_lead_time": avg_lead_time,
            }
        else:
            return None
Beispiel #5
0
 def __init__(self, config=None, css_class='row_chart'):
     super(RRReportingHistory, self).__init__(config, css_class)
     self.config = config or {}
     self.css_class = css_class
     datespan_type = self.config.get('datespan_type')
     if datespan_type == 1:
         self.title = "R&R Reporting History (Group %s)" %\
                      DeliveryGroups(int(self.config['datespan_first'])).current_submitting_group()
     else:
         self.title = "R&R Reporting History"
Beispiel #6
0
 def __init__(self, config=None, css_class='row_chart'):
     super(DeliveryStatus, self).__init__(config, css_class)
     self.config = config or {}
     self.css_class = css_class
     datespan_type = self.config.get('datespan_type')
     if datespan_type == 1:
         self.title = "Delivery Status: Group %s" %\
                      DeliveryGroups(int(self.config['datespan_first'])).current_delivering_group()
     else:
         self.title = "Delivery Status"
    def setUpClass(cls):
        super(TestReportSummaryBase, cls).setUpClass()
        delete_domain_phone_numbers(TEST_DOMAIN)
        cls.sms_backend, cls.sms_backend_mapping = setup_default_sms_test_backend()
        cls.domain = prepare_domain(TEST_DOMAIN)

        cls.district = make_loc(code="dis1", name="TEST DISTRICT", type="DISTRICT", domain=TEST_DOMAIN,
                                metadata={'group': DeliveryGroups().current_submitting_group()})
        cls.facility = make_loc(code="d10001", name="Test Facility 1", type="FACILITY",
                                domain=TEST_DOMAIN, parent=cls.district,
                                metadata={'group': DeliveryGroups().current_submitting_group()})
        cls.facility2 = make_loc(code="d10002", name="Test Facility 2", type="FACILITY",
                                 domain=TEST_DOMAIN, parent=cls.district,
                                 metadata={'group': DeliveryGroups().current_delivering_group()})
        cls.facility3 = make_loc(code="d10003", name="Test Facility 3", type="FACILITY",
                                 domain=TEST_DOMAIN, parent=cls.district,
                                 metadata={'group': DeliveryGroups().current_submitting_group()})

        cls.facilities = [cls.facility, cls.facility2, cls.facility3]
        cls.district_user = bootstrap_user(
            cls.district, username='******', domain=TEST_DOMAIN, home_loc='dis1', phone_number='1234',
            first_name='test', last_name='Test'
        )

        cls.contact1 = bootstrap_user(
            cls.facility, username='******', domain=TEST_DOMAIN, home_loc='d10001', phone_number='1235',
            first_name='test', last_name='Test'
        )

        cls.contact2 = bootstrap_user(
            cls.facility2, username='******', domain=TEST_DOMAIN, home_loc='d10002', phone_number='1236',
            first_name='test', last_name='Test'
        )

        cls.contact3 = bootstrap_user(
            cls.facility3, username='******', domain=TEST_DOMAIN, home_loc='d10003', phone_number='1237',
            first_name='test', last_name='Test'
        )

        for facility in cls.facilities:
            facility.metadata['group'] = cls.relevant_group()
            facility.save()
        create_products(cls, TEST_DOMAIN, ["id", "dp", "fs", "md", "ff", "dx", "bp", "pc", "qi", "jd", "mc", "ip"])
Beispiel #8
0
    def test_group_exclusion(self):
        people = list(
            RandrReminder(TEST_DOMAIN, datetime.utcnow()).get_people())
        self.assertEqual(len(people), 1)
        self.assertEqual(people[0].get_id, self.user1.get_id)

        self.facility.metadata['group'] = DeliveryGroups(
        ).current_delivering_group()
        self.facility.save()
        people = list(
            RandrReminder(TEST_DOMAIN, datetime.utcnow()).get_people())
        self.assertEqual(len(people), 0)

        self.facility.metadata['group'] = DeliveryGroups(
        ).current_processing_group()
        self.facility.save()
        people = list(
            RandrReminder(TEST_DOMAIN, datetime.utcnow()).get_people())
        self.assertEqual(len(people), 0)
def _is_valid_status(facility, date, status_type):
    if status_type not in NEEDED_STATUS_TYPES:
        return False
    groups = HistoricalLocationGroup.objects.filter(
        date__month=date.month,
        date__year=date.year,
        location_id=facility.sql_location
    )
    if (not facility.metadata.get('group', None)) and (groups.count() == 0):
        return False

    if groups.count() > 0:
        code = groups[0].group
    else:
        code = facility.metadata['group']
    dg = DeliveryGroups(date.month)
    if status_type == SupplyPointStatusTypes.R_AND_R_FACILITY:
        return code == dg.current_submitting_group()
    elif status_type == SupplyPointStatusTypes.DELIVERY_FACILITY:
        return code == dg.current_delivering_group()
    return True
Beispiel #10
0
    def rows(self):
        rows = []
        locations = SQLLocation.objects.filter(parent__location_id=self.config['location_id'])
        dg = []
        for date in list(rrule.rrule(rrule.MONTHLY, dtstart=self.config['startdate'],
                                     until=self.config['enddate'])):
            dg.extend(DeliveryGroups().delivering(locations, date.month))

        for child in dg:
            group_summary = GroupSummary.objects.filter(
                org_summary__date__lte=self.config['startdate'],
                org_summary__location_id=child.location_id,
                title=SupplyPointStatusTypes.DELIVERY_FACILITY,
                total=1
            ).exists()
            if not group_summary:
                continue

            latest = latest_status_or_none(
                child.location_id,
                SupplyPointStatusTypes.DELIVERY_FACILITY,
                self.config['startdate'],
                self.config['enddate']
            )
            status_name = latest.name if latest else ""
            status_date = latest.status_date.strftime("%d-%m-%Y") if latest else "None"

            url = make_url(FacilityDetailsReport, self.config['domain'],
                           '?location_id=%s&filter_by_program=%s&'
                           'datespan_type=%s&datespan_first=%s&datespan_second=%s',
                           (child.location_id,
                            self.config['program'], self.config['datespan_type'],
                            self.config['datespan_first'], self.config['datespan_second']))

            cycle_lead_time = get_this_lead_time(
                child.location_id,
                self.config['startdate'],
                self.config['enddate']
            )
            avg_lead_time = get_avg_lead_time(child.location_id, self.config['startdate'],
                                              self.config['enddate'])
            rows.append(
                [
                    child.site_code,
                    link_format(child.name, url),
                    status_name,
                    status_date,
                    cycle_lead_time,
                    avg_lead_time
                ]
            )
        return rows
def _is_valid_status(facility, date, type):
    if type not in NEEDED_STATUS_TYPES:
        return False
    facility = Location.get(docid=facility)
    groups = HistoricalLocationGroup.objects.filter(
        date__month=date.month,
        date__year=date.year,
        location_id=facility.sql_location
    )
    if (not facility.metadata.get('groups', [])) and (groups.count() == 0):
        return False

    if groups.count() > 0:
        code = groups[0].group
    else:
        code = facility.metadata['groups'][0]
    dg = DeliveryGroups(date.month)
    if type.startswith('rr'):
        return code == dg.current_submitting_group()
    elif type.startswith('del'):
        return code == dg.current_delivering_group()
    return True
Beispiel #12
0
    def test_delivery_group_basic(self):
        submitting_group = DeliveryGroups().current_submitting_group()
        original_submitting = len(
            list(
                get_sql_locations_by_domain_and_group(TEST_DOMAIN,
                                                      submitting_group)))

        for location in Location.by_domain(TEST_DOMAIN):
            if location.metadata.get('group') != submitting_group:
                location.metadata['group'] = submitting_group
                location.save()
                break

        new_submitting = len(
            list(
                get_sql_locations_by_domain_and_group(TEST_DOMAIN,
                                                      submitting_group)))
        self.assertEqual(original_submitting + 1, new_submitting)
Beispiel #13
0
    def delivery_data_total(self):
        current_delivering_group = DeliveryGroups(self.start_date.month).current_delivering_group()
        location_ids = self.get_location_ids(current_delivering_group)
        if not location_ids:
            return {}
        query = """
            SELECT status_value, COUNT(location_id) FROM
                (
                    SELECT DISTINCT ON (location_id) location_id, status_value
                    FROM ilsgateway_supplypointstatus
                    WHERE status_date BETWEEN %s AND %s AND status_type = 'del_fac'
                    AND status_value != 'reminder_sent' AND location_id IN %s
                    ORDER BY location_id, status_date DESC
                )x
            GROUP BY status_value;

        """
        with connection.cursor() as cursor:
            cursor.execute(query, [self.start_date, self.end_date, location_ids])
            rows = cursor.fetchall()
        rows.append(('total', len(location_ids)))
        return dict(rows)
Beispiel #14
0
def send_delivery_reminder(domain, date, loc_type='FACILITY', test_list=None):
    if loc_type == 'FACILITY':
        status_type = SupplyPointStatusTypes.DELIVERY_FACILITY
        sms_text = REMINDER_DELIVERY_FACILITY
    elif loc_type == 'DISTRICT':
        status_type = SupplyPointStatusTypes.DELIVERY_DISTRICT
        sms_text = REMINDER_DELIVERY_DISTRICT
    else:
        return
    current_group = DeliveryGroups().current_delivering_group(date.month)
    sp_ids = set()
    users = CommCareUser.by_domain(domain) if not test_list else test_list
    for user in users:
        location = user.location
        if user.is_active and location and location.location_type == loc_type:
            status_exists = SupplyPointStatus.objects.filter(
                location_id=location.get_id,
                status_type=status_type,
                status_date__gte=date).exists()
            groups = location.metadata.get('group', None)
            if groups and current_group in groups and not status_exists:
                send_translated_message(user, sms_text)
    update_statuses(sp_ids, status_type, SupplyPointStatusValues.REMINDER_SENT)
 def relevant_group(cls):
     # this doesn't really matter since it's relevant every month
     return DeliveryGroups().current_delivering_group()
Beispiel #16
0
def process_non_facility_warehouse_data(location,
                                        start_date,
                                        end_date,
                                        runner=None,
                                        strict=True):
    facs = get_non_archived_facilities_below(location, end_date)

    start_date = datetime(start_date.year, start_date.month, 1)
    end_date = datetime(end_date.year, end_date.month, 1)

    if runner:
        runner.location = location
        runner.save()
    fac_ids = [f.location_id for f in facs]
    logging.info("processing non-facility %s (%s), %s children" %
                 (location.name, str(location.location_id), len(facs)))
    prods = SQLProduct.objects.filter(domain=location.domain,
                                      is_archived=False)

    sub_summaries = OrganizationSummary.objects.filter(
        location_id__in=fac_ids,
        date__range=(start_date, end_date),
        average_lead_time_in_days__gt=0).values('date').annotate(
            average_time=Avg('average_lead_time_in_days'))

    sub_summaries = {(subsummary['date'].year, subsummary['date'].month):
                     subsummary
                     for subsummary in sub_summaries}

    sub_prods = ProductAvailabilityData.objects.filter(
        location_id__in=fac_ids,
        date__range=(start_date, end_date)).values('product', 'date').annotate(
            total_sum=Sum('total'),
            with_stock_sum=Sum('with_stock'),
            without_stock_sum=Sum('without_stock'),
        )

    sub_prods = {((sub_prod['date'].year, sub_prod['date'].month),
                  sub_prod['product']): sub_prod
                 for sub_prod in sub_prods}

    sub_group_summaries = GroupSummary.objects.filter(
        org_summary__location_id__in=fac_ids,
        org_summary__date__range=(start_date, end_date)).values(
            'title',
            'org_summary__date').annotate(total_sum=Sum('total'),
                                          responded_sum=Sum('responded'),
                                          on_time_sum=Sum('on_time'),
                                          complete_sum=Sum('complete'))

    sub_group_summaries = {((sub_group_summary['org_summary__date'].year,
                             sub_group_summary['org_summary__date'].month),
                            sub_group_summary['title']): sub_group_summary
                           for sub_group_summary in sub_group_summaries}

    total_orgs = len(facs)
    for year, month in months_between(start_date, end_date):
        window_date = datetime(year, month, 1)
        org_summary = OrganizationSummary.objects.get_or_create(
            location_id=location.location_id, date=window_date)[0]

        org_summary.total_orgs = total_orgs

        # lead times
        if (year, month) in sub_summaries:
            sub_summary = sub_summaries[year, month]
            org_summary.average_lead_time_in_days = sub_summary['average_time']
        else:
            org_summary.average_lead_time_in_days = 0

        org_summary.save()
        # product availability
        for p in prods:
            product_data = ProductAvailabilityData.objects.get_or_create(
                product=p.product_id,
                location_id=location.location_id,
                date=window_date)[0]

            sub_prod = sub_prods.get(((year, month), p.product_id), {})

            product_data.total = sub_prod.get('total_sum', 0)
            if strict:
                assert product_data.total == total_orgs, \
                    "total should match number of sub facilities %s-%s" % (product_data.total, total_orgs)
            product_data.with_stock = sub_prod.get('with_stock_sum', 0)
            product_data.without_stock = sub_prod.get('without_stock_sum', 0)
            product_data.without_data = product_data.total - product_data.with_stock - product_data.without_stock
            product_data.save()

        dg = DeliveryGroups(month=month, facs=facs)
        for status_type in const.NEEDED_STATUS_TYPES:
            gsum = GroupSummary.objects.get_or_create(org_summary=org_summary,
                                                      title=status_type)[0]

            sub_sum = sub_group_summaries.get(((year, month), status_type), {})

            gsum.total = sub_sum.get('total_sum', 0)
            gsum.responded = sub_sum.get('responded_sum', 0)
            gsum.on_time = sub_sum.get('on_time_sum', 0)
            gsum.complete = sub_sum.get('complete_sum', 0)
            gsum.save()

            if status_type == SupplyPointStatusTypes.DELIVERY_FACILITY:
                expected = len(dg.delivering())
            elif status_type == SupplyPointStatusTypes.R_AND_R_FACILITY:
                expected = len(dg.submitting())
            elif status_type == SupplyPointStatusTypes.SOH_FACILITY \
                    or status_type == SupplyPointStatusTypes.SUPERVISION_FACILITY:
                expected = len(facs)
            if gsum.total != expected:
                logging.info("expected %s but was %s for %s" %
                             (expected, gsum.total, gsum))

        for alert_type in [
                const.RR_NOT_SUBMITTED, const.DELIVERY_NOT_RECEIVED,
                const.SOH_NOT_RESPONDING, const.RR_NOT_RESPONDED,
                const.DELIVERY_NOT_RESPONDING
        ]:
            sub_alerts = Alert.objects.filter(location_id__in=fac_ids,
                                              date=window_date,
                                              type=alert_type)
            aggregate_response_alerts(location.location_id, window_date,
                                      sub_alerts, alert_type)

    update_historical_data_for_location(location)
def process_non_facility_warehouse_data(org, start_date, end_date, strict=True):
    facs = get_nested_children(org)
    fac_ids = [f._id for f in facs]
    logging.info("processing non-facility %s (%s), %s children" % (org.name, str(org._id), len(facs)))
    for year, month in months_between(start_date, end_date):
        window_date = datetime(year, month, 1)
        org_summary = OrganizationSummary.objects.get_or_create(supply_point=org._id, date=window_date)[0]

        org_summary.total_orgs = len(facs)
        sub_summaries = OrganizationSummary.objects.filter(date=window_date, supply_point__in=fac_ids)

        subs_with_lead_time = [s for s in sub_summaries if s.average_lead_time_in_days]
        # lead times
        if subs_with_lead_time:
            days_sum = sum([s.average_lead_time_in_days for s in subs_with_lead_time])
            org_summary.average_lead_time_in_days = days_sum / len(subs_with_lead_time)
        else:
            org_summary.average_lead_time_in_days = 0

        org_summary.save()
        # product availability
        prods = Product.ids_by_domain(org.domain)
        for p in prods:
            product_data = ProductAvailabilityData.objects.get_or_create(product=p,
                                                                         supply_point=org._id,
                                                                         date=window_date)[0]

            sub_prods = ProductAvailabilityData.objects.filter(product=p,
                                                               supply_point__in=fac_ids,
                                                               date=window_date)

            product_data.total = sum([p.total for p in sub_prods])
            if strict:
                assert product_data.total == len(facs), \
                    "total should match number of sub facilities"
            product_data.with_stock = sum([p.with_stock for p in sub_prods])
            product_data.without_stock = sum([p.without_stock for p in sub_prods])
            product_data.without_data = product_data.total - product_data.with_stock - product_data.without_stock
            product_data.save()

        dg = DeliveryGroups(month=month, facs=facs)
        for type in NEEDED_STATUS_TYPES:
            gsum = GroupSummary.objects.get_or_create(org_summary=org_summary, title=type)[0]
            sub_sums = GroupSummary.objects.filter(title=type, org_summary__in=sub_summaries).all()

            # TODO: see if moving the aggregation to the db makes it
            # faster, if this is slow
            gsum.total = sum([s.total for s in sub_sums])
            gsum.responded = sum([s.responded for s in sub_sums])
            gsum.on_time = sum([s.on_time for s in sub_sums])
            gsum.complete = sum([s.complete for s in sub_sums])
            # gsum.missed_response = sum([s.missed_response for s in sub_sums])
            gsum.save()

            if type == SupplyPointStatusTypes.DELIVERY_FACILITY:
                expected = len(dg.delivering())
            elif type == SupplyPointStatusTypes.R_AND_R_FACILITY:
                expected = len(dg.submitting())
            elif type == SupplyPointStatusTypes.SOH_FACILITY \
                    or type == SupplyPointStatusTypes.SUPERVISION_FACILITY:
                expected = len(facs)
            if gsum.total != expected:
                logging.info("expected %s but was %s for %s" % (expected, gsum.total, gsum))

        for alert_type in ['rr_not_submitted', 'delivery_not_received',
                           'soh_not_responding', 'rr_not_responded', 'delivery_not_responding']:
            sub_alerts = Alert.objects.filter(supply_point__in=fac_ids, date=window_date, type=alert_type)
            aggregate_response_alerts(org, window_date, sub_alerts, alert_type)
 def relevant_group(cls):
     return DeliveryGroups().current_submitting_group()
Beispiel #19
0
 def current_group(self):
     return DeliveryGroups().current_delivering_group(self.date.month)
Beispiel #20
0
def process_non_facility_warehouse_data(location, start_date, end_date, runner=None, strict=True):
    if runner:
        runner.location = location.sql_location
        runner.save()
    facs = get_non_archived_facilities_below(location)
    fac_ids = [f._id for f in facs]
    logging.info("processing non-facility %s (%s), %s children"
                 % (location.name, str(location.location_id), len(facs)))
    for year, month in months_between(start_date, end_date):
        window_date = datetime(year, month, 1)
        org_summary = OrganizationSummary.objects.get_or_create(
            location_id=location.location_id, date=window_date
        )[0]

        org_summary.total_orgs = len(facs)
        sub_summaries = OrganizationSummary.objects.filter(date=window_date, location_id__in=fac_ids)

        subs_with_lead_time = [s for s in sub_summaries if s.average_lead_time_in_days]
        # lead times
        if subs_with_lead_time:
            days_sum = sum([s.average_lead_time_in_days for s in subs_with_lead_time])
            org_summary.average_lead_time_in_days = days_sum / len(subs_with_lead_time)
        else:
            org_summary.average_lead_time_in_days = 0

        org_summary.save()
        # product availability
        prods = SQLProduct.objects.filter(domain=location.domain, is_archived=False)
        for p in prods:
            product_data = ProductAvailabilityData.objects.get_or_create(product=p.product_id,
                                                                         location_id=location.location_id,
                                                                         date=window_date)[0]

            sub_prods = ProductAvailabilityData.objects.filter(product=p.product_id,
                                                               location_id__in=fac_ids,
                                                               date=window_date)

            product_data.total = sum([p.total for p in sub_prods])
            if strict:
                assert product_data.total == len(facs), \
                    "total should match number of sub facilities"
            product_data.with_stock = sum([p.with_stock for p in sub_prods])
            product_data.without_stock = sum([p.without_stock for p in sub_prods])
            product_data.without_data = product_data.total - product_data.with_stock - product_data.without_stock
            product_data.save()

        dg = DeliveryGroups(month=month, facs=facs)
        for status_type in const.NEEDED_STATUS_TYPES:
            gsum = GroupSummary.objects.get_or_create(org_summary=org_summary, title=status_type)[0]
            sub_sums = GroupSummary.objects.filter(title=status_type, org_summary__in=sub_summaries).all()

            # TODO: see if moving the aggregation to the db makes it
            # faster, if this is slow
            gsum.total = sum([s.total for s in sub_sums])
            gsum.responded = sum([s.responded for s in sub_sums])
            gsum.on_time = sum([s.on_time for s in sub_sums])
            gsum.complete = sum([s.complete for s in sub_sums])
            # gsum.missed_response = sum([s.missed_response for s in sub_sums])
            gsum.save()

            if status_type == SupplyPointStatusTypes.DELIVERY_FACILITY:
                expected = len(dg.delivering())
            elif status_type == SupplyPointStatusTypes.R_AND_R_FACILITY:
                expected = len(dg.submitting())
            elif status_type == SupplyPointStatusTypes.SOH_FACILITY \
                    or status_type == SupplyPointStatusTypes.SUPERVISION_FACILITY:
                expected = len(facs)
            if gsum.total != expected:
                logging.info("expected %s but was %s for %s" % (expected, gsum.total, gsum))

        for alert_type in [const.RR_NOT_SUBMITTED, const.DELIVERY_NOT_RECEIVED,
                           const.SOH_NOT_RESPONDING, const.RR_NOT_RESPONDED, const.DELIVERY_NOT_RESPONDING]:
            sub_alerts = Alert.objects.filter(location_id__in=fac_ids, date=window_date, type=alert_type)
            aggregate_response_alerts(location.location_id, window_date, sub_alerts, alert_type)
Beispiel #21
0
    def rows(self):
        rows = []
        locations = SQLLocation.objects.filter(
            parent__location_id=self.config['location_id'])
        dg = []
        for date in list(
                rrule.rrule(rrule.MONTHLY,
                            dtstart=self.config['startdate'],
                            until=self.config['enddate'])):
            dg.extend(DeliveryGroups().submitting(locations, date.month))

        for child in dg:
            total_responses = 0
            total_possible = 0
            submitted, rr_value = randr_value(child.location_id,
                                              self.config['startdate'],
                                              self.config['enddate'])
            if child.is_archived and not rr_value:
                continue

            group_summaries = GroupSummary.objects.filter(
                org_summary__date__lte=self.config['startdate'],
                org_summary__location_id=child.location_id,
                title=SupplyPointStatusTypes.R_AND_R_FACILITY,
                total=1)

            if not group_summaries:
                continue

            for group_summary in group_summaries:
                if group_summary:
                    total_responses += group_summary.responded
                    total_possible += group_summary.total
            hist_resp_rate = rr_format_percent(total_responses, total_possible)

            url = make_url(
                FacilityDetailsReport, self.config['domain'],
                '?location_id=%s&filter_by_program=%s&'
                'datespan_type=%s&datespan_first=%s&datespan_second=%s',
                (child.location_id, self.config['program'],
                 self.config['datespan_type'], self.config['datespan_first'],
                 self.config['datespan_second']))

            contact = get_one_user_at_location(self.config['domain'],
                                               child.location_id)

            if contact:
                role = contact.user_data.get('role') or ""
                args = (contact.first_name, contact.last_name, role,
                        contact.default_phone_number)
                contact_string = "%s %s (%s) %s" % args
            else:
                contact_string = ""

            rows.append([
                child.site_code,
                link_format(child.name, url),
                get_span(submitted) % (rr_value.strftime("%d %b %Y")
                                       if rr_value else "Not reported"),
                contact_string, hist_resp_rate
            ])

        return rows
Beispiel #22
0
 def setUp(self):
     super(TestDeliveryReminder, self).setUp()
     self.facility.metadata['group'] = DeliveryGroups(
     ).current_delivering_group()
     self.facility.save()
Beispiel #23
0
def process_non_facility_warehouse_data(location,
                                        start_date,
                                        end_date,
                                        runner,
                                        strict=True):
    runner.location = location.sql_location
    runner.save()
    facs = get_non_archived_facilities_below(location)
    fac_ids = [f._id for f in facs]
    logging.info("processing non-facility %s (%s), %s children" %
                 (location.name, str(location._id), len(facs)))
    for year, month in months_between(start_date, end_date):
        window_date = datetime(year, month, 1)
        org_summary = OrganizationSummary.objects.get_or_create(
            location_id=location._id, date=window_date)[0]

        org_summary.total_orgs = len(facs)
        sub_summaries = OrganizationSummary.objects.filter(
            date=window_date, location_id__in=fac_ids)

        subs_with_lead_time = [
            s for s in sub_summaries if s.average_lead_time_in_days
        ]
        # lead times
        if subs_with_lead_time:
            days_sum = sum(
                [s.average_lead_time_in_days for s in subs_with_lead_time])
            org_summary.average_lead_time_in_days = days_sum / len(
                subs_with_lead_time)
        else:
            org_summary.average_lead_time_in_days = 0

        org_summary.save()
        # product availability
        prods = SQLProduct.objects.filter(domain=location.domain,
                                          is_archived=False)
        for p in prods:
            product_data = ProductAvailabilityData.objects.get_or_create(
                product=p.product_id,
                location_id=location._id,
                date=window_date)[0]

            sub_prods = ProductAvailabilityData.objects.filter(
                product=p.product_id,
                location_id__in=fac_ids,
                date=window_date)

            product_data.total = sum([p.total for p in sub_prods])
            if strict:
                assert product_data.total == len(facs), \
                    "total should match number of sub facilities"
            product_data.with_stock = sum([p.with_stock for p in sub_prods])
            product_data.without_stock = sum(
                [p.without_stock for p in sub_prods])
            product_data.without_data = product_data.total - product_data.with_stock - product_data.without_stock
            product_data.save()

        dg = DeliveryGroups(month=month, facs=facs)
        for status_type in const.NEEDED_STATUS_TYPES:
            gsum = GroupSummary.objects.get_or_create(org_summary=org_summary,
                                                      title=status_type)[0]
            sub_sums = GroupSummary.objects.filter(
                title=status_type, org_summary__in=sub_summaries).all()

            # TODO: see if moving the aggregation to the db makes it
            # faster, if this is slow
            gsum.total = sum([s.total for s in sub_sums])
            gsum.responded = sum([s.responded for s in sub_sums])
            gsum.on_time = sum([s.on_time for s in sub_sums])
            gsum.complete = sum([s.complete for s in sub_sums])
            # gsum.missed_response = sum([s.missed_response for s in sub_sums])
            gsum.save()

            if status_type == SupplyPointStatusTypes.DELIVERY_FACILITY:
                expected = len(dg.delivering())
            elif status_type == SupplyPointStatusTypes.R_AND_R_FACILITY:
                expected = len(dg.submitting())
            elif status_type == SupplyPointStatusTypes.SOH_FACILITY \
                    or status_type == SupplyPointStatusTypes.SUPERVISION_FACILITY:
                expected = len(facs)
            if gsum.total != expected:
                logging.info("expected %s but was %s for %s" %
                             (expected, gsum.total, gsum))

        for alert_type in [
                const.RR_NOT_SUBMITTED, const.DELIVERY_NOT_RECEIVED,
                const.SOH_NOT_RESPONDING, const.RR_NOT_RESPONDED,
                const.DELIVERY_NOT_RESPONDING
        ]:
            sub_alerts = Alert.objects.filter(location_id__in=fac_ids,
                                              date=window_date,
                                              type=alert_type)
            aggregate_response_alerts(location._id, window_date, sub_alerts,
                                      alert_type)
Beispiel #24
0
 def setUp(self):
     super(TestSupervisionStatusSet, self).setUp()
     self.facility.metadata['group'] = DeliveryGroups(
     ).current_submitting_group()
     self.facility.save()
Beispiel #25
0
def process_non_facility_warehouse_data(location, start_date, end_date, runner=None, strict=True):
    start_date = datetime(start_date.year, start_date.month, 1)
    end_date = datetime(end_date.year, end_date.month, 1)

    if runner:
        runner.location = location.sql_location
        runner.save()
    facs = get_non_archived_facilities_below(location)
    fac_ids = [f._id for f in facs]
    logging.info("processing non-facility %s (%s), %s children"
                 % (location.name, str(location.location_id), len(facs)))
    prods = SQLProduct.objects.filter(domain=location.domain, is_archived=False)

    sub_summaries = OrganizationSummary.objects.filter(
        location_id__in=fac_ids, date__range=(start_date, end_date), average_lead_time_in_days__gt=0
    ).values('date').annotate(average_time=Avg('average_lead_time_in_days'))

    sub_summaries = {
        (subsummary['date'].year, subsummary['date'].month): subsummary
        for subsummary in sub_summaries
    }

    sub_prods = ProductAvailabilityData.objects.filter(
        location_id__in=fac_ids, date__range=(start_date, end_date)
    ).values('product', 'date').annotate(
        total_sum=Sum('total'),
        with_stock_sum=Sum('with_stock'),
        without_stock_sum=Sum('without_stock'),
    )

    sub_prods = {
        ((sub_prod['date'].year, sub_prod['date'].month), sub_prod['product']): sub_prod for sub_prod in sub_prods
    }

    sub_group_summaries = GroupSummary.objects.filter(
        org_summary__location_id__in=fac_ids,
        org_summary__date__range=(start_date, end_date)
    ).values('title', 'org_summary__date').annotate(
        total_sum=Sum('total'),
        responded_sum=Sum('responded'),
        on_time_sum=Sum('on_time'),
        complete_sum=Sum('complete')
    )

    sub_group_summaries = {
        ((sub_group_summary['org_summary__date'].year, sub_group_summary['org_summary__date'].month), sub_group_summary['title']): sub_group_summary
        for sub_group_summary in sub_group_summaries
    }

    total_orgs = len(facs)
    for year, month in months_between(start_date, end_date):
        window_date = datetime(year, month, 1)
        org_summary = OrganizationSummary.objects.get_or_create(
            location_id=location.location_id, date=window_date
        )[0]

        org_summary.total_orgs = total_orgs

        # lead times
        if (year, month) in sub_summaries:
            sub_summary = sub_summaries[year, month]
            org_summary.average_lead_time_in_days = sub_summary['average_time']
        else:
            org_summary.average_lead_time_in_days = 0

        org_summary.save()
        # product availability
        for p in prods:
            product_data = ProductAvailabilityData.objects.get_or_create(product=p.product_id,
                                                                         location_id=location.location_id,
                                                                         date=window_date)[0]

            sub_prod = sub_prods.get(((year, month), p.product_id), {})

            product_data.total = sub_prod.get('total_sum', 0)
            if strict:
                assert product_data.total == total_orgs, \
                    "total should match number of sub facilities %s-%s" % (product_data.total, total_orgs)
            product_data.with_stock = sub_prod.get('with_stock_sum', 0)
            product_data.without_stock = sub_prod.get('without_stock_sum', 0)
            product_data.without_data = product_data.total - product_data.with_stock - product_data.without_stock
            product_data.save()

        dg = DeliveryGroups(month=month, facs=facs)
        for status_type in const.NEEDED_STATUS_TYPES:
            gsum = GroupSummary.objects.get_or_create(org_summary=org_summary, title=status_type)[0]

            sub_sum = sub_group_summaries.get(((year, month), status_type), {})

            gsum.total = sub_sum.get('total_sum', 0)
            gsum.responded = sub_sum.get('responded_sum', 0)
            gsum.on_time = sub_sum.get('on_time_sum', 0)
            gsum.complete = sub_sum.get('complete_sum', 0)
            gsum.save()

            if status_type == SupplyPointStatusTypes.DELIVERY_FACILITY:
                expected = len(dg.delivering())
            elif status_type == SupplyPointStatusTypes.R_AND_R_FACILITY:
                expected = len(dg.submitting())
            elif status_type == SupplyPointStatusTypes.SOH_FACILITY \
                    or status_type == SupplyPointStatusTypes.SUPERVISION_FACILITY:
                expected = len(facs)
            if gsum.total != expected:
                logging.info("expected %s but was %s for %s" % (expected, gsum.total, gsum))

        for alert_type in [const.RR_NOT_SUBMITTED, const.DELIVERY_NOT_RECEIVED,
                           const.SOH_NOT_RESPONDING, const.RR_NOT_RESPONDED, const.DELIVERY_NOT_RESPONDING]:
            sub_alerts = Alert.objects.filter(location_id__in=fac_ids, date=window_date, type=alert_type)
            aggregate_response_alerts(location.location_id, window_date, sub_alerts, alert_type)

    update_historical_data_for_location(location)