Beispiel #1
0
 def check_day(*args, **kwargs):
     comp = date_generator_func()
     appropriate_day = get_day_of_month(comp.year, comp.month, day)
     if comp.date() == appropriate_day:
         return f(*args, **kwargs)
     else:
         pass
    def rows(self):
        rows = []
        enddate = self.config['enddate']

        products = self.get_products()

        if self.config['location_id']:
            locations = SQLLocation.objects.filter(parent__location_id=self.config['location_id'])
            for loc in locations:
                supply_point = loc.supply_point_id

                status, last_reported = get_last_reported(supply_point, self.config['domain'], enddate)
                hisp = get_hisp_resp_rate(loc)

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

                row_data = [
                    loc.site_code,
                    link_format(loc.name, url),
                    loc.metadata.get('group', None),
                    icon_format(status, last_reported),
                    "<span title='%d of %d'>%s%%</span>" % (hisp[1],
                                                            hisp[2],
                                                            floatformat(hisp[0] * 100.0)) if hisp else "No data"
                ]

                for product in products:
                    last_of_the_month = get_day_of_month(enddate.year, enddate.month, -1)
                    first_of_the_next_month = last_of_the_month + timedelta(days=1)
                    try:
                        srs = StockTransaction.objects.filter(
                            report__domain=self.config['domain'],
                            report__date__lt=first_of_the_next_month,
                            case_id=supply_point,
                            product_id=product.product_id
                        ).order_by("-report__date")[0]
                    except IndexError:
                        srs = None

                    if srs:
                        try:
                            ss = StockState.objects.get(case_id=supply_point, product_id=product.product_id)
                            val = calculate_months_remaining(ss, srs.stock_on_hand)
                            ret = _months_or_default(val, -1)
                        except StockState.DoesNotExist:
                            ret = -1
                    else:
                        ret = -1

                    row_data.append(product_format(ret, srs, self.config['soh_month']))

                rows.append(row_data)

        return rows
Beispiel #3
0
    def rows(self):
        rows = []
        enddate = self.config['enddate']

        products = self.get_products()

        if self.config['location_id']:
            locations = SQLLocation.active_objects.filter(parent__location_id=self.config['location_id'])
            for loc in locations:
                supply_point = loc.supply_point_id

                status, last_reported = get_last_reported(supply_point, self.config['domain'], enddate)
                hisp = get_hisp_resp_rate(loc)

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

                row_data = [
                    loc.site_code,
                    link_format(loc.name, url),
                    loc.metadata.get('group', None),
                    icon_format(status, last_reported),
                    "<span title='%d of %d'>%s%%</span>" % (hisp[1],
                                                            hisp[2],
                                                            floatformat(hisp[0] * 100.0)) if hisp else "No data"
                ]

                for product in products:
                    last_of_the_month = get_day_of_month(enddate.year, enddate.month, -1)
                    first_of_the_next_month = last_of_the_month + timedelta(days=1)
                    try:
                        srs = StockTransaction.objects.filter(
                            report__domain=self.config['domain'],
                            report__date__lt=first_of_the_next_month,
                            case_id=supply_point,
                            product_id=product.product_id
                        ).order_by("-report__date")[0]
                    except IndexError:
                        srs = None

                    if srs:
                        try:
                            ss = StockState.objects.get(case_id=supply_point, product_id=product.product_id)
                            val = calculate_months_remaining(ss, srs.stock_on_hand)
                            ret = _months_or_default(val, -1)
                        except StockState.DoesNotExist:
                            ret = -1
                    else:
                        ret = -1

                    row_data.append(product_format(ret, srs, self.config['soh_month']))

                rows.append(row_data)

        return rows
