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
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
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
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
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
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
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