Beispiel #4
0
def amc_plot(sps, datespan):
    cols = {"date": ("datetime", "Date")}
    products = Product.objects.all().order_by('sms_code')
    for p in products:
        if p.average_monthly_consumption:
            cols[p.sms_code] = (
                'number', p.sms_code
            )  #, {'type': 'string', 'label': "title_"+s.sms_code}]
    table = gviz_api.DataTable(cols)

    data_rows = {}
    for year, month in datespan.months_iterator():
        dm = DateSpan(startdate=datetime(year, month, 1) -
                      relativedelta(months=2),
                      enddate=get_day_of_month(year, month, -1))
        dt = datetime(year, month, 1)
        if not dt in data_rows: data_rows[dt] = {}
        for pr in products:
            cache_key = "log-amc-%s-%s-%s" % (pr.sms_code, year, month)
            cached_amc = cache.get(cache_key)
            if cached_amc is not None:
                data_rows[dt][pr.sms_code] = cached_amc
            else:
                ps = ProductStock.objects.filter(supply_point__in=sps,
                                                 product=pr,
                                                 is_active=True)
                total = 0.0
                count = 0.0
                for p in ps:
                    try:
                        total += p.get_daily_consumption(datespan=dm) * 30.0
                        count += 1
                    except:
                        continue
                amc_avg = total / count if count else 0
                cache.set(cache_key, amc_avg, (30 * 24 * 60 * 60) - 1)
                data_rows[dt][pr.sms_code] = amc_avg

    rows = []
    for d in data_rows.keys():
        q = {"date": d}
        q.update(data_rows[d])
        rows += [q]
    if not rows:
        return None
    table.LoadData(rows)

    chart_data = table.ToJSCode("chart_data",
                                columns_order=["date"] +
                                [x for x in cols.keys() if x != "date"],
                                order_by="date")
    return chart_data, data_rows
Beispiel #5
0
def amc_plot(sps, datespan, products=None):
    cols = {"date": ("datetime", "Date")}
    products = products or Product.objects.all().order_by("sms_code")
    for p in products:
        if p.average_monthly_consumption:
            cols[p.sms_code] = ("number", p.sms_code)  # , {'type': 'string', 'label': "title_"+s.sms_code}]
    table = gviz_api.DataTable(cols)

    data_rows = {}
    for year, month in datespan.months_iterator():
        dm = DateSpan(
            startdate=datetime(year, month, 1) - relativedelta(months=2), enddate=get_day_of_month(year, month, -1)
        )
        dt = datetime(year, month, 1)
        if not dt in data_rows:
            data_rows[dt] = {}
        for pr in products:
            cache_key = "log-amc-%s-%s-%s" % (pr.sms_code, year, month)
            cached_amc = cache.get(cache_key)
            if cached_amc is not None:
                data_rows[dt][pr.sms_code] = cached_amc
            else:
                ps = ProductStock.objects.filter(supply_point__in=sps, product=pr, is_active=True)
                total = 0.0
                count = 0.0
                for p in ps:
                    try:
                        total += p.get_daily_consumption(datespan=dm) * 30.0
                        count += 1
                    except:
                        continue
                amc_avg = total / count if count else 0
                cache.set(cache_key, amc_avg, (30 * 24 * 60 * 60) - 1)
                data_rows[dt][pr.sms_code] = amc_avg

    rows = []
    for d in data_rows.keys():
        q = {"date": d}
        q.update(data_rows[d])
        rows += [q]
    if not rows:
        return None
    table.LoadData(rows)

    chart_data = table.ToJSCode(
        "chart_data", columns_order=["date"] + [x for x in cols.keys() if x != "date"], order_by="date"
    )
    return chart_data, data_rows
Beispiel #6
0
def get_patient_stats_detail_context(report_date, patient_id):
    """

    """
    context = {}
    days = get_day_of_month(report_date.year, report_date.month, -1).day
    num_days_in_report_month = days
    datetime_end_month = datetime.datetime(report_date.year, report_date.month,
                                           num_days_in_report_month, 23, 59)
    datetime_start_month = datetime.datetime(report_date.year,
                                             report_date.month, 01, 0, 0)

    patient = get_object_or_404(Patient, id=patient_id)
    context["daily_doses"] = patient.daily_doses

    context["patient"] = patient
    if not report_date:
        report_date = datetime.now()

    wp_usage_rows = []
    for day in range(1, days + 1):
        row_date = datetime.date(report_date.year, report_date.month, day)
        if is_patient_out_of_date_range(patient, row_date):
            continue

        row = []
        row.append(row_date)
        msg_count = patient.wisepill_messages.filter(
            timestamp__year=row_date.year,
            timestamp__month=row_date.month,
            timestamp__day=row_date.day).count()
        row.append(msg_count)
        wp_usage_rows.append(row)

    pill_count_data = {}
    pills_missed_data = {}
    pill_count_data["patient_id"] = patient.subject_number
    pills_missed = patient.pillsmissed_set.filter(
        date__range=(datetime_start_month,
                     datetime_end_month)).order_by('-date')[:4]
    weeks = []
    for pm in pills_missed:
        week_start = pm.date - datetime.timedelta(days=7)
        week_end = pm.date
        num_missed = pm.num_missed
        weeks.append({
            'pills_missed': num_missed,
            'week_start': week_start,
            'week_end': week_end,
            'received_on': pm.date
        })

    pills_missed_data[patient] = weeks

    pm_weekly_aggregate = []
    num_weeks_in_report_month = num_days_in_report_month / 7
    for week in range(0, num_weeks_in_report_month + 1):
        week_start = (datetime.date(report_date.year, report_date.month, 1) +
                      datetime.timedelta(days=week * 7))
        week_end = week_start + datetime.timedelta(days=7)
        pm_week_data = {}
        if is_patient_out_of_date_range(patient, week_start, week_end):
            continue

        pills_missed_set = patient.pillsmissed_set.filter(
            date__gt=week_start, date__lt=week_end,
            source=1)  # source = 1 means SMS
        if len(pills_missed_set) > 0:
            pills_missed_week = pills_missed_set.aggregate(
                Sum('num_missed'))["num_missed__sum"]
        else:
            pills_missed_week = "No Response/No Query"

        pm_week_data["sum"] = pills_missed_week
        pm_week_data["week_start"] = week_start
        pm_week_data["week_end"] = week_end
        pm_weekly_aggregate.append(pm_week_data)

    patient_connections = patient.contact.connection_set.all()
    messages = Message.objects.filter(connection__in=patient_connections)

    messages = messages.exclude(text__contains='start tree').exclude(
        text__contains='TimeOut')  #exclude internal messages
    messages = messages.filter(
        date__range=(datetime_start_month, datetime_end_month)).order_by(
            '-date')  #stick to the report month

    reminders = Reminder.objects.all()

    context["pat_messages"] = messages
    context["wp_usage_rows"] = wp_usage_rows
    context["pm_weeks"] = pills_missed_data
    context["pm_weekly"] = pm_weekly_aggregate
    return context
 def testDays(self):
     # there's nothing fancy here
     self.assertEqual(date(2011, 8, 1), get_day_of_month(2011, 8, 1))
     self.assertEqual(date(2011, 8, 2), get_day_of_month(2011, 8, 2))
     self.assertEqual(date(2011, 8, 3), get_day_of_month(2011, 8, 3))
     self.assertEqual(date(2011, 8, 4), get_day_of_month(2011, 8, 4))
     self.assertEqual(date(2011, 8, 5), get_day_of_month(2011, 8, 5))
     self.assertEqual(date(2011, 8, 6), get_day_of_month(2011, 8, 6))
     
     # negative
     self.assertEqual(date(2011, 8, 31), get_day_of_month(2011, 8, -1))
     self.assertEqual(date(2011, 8, 28), get_day_of_month(2011, 8, -4))
     
     # random
     self.assertEqual(date(2011, 9, 1), get_day_of_month(2011, 9, 1))
     self.assertEqual(date(2011, 10, 1), get_day_of_month(2011, 10, 1))
     self.assertEqual(date(2012, 2, 5), get_day_of_month(2012, 2, 5))
     
     # leap year
     self.assertEqual(date(2012, 2, 29), get_day_of_month(2012, 2, -1))
     
     
     # fail
     try:
         get_day_of_month(2011, 2, 30)
         self.fail("previous call should have failed")
     except ValueError: pass
     
     try:
         get_day_of_month(2011, 2, -30)
         self.fail("previous call should have failed")
     except ValueError: pass
Beispiel #8
0
    def rows(self):
        rows = []
        enddate = self.config['enddate']

        def get_last_reported(supplypoint):

            last_bd_of_the_month = get_business_day_of_month(enddate.year,
                                                             enddate.month,
                                                             -1)
            st = StockTransaction.objects.filter(
                case_id=supplypoint,
                type='stockonhand',
                report__date__lte=last_bd_of_the_month
            ).order_by('-report__date')

            last_bd_of_last_month = datetime.combine(get_business_day_of_month(enddate.year,
                                                     enddate.month,
                                                     -1), time())
            if st:
                sts = _reported_on_time(last_bd_of_last_month, st[0].report.date)
                return sts, st[0].report.date.date()
            else:
                sts = OnTimeStates.NO_DATA
                return sts, None

        def get_hisp_resp_rate(location):
            statuses = SupplyPointStatus.objects.filter(supply_point=location.location_id,
                                                        status_type=SupplyPointStatusTypes.SOH_FACILITY)
            if not statuses:
                return None
            status_month_years = set([(x.status_date.month, x.status_date.year) for x in statuses])
            denom = len(status_month_years)
            num = 0
            for s in status_month_years:
                f = statuses.filter(status_date__month=s[0], status_date__year=s[1]).filter(
                    Q(status_value=SupplyPointStatusValues.SUBMITTED) |
                    Q(status_value=SupplyPointStatusValues.NOT_SUBMITTED) |
                    Q(status_value=SupplyPointStatusValues.RECEIVED) |
                    Q(status_value=SupplyPointStatusValues.NOT_RECEIVED)).order_by("-status_date")
                if f.count():
                    num += 1

            return float(num) / float(denom), num, denom

        if not self.config['products']:
            products = SQLProduct.objects.filter(domain=self.config['domain']).order_by('code')
        else:
            products = SQLProduct.objects.filter(product_id__in=self.config['products'],
                                                 domain=self.config['domain']).order_by('code')

        if self.config['location_id']:
            locations = SQLLocation.objects.filter(parent__location_id=self.config['location_id'],
                                                   site_code__icontains=self.config['msd_code'])
            for loc in locations:
                supply_point = loc.supply_point_id

                status, last_reported = get_last_reported(supply_point)
                hisp = get_hisp_resp_rate(loc)

                url = make_url(FacilityDetailsReport, self.config['domain'],
                           '?location_id=%s&filter_by_program=%s%s',
                           (loc.location_id, self.config['program'], self.config['prd_part_url']))

                row_data = [
                    loc.site_code,
                    link_format(loc.name, url),
                    loc.metadata.get('group', None),
                    icon_format(status, last_reported),
                    "<span title='%d of %d'>%s%%</span>" % (hisp[1],
                                                            hisp[2],
                                                            floatformat(hisp[0] * 100.0)) if hisp else "No data"
                ]

                for product in products:
                    last_of_the_month = get_day_of_month(enddate.year, enddate.month, -1)
                    first_of_the_next_month = last_of_the_month + timedelta(days=1)
                    try:
                        srs = StockTransaction.objects.filter(
                            report__date__lt=first_of_the_next_month,
                            case_id=supply_point,
                            product_id=product.product_id).order_by("-report__date")[0]
                    except IndexError:
                        srs = None

                    if srs:
                        def calculate_months_remaining(stock_state, quantity):
                            consumption = stock_state.get_monthly_consumption()
                            if consumption is not None and consumption > 0 and quantity is not None:
                                return float(quantity) / float(consumption)
                            elif quantity == 0:
                                return 0
                            return None
                        try:
                            ss = StockState.objects.get(case_id=supply_point, product_id=product.product_id)
                            val = calculate_months_remaining(ss, srs.stock_on_hand)
                            ret = _months_or_default(val, -1)
                        except StockState.DoesNotExist:
                            ret = -1
                    else:
                        ret = -1

                    row_data.append(product_format(ret, srs, self.config['soh_month']))

                rows.append(row_data)

        return rows
Beispiel #9
0
def get_patient_stats_detail_context(report_date, patient_id):
    """

    """
    context = {}
    days = get_day_of_month(report_date.year,report_date.month,-1).day
    num_days_in_report_month = days
    datetime_end_month = datetime.datetime(report_date.year,report_date.month,num_days_in_report_month,23,59)
    datetime_start_month = datetime.datetime(report_date.year, report_date.month,01,0,0)

    patient = get_object_or_404(Patient, id=patient_id)
    context["daily_doses"] = patient.daily_doses

    context["patient"] = patient
    if not report_date:
        report_date = datetime.now()

    wp_usage_rows = []
    for day in range(1,days+1):
        row_date = datetime.date(report_date.year,report_date.month, day)
        if is_patient_out_of_date_range(patient, row_date):
            continue
        
        row = []
        row.append(row_date)
        msg_count = patient.wisepill_messages.filter(timestamp__year=row_date.year,timestamp__month=row_date.month,timestamp__day=row_date.day).count()
        row.append(msg_count)
        wp_usage_rows.append(row)

    pill_count_data = {}
    pills_missed_data = {}
    pill_count_data["patient_id"] = patient.subject_number
    pills_missed = patient.pillsmissed_set.filter(date__range=(datetime_start_month,datetime_end_month)).order_by('-date')[:4]
    weeks = []
    for pm in pills_missed:
        week_start = pm.date-datetime.timedelta(days=7)
        week_end = pm.date
        num_missed = pm.num_missed
        weeks.append({
            'pills_missed': num_missed,
            'week_start': week_start,
            'week_end': week_end,
            'received_on': pm.date
        })

    pills_missed_data[patient] = weeks

    pm_weekly_aggregate = []
    num_weeks_in_report_month = num_days_in_report_month / 7
    for week in range(0,num_weeks_in_report_month + 1):
        week_start = (datetime.date(report_date.year,report_date.month,1) + datetime.timedelta(days=week*7))
        week_end = week_start + datetime.timedelta(days=7)
        pm_week_data = {}
        if is_patient_out_of_date_range(patient,week_start,week_end):
            continue

        pills_missed_set = patient.pillsmissed_set.filter(date__gt=week_start, date__lt=week_end, source=1) # source = 1 means SMS
        if len(pills_missed_set) > 0:
            pills_missed_week = pills_missed_set.aggregate(Sum('num_missed'))["num_missed__sum"]
        else:
            pills_missed_week = "No Response/No Query"


        pm_week_data["sum"] = pills_missed_week
        pm_week_data["week_start"] = week_start
        pm_week_data["week_end"] = week_end
        pm_weekly_aggregate.append(pm_week_data)



    patient_connections = patient.contact.connection_set.all()
    messages = Message.objects.filter(connection__in=patient_connections)

    messages = messages.exclude(text__contains='start tree').exclude(text__contains='TimeOut') #exclude internal messages
    messages = messages.filter(date__range=(datetime_start_month, datetime_end_month)).order_by('-date') #stick to the report month

    reminders = Reminder.objects.all()

    context["pat_messages"] = messages
    context["wp_usage_rows"] = wp_usage_rows
    context["pm_weeks"] = pills_missed_data
    context["pm_weekly"] = pm_weekly_aggregate
    return context