def test_end_before_start(self): startdate = datetime(2015, 02, 01) enddate = datetime(2015, 01, 01) datespan = DateSpan(startdate, enddate) self.assertFalse(datespan.is_valid()) self.assertEqual(datespan.get_validation_reason(), "You can't have an end date of %s after start date of %s" % (enddate, startdate))
def datespan_from_beginning(domain_object, timezone): if use_new_exports(domain_object.name): startdate = domain_object.date_created else: startdate = get_first_form_submission_received(domain_object.name) now = datetime.utcnow() datespan = DateSpan(startdate, now, timezone=timezone) datespan.is_default = True return datespan
def test_since(self): enddate = datetime(2013, 7, 21, 12, 30, 45) datespan_inclusive = DateSpan.since(7, enddate) self.assertEqual(datespan_inclusive.enddate, datetime(2013, 7, 21, 0, 0, 0)) self.assertEqual(datespan_inclusive.startdate, datetime(2013, 7, 15, 0, 0, 0)) datespan_non_inclusive = DateSpan.since(7, enddate, inclusive=False) self.assertEqual(datespan_non_inclusive.enddate, datetime(2013, 7, 21, 0, 0, 0)) self.assertEqual(datespan_non_inclusive.startdate, datetime(2013, 7, 14, 0, 0, 0))
def test_adjustment(self): end = datetime(2014, 3, 7, 2, tzinfo=pytz.utc) start = end = datetime(2014, 2, 7, 2, tzinfo=pytz.utc) ds = DateSpan(start, end) pst = pytz.timezone('US/Pacific') ds.set_timezone(pst) self.assertEqual(ds.enddate - end, timedelta(hours=8)) self.assertEqual(ds.startdate - start, timedelta(hours=8)) self.assertEqual(ds.timezone, pst)
def datespan_from_beginning(domain_object, timezone): from corehq import toggles if toggles.NEW_EXPORTS.enabled(domain_object.name): startdate = domain_object.date_created else: startdate = get_first_form_submission_received(domain_object.name) now = datetime.utcnow() datespan = DateSpan(startdate, now, timezone=timezone) datespan.is_default = True return datespan
def update_context(self): self.context["datespan_name"] = self.name range = self.request.GET.get('range', None) if range: dates = str(range).split(_(' to ')) self.request.datespan.startdate = datetime.datetime.combine( iso_string_to_date(dates[0]), datetime.time()) self.request.datespan.enddate = datetime.datetime.combine( iso_string_to_date(dates[1]), datetime.time()) self.datespan = DateSpan.since(self.default_days, timezone=self.timezone, inclusive=self.inclusive) if self.request.datespan.is_valid(): self.datespan.startdate = self.request.datespan.startdate self.datespan.enddate = self.request.datespan.enddate self.context['timezone'] = self.timezone.zone self.context['datespan'] = self.datespan report_labels = json.dumps({ 'year_to_date': _('Year to Date'), 'last_month': _('Last Month'), 'last_quarter': _('Last Quarter'), 'last_two_quarters': _('Last Two Quarters'), 'last_three_quarters': _('Last Three Quarters'), 'last_year': _('Last Year'), 'last_two_years': _('Last Two Years'), 'last_three_years': _('Last Three Years'), 'last_four_years': _('Last Four Years') }) self.context['report_labels'] = report_labels self.context['separator'] = _(' to ')
def datespan(self): if self._datespan is None: datespan = DateSpan.from_month(self.month, self.year) self.request.datespan = datespan self.context.update(dict(datespan=datespan)) self._datespan = datespan return self._datespan
def datespan(self): now = datetime.datetime.utcnow() year, month = add_months(now.year, now.month, -1) last_month = DateSpan.from_month(month, year) self.request.datespan = last_month self.context.update(dict(datespan=last_month)) return last_month
def datespan(self): datespan = DateSpan.since(self.default_days, enddate=datetime.date.today(), timezone=self.timezone) if self.get_start_date(self.request) is not None: datespan.startdate = self.get_start_date(self.request) if self.get_end_date(self.request) is not None: datespan.enddate = self.get_end_date(self.request) return datespan
def wrapped_func(*args, **kwargs): # attempt to find the request object from all the argument # values, checking first the args and then the kwargs req = None for arg in args: if _is_http_request(arg): req = arg break if not req: for arg in kwargs.values(): if _is_http_request(arg): req = arg break if req: dict = req.POST if req.method == "POST" else req.GET def date_or_nothing(param): return datetime.strptime(dict[param], format_string)\ if param in dict and dict[param] else None try: startdate = date_or_nothing(from_param) enddate = date_or_nothing(to_param) except ValueError, e: return HttpResponseBadRequest(unicode(e)) if startdate or enddate: req.datespan = DateSpan(startdate, enddate, format_string) else: # default to the last N days req.datespan = DateSpan.since(default_days, format=format_string, inclusive=inclusive) req.datespan.is_default = True
def order_fill_stats(locations, type=None, datespan=None): """ With a list of locations - display reporting rates associated with those locations. This method only looks at closed orders """ if locations: if datespan == None: # default to last 30 days datespan = DateSpan.since(30) base_points = SupplyPoint.objects.filter(location__in=locations, active=True) if type is not None: base_points = base_points.filter(type__code=type) if base_points.count() > 0: base_reqs = StockRequest.objects.filter( supply_point__in=base_points, requested_on__gte=datespan.startdate, requested_on__lte=datespan.enddate ) rec_reqs = base_reqs.filter(status=StockRequestStatus.RECEIVED) totals = base_reqs.values("product").annotate(total=Count("pk")) rec_totals = rec_reqs.values("product").annotate(total=Count("pk")) eo_totals = base_reqs.filter(is_emergency=True).values("product").annotate(total=Count("pk")) stocked_out = rec_reqs.filter(amount_received=0).values("product").annotate(total=Count("pk")) not_stocked_out = rec_reqs.filter(amount_received__gt=0).exclude( response_status=StockRequestStatus.STOCKED_OUT ) under_supplied = ( not_stocked_out.filter(amount_requested__gt=F("amount_received")) .values("product") .annotate(total=Count("pk")) ) well_supplied = ( not_stocked_out.filter(amount_requested=F("amount_received")) .values("product") .annotate(total=Count("pk")) ) over_supplied = ( not_stocked_out.filter(amount_requested__lt=F("amount_received")) .values("product") .annotate(total=Count("pk")) ) main_data = {} for row in totals: main_data[row["product"]] = defaultdict(lambda x: 0) main_data[row["product"]]["product"] = Product.objects.get(pk=row["product"]) main_data[row["product"]]["total"] = row["total"] def _update_main_data(main, to_update, tag): for row in to_update: main[row["product"]][tag] = row["total"] _update_main_data(main_data, rec_totals, "filled") _update_main_data(main_data, eo_totals, "emergency") _update_main_data(main_data, stocked_out, "stocked_out") _update_main_data(main_data, under_supplied, "under_supplied") _update_main_data(main_data, well_supplied, "well_supplied") _update_main_data(main_data, over_supplied, "over_supplied") return r_2_s_helper("logistics/partials/order_fill_stats.html", {"data": main_data, "datespan": datespan}) return "" # no data, no report
def update_context(self): self.context["datespan_name"] = self.name self.datespan = DateSpan.since(7, format="%Y-%m-%d", timezone=self.timezone) if self.request.datespan.is_valid(): self.datespan.startdate = self.request.datespan.startdate self.datespan.enddate = self.request.datespan.enddate self.context['timezone'] = self.timezone.zone self.context['datespan'] = self.datespan
def __init__(self, filter, value): assert filter.type == 'date' # todo: might want some better way to set defaults if value is None: # default to one week value = DateSpan.since(7) assert isinstance(value, DateSpan) super(DateFilterValue, self).__init__(filter, value)
def update_context(self): self.context["datespan_name"] = self.name self.datespan = DateSpan.since(self.default_days, timezone=self.timezone, inclusive=self.inclusive) if self.request.datespan.is_valid(): self.datespan.startdate = self.request.datespan.startdate self.datespan.enddate = self.request.datespan.enddate self.context['timezone'] = self.timezone.zone self.context['datespan'] = self.datespan
def stockonhand_table(supply_point, datespan=None): if datespan is None: datespan = DateSpan.since(settings.LOGISTICS_REPORTING_CYCLE_IN_DAYS) sohs = supply_point.stocked_productstocks().order_by("product__name") # update the stock quantities to match whatever reporting period has been specified for soh in sohs: soh.quantity = supply_point.historical_stock_by_date(soh.product, datespan.end_of_end_day) return r_2_s_helper("logistics/partials/stockonhand_table_full.html", {"stockonhands": sohs, "datespan": datespan})
def handle(self, month_years, **options): datespan_list = [] for arg in month_years: month_year = dateutil.parser.parse(arg) datespan_list.append(DateSpan.from_month(month_year.month, month_year.year)) generator = MALTTableGenerator(datespan_list) print("Building Malt table... for time range {}".format(datespan_list)) generator.build_table() print("Finished!")
def default_datespan(self): # DateSpan.since() will make enddate default to yesterday when it's None enddate = None if self.default_datespan_end_date_to_today: enddate = ServerTime(datetime.utcnow()).user_time(self.timezone).done().date() datespan = DateSpan.since(self.datespan_default_days, enddate=enddate, inclusive=self.inclusive, timezone=self.timezone) datespan.max_days = self.datespan_max_days datespan.is_default = True return datespan
def test_basic_submission_by_date(self): start = datetime(2013, 7, 1) end = datetime(2013, 7, 30) received_on = datetime(2013, 7, 15) self._send_form_to_es(received_on=received_on) self._send_form_to_es(received_on=received_on, xmlns=SYSTEM_FORM_XMLNS) results = get_submission_counts_by_date(self.domain, ['cruella_deville'], DateSpan(start, end), pytz.utc) self.assertEquals(results['2013-07-15'], 1)
def test_submission_different_domain_by_user(self): start = datetime(2013, 7, 1) end = datetime(2013, 7, 30) received_on = datetime(2013, 7, 15) self._send_form_to_es(received_on=received_on) self._send_form_to_es(received_on=received_on, domain='not-in-my-backyard') results = get_submission_counts_by_user(self.domain, DateSpan(start, end)) self.assertEquals(results['cruella_deville'], 1)
def get_month_datespan(self, start, end=None): """ start and end are (year, month) tuples """ if end is None: end=start return DateSpan( self.get_first_day_of_month(start[0], start[1]), self.get_last_day_of_month(end[0], end[1]), format="%b %Y", inclusive=False )
def stockonhand_table(supply_point, datespan=None): if datespan is None: datespan = DateSpan.since(settings.LOGISTICS_REPORTING_CYCLE_IN_DAYS) sohs = supply_point.stocked_productstocks().order_by('product__name') # update the stock quantities to match whatever reporting period has been specified for soh in sohs: soh.quantity = supply_point.historical_stock_by_date( soh.product, datespan.end_of_end_day) return r_2_s_helper("logistics/partials/stockonhand_table_full.html", { "stockonhands": sohs, "datespan": datespan })
def get_previous_week(send_date: date) -> DateSpan: """ Returns a DateSpan from last week Monday to last week Sunday ISO 8601 has Monday as Day 1 and Sunday as Day 7 """ # monday.weekday() == 0, so subtracting send_date.weekday() from # send_date will always give you the Monday at the start of the week monday = send_date - timedelta(days=send_date.weekday()) startdate = monday - timedelta(days=7) enddate = monday - timedelta(days=1) return DateSpan(startdate, enddate)
def _computed_dates(self, actual_startdate, actual_enddate): filter = ReportFilter(compare_as_string=False, field=u'submission_date', slug=u'submitted_on', type=u'date', required=False) value = DateSpan(actual_startdate, actual_enddate) filter_value = DateFilterValue(filter, value) computed_values = filter_value.to_sql_values() startdate = computed_values['%s_startdate' % filter.slug] enddate = computed_values['%s_enddate' % filter.slug] return startdate, enddate
def test_multiple_months(self): self._save_form_data(self.app_id, datetime.datetime(2019, 12, 15)) self._save_form_data(self.app_id, datetime.datetime(2020, 1, 15)) self._save_form_data(self.app_id, datetime.datetime(2020, 1, 16)) self.es.indices.refresh(XFORM_INDEX_INFO.index) monthspans = [ DateSpan.from_month(12, 2019), DateSpan.from_month(1, 2020) ] generate_malt(monthspans, domains=[self.domain.name]) december_malt = MALTRow.objects.get(domain_name=self.domain, month=DateSpan.from_month( 12, 2019).startdate) january_malt = MALTRow.objects.get(domain_name=self.domain, month=DateSpan.from_month( 1, 2020).startdate) self.assertEqual(december_malt.num_of_forms, 1) self.assertEqual(january_malt.num_of_forms, 2)
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 datespan_from_beginning(domain, default_days, timezone): now = datetime.utcnow() def extract_date(x): try: def clip_timezone(datestring): return datestring[:len('yyyy-mm-ddThh:mm:ss')] return string_to_datetime(clip_timezone(x['key'][2])) except Exception: logging.error("Tried to get a date from this, but it didn't work: %r" % x) return None key = make_form_couch_key(domain) startdate = get_db().view('reports_forms/all_forms', startkey=key, endkey=key+[{}], limit=1, descending=False, reduce=False, wrapper=extract_date, ).one() #or now - timedelta(days=default_days - 1) datespan = DateSpan(startdate, now, timezone=timezone) datespan.is_default = True return datespan
def datespan_export_filter(doc, datespan): if isinstance(datespan, dict): datespan = DateSpan(**datespan) try: received_on = doc['received_on'] except Exception: if settings.DEBUG: raise return False if datespan.startdate_param <= received_on < datespan.enddate_param: return True return False
def datespan_export_filter(doc, datespan): if isinstance(datespan, dict): datespan = DateSpan(**datespan) try: received_on = iso_string_to_datetime(doc['received_on']).replace(tzinfo=pytz.utc) except Exception: if settings.DEBUG: raise return False if datespan.startdate <= received_on < (datespan.enddate + timedelta(days=1)): return True return False
def test_get_case_counts_closed_by_user(self): datespan = DateSpan(datetime(2013, 7, 1), datetime(2013, 7, 30)) opened_on = datetime(2013, 7, 15) self._send_case_to_es(opened_on=opened_on) results = get_case_counts_closed_by_user(self.domain, datespan) self.assertEqual(results, {}) self._send_case_to_es(opened_on=opened_on, closed_on=opened_on) results = get_case_counts_closed_by_user(self.domain, datespan) self.assertEqual(results[self.user_id], 1)
def test_get_total_case_counts_closed(self): """Test a case closure before the startdate""" datespan = DateSpan(datetime(2013, 7, 1), datetime(2013, 7, 30)) opened_on = datetime(2013, 7, 15) opened_on_early = datetime(2013, 6, 14) closed_on = datetime(2013, 6, 15) self._send_case_to_es(opened_on=opened_on) self._send_case_to_es(opened_on=opened_on_early, closed_on=closed_on) results = get_total_case_counts_by_owner(self.domain, datespan) self.assertEqual(results[self.owner_id], 1)
def sms_billables(self): datespan = DateSpan(DateSentFilter.get_start_date(self.request), DateSentFilter.get_end_date(self.request)) selected_billables = SmsBillable.get_billables_sent_between(datespan) if DateCreatedFilter.use_filter(self.request): date_span = DateSpan( DateCreatedFilter.get_start_date(self.request), DateCreatedFilter.get_end_date(self.request)) selected_billables = SmsBillable.filter_selected_billables_by_date( selected_billables, date_span) show_billables = ShowBillablesFilter.get_value(self.request, self.domain) if show_billables: selected_billables = SmsBillable.filter_selected_billables_show_billables( selected_billables, show_billables, ) account_name = NameFilter.get_value(self.request, self.domain) if account_name: selected_billables = SmsBillable.filter_selected_billables_by_account( selected_billables, account_name) domain = DomainFilter.get_value(self.request, self.domain) if domain: selected_billables = selected_billables.filter(domain=domain, ) has_gateway_fee = HasGatewayFeeFilter.get_value( self.request, self.domain) if has_gateway_fee: if has_gateway_fee == HasGatewayFeeFilter.YES: selected_billables = selected_billables.exclude( gateway_fee=None) else: selected_billables = selected_billables.filter( gateway_fee=None) gateway_type = GatewayTypeFilter.get_value(self.request, self.domain) if gateway_type: selected_billables = selected_billables.filter( gateway_fee__criteria__backend_api_id=gateway_type, ) return selected_billables
def default_datespan(self): # DateSpan.since() will make enddate default to yesterday when it's None enddate = None if self.default_datespan_end_date_to_today: enddate = ServerTime(datetime.utcnow()).user_time( self.timezone).done().date() datespan = DateSpan.since(self.datespan_default_days, enddate=enddate, inclusive=self.inclusive, timezone=self.timezone) datespan.max_days = self.datespan_max_days datespan.is_default = True return datespan
def _computed_dates(self, actual_startdate, actual_enddate): filter = { 'compare_as_string': False, 'field': 'submission_date', 'slug': 'submitted_on', 'type': 'date', 'required': False } value = DateSpan(actual_startdate, actual_enddate) filter_value = DateFilterValue(filter, value) computed_values = filter_value.to_sql_values() startdate = computed_values['%s_startdate' % filter['slug']] enddate = computed_values['%s_enddate' % filter['slug']] return startdate, enddate
def hits(self, domain_name): time_filter = form_es.submitted datespan = DateSpan(datetime.now() - timedelta(days=self.window), datetime.utcnow()) users_filter = form_es.user_id( EMWF.user_es_query( domain_name, ['t__0'], # All mobile workers self.couch_user).values_list('_id', flat=True)) query = (form_es.FormES().domain(domain_name).filter( time_filter(gte=datespan.startdate, lt=datespan.enddate_adjusted)).filter(users_filter)) return query.run().hits
def setUp(self): super().setUp() self.domain = 'domain' self.monthspan = DateSpan.from_month(1, 2022) self.run_date = self.monthspan.computed_enddate self.app_row = create_mock_nested_query_row() self.user = create_user_for_malt_tests(is_web_user=True) self.app_data = create_malt_app_data() app_data_patcher = patch( 'corehq.apps.data_analytics.malt_generator._get_malt_app_data') self.mock_get_malt_app_data = app_data_patcher.start() self.mock_get_malt_app_data.return_value = self.app_data self.addCleanup(app_data_patcher.stop)
def sms_billables(self): datespan = DateSpan(DateSentFilter.get_start_date(self.request), DateSentFilter.get_end_date(self.request)) selected_billables = SmsBillable.objects.filter( date_sent__gte=datespan.startdate, date_sent__lt=datespan.enddate_adjusted, ) if DateCreatedFilter.use_filter(self.request): date_span = DateSpan( DateCreatedFilter.get_start_date(self.request), DateCreatedFilter.get_end_date(self.request)) selected_billables = selected_billables.filter( date_created__gte=date_span.startdate, date_created__lt=date_span.enddate_adjusted, ) show_billables = ShowBillablesFilter.get_value(self.request, self.domain) if show_billables: selected_billables = selected_billables.filter( is_valid=(show_billables == ShowBillablesFilter.VALID), ) domain = DomainFilter.get_value(self.request, self.domain) if domain: selected_billables = selected_billables.filter(domain=domain, ) has_gateway_fee = HasGatewayFeeFilter.get_value( self.request, self.domain) if has_gateway_fee: if has_gateway_fee == HasGatewayFeeFilter.YES: selected_billables = selected_billables.exclude( gateway_fee=None) else: selected_billables = selected_billables.filter( gateway_fee=None) gateway_type = GatewayTypeFilter.get_value(self.request, self.domain) if gateway_type: selected_billables = selected_billables.filter( gateway_fee__criteria__backend_api_id=gateway_type, ) return selected_billables
def datespan_in_request(from_param="from", to_param="to", format_string=ISO_DATE_FORMAT, default_days=30, inclusive=True, default_function=None): """ Wraps a request with dates based on url params or defaults and Checks date validity. """ # you can pass in a function to say what the default should be, # if you don't it will pull the value from the last default_days # in. If you override default_function, default_days is ignored. if default_function is None: default_function = lambda: DateSpan.since(default_days, format=format_string, inclusive=inclusive) # this is loosely modeled after example number 4 of decorator # usage here: http://www.python.org/dev/peps/pep-0318/ def get_dates(f): def wrapped_func(*args, **kwargs): # attempt to find the request object from all the argument # values, checking first the args and then the kwargs req = request_from_args_or_kwargs(*args, **kwargs) if req: req_dict = req.POST if req.method == "POST" else req.GET def date_or_nothing(param): date = req_dict.get(param, None) return datetime.strptime(date, format_string) if date else None try: startdate = date_or_nothing(from_param) enddate = date_or_nothing(to_param) except ValueError as e: return HttpResponseBadRequest(unicode(e)) if startdate or enddate: req.datespan = DateSpan(startdate, enddate, format_string) else: req.datespan = default_function() req.datespan.is_default = True return f(*args, **kwargs) if hasattr(f, "func_name"): wrapped_func.func_name = f.func_name # preserve doc strings wrapped_func.__doc__ = f.__doc__ return wrapped_func else: # this means it wasn't actually a view. return f return get_dates
def value(self, **kwargs): selected_year = kwargs[self.year_param_name] if selected_year == SHOW_ALL_CHOICE: # no filter translates to not filtering the dates at all return DateSpan.max() try: year = int(kwargs[self.year_param_name]) quarter = int(kwargs[self.quarter_param_name]) except ValueError: raise FilterValueException() if not (1 <= quarter <= 4): raise FilterValueException() return self.get_quarter(year, quarter)
def test_app_submission_breakdown(self, combination_count_list): """ The breakdown of this report is (app, device, userid, username): count """ domain = 'test-data-analytics' received = datetime(2016, 3, 24) month = DateSpan.from_month(3, 2016) for app, device, userid, username, count in combination_count_list: for i in range(count): save_to_es_analytics_db(domain, received, app, device, userid, username) self.es.indices.refresh(XFORM_INDEX_INFO.index) data_back = get_app_submission_breakdown_es(domain, month) normalized_data_back = set(data_back) self.assertEqual(set(combination_count_list), normalized_data_back)
def test_export_response_returns_200(self): request = self.request_factory.post('/some/url') request.couch_user = self.couch_user request.domain = self.domain request.datespan = DateSpan( startdate=datetime.utcnow() - timedelta(days=30), enddate=datetime.utcnow(), ) request.can_access_all_locations = True report = WorkerActivityReport(request, domain=self.domain) report.rendered_as = 'export' res = report.export_response self.assertEqual(res.status_code, 200)
def test_consommation_data_report(self): mock = MagicMock() mock.couch_user = self.user mock.GET = { 'startdate': '2016-05-28', 'enddate': '2018-06-04', 'location_id': '', } mock.datespan = DateSpan(datetime.datetime(2016, 5, 28), datetime.datetime(2018, 6, 4)) tableu_de_board_report2_report = TableuDeBoardReport2( request=mock, domain='test-pna') consommation_data_report = tableu_de_board_report2_report.report_context[ 'reports'][3]['report_table'] headers = consommation_data_report['headers'].as_export_table[0] rows = consommation_data_report['rows'] self.assertEqual(headers, [ 'PPS', 'ACT Adulte', 'ACT Grand Enfant', 'ACT Nourisson', 'ACT Petit Enfant', 'Amoxicilline 250mg SP', 'Ampiciline 1G Amp', 'CU', u'Calcium 100mg', 'Cefixime 100MG/5ML SUSP.BUV', 'Ceftriaxone 1G', 'Collier', 'DIU', u'Depo-Provera', 'Dexamethasone 4mg', 'Diazepam 10MG/2ML AMP. INJ.', 'Epinephrine 1MG/1ML AMP. INJ.', 'Fer 0.68% SP', 'Gentamicin INJ 80mg/2ml', 'Hydrocortisone 100MG AMP. INJ.', 'IMPLANON', 'Jadelle', 'Kit de depistage Rapide du VIH B/30', 'Mebendazole 100MG SP', 'Mebendazole 500MG CP.', 'Microgynon/Lof.', 'Microlut/Ovrette', 'Oxytocine 5 UI', 'Paracetamol 120MG/5ML SP', 'Paracetamol 1G/100ML INJ.', 'Phytomenadione 10mg', 'Preservatif Feminin', 'Preservatif Masculin', 'Recto caps 200 mg', 'Recto caps 50 mg', 'S.R.O. Faible osmolarite', 'Sayana Press', 'Sulfate de Magnesium 20 ml', 'Test depistage rapide Palu', u'Zinc 20mg' ]) self.assertEqual( sorted(rows, key=lambda x: x[0]), sorted([[ 'GATE', 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0 ], [ None, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 ]], key=lambda x: x[0]))
def test_timezones_ahead_utc_in_get_submission_counts_by_date(self): """ When bucketing form submissions, the returned bucket key needs to be converted to a datetime with the timezone specified. Specifically an issue for timezones ahead of UTC (positive offsets) """ start = datetime(2013, 7, 1) end = datetime(2013, 7, 30) received_on = datetime(2013, 7, 15) self._send_form_to_es(received_on=received_on) self._send_form_to_es(received_on=received_on, xmlns=SYSTEM_FORM_XMLNS) results = get_submission_counts_by_date( self.domain, ['cruella_deville'], DateSpan(start, end), pytz.timezone('Africa/Johannesburg')) self.assertEqual(results['2013-07-15'], 1)
def test_timezone_differences(self): """ Our received_on dates are always in UTC, so if we submit a form right at midnight UTC, then the report should show that form being submitted the day before if viewing from an earlier timezone like New York """ start = datetime(2013, 7, 1) end = datetime(2013, 7, 30) received_on = datetime(2013, 7, 15, 0, 0, 0) timezone = pytz.timezone('America/New_York') self._send_form_to_es(received_on=received_on) results = get_submission_counts_by_date(self.domain, ['cruella_deville'], DateSpan(start, end), timezone) self.assertEqual(results['2013-07-14'], 1)
def test_dates_use_iso_formatting(self): spec = { 'slug': 'opened_on', 'type': 'date', 'compare_as_string': True, } start = datetime(year=2021, month=1, day=5) end = datetime(year=2021, month=1, day=5, hour=7) value = DateSpan(inclusive=False, startdate=start, enddate=end) filter_value = DateFilterValue(spec, value) sql_values = filter_value.to_sql_values() self.assertEqual(sql_values['opened_on_startdate'], '2021-01-05T00:00:00') self.assertEqual(sql_values['opened_on_enddate'], '2021-01-05T07:00:00')
def test_export_response_does_not_cache_tasks(self, task_mock): request = self.request_factory.post(f'/a/{self.domain}/report/url') request.couch_user = self.couch_user request.domain = self.domain request.datespan = DateSpan( startdate=datetime.utcnow() - timedelta(days=30), enddate=datetime.utcnow(), ) request.can_access_all_locations = True report = WorkerActivityReport(request, domain=self.domain) report.rendered_as = 'export' report.export_response report.export_response self.assertEqual(task_mock.call_count, 2)
def test_export_response_returns_200_with_file(self): request = self.request_factory.post('/some/url') request.couch_user = self.couch_user request.domain = self.domain request.datespan = DateSpan( startdate=datetime.utcnow() - timedelta(days=30), enddate=datetime.utcnow(), ) request.can_access_all_locations = True report = WorkerActivityReport(request, domain=self.domain) report.rendered_as = 'export' report.exportable_all = False res = report.export_response self.assertEqual(res.status_code, 200) self.assertEqual(res.headers['content-type'], 'application/vnd.ms-excel')
def get_data(self, slugs=None): startdate = self.config['startdate'] enddate = self.config['enddate'] datespan = DateSpan(startdate, enddate) location_id = self.config['location_id'] domain = self.config['domain'] report_data = {} for report in self.get_reports(): report_data[report.slug] = { 'name': report.name, 'data': report.get_report_data({ 'location_id': location_id, 'datespan': datespan, 'domain': domain }) } return report_data
def update_context(self): self.context["datespan_name"] = self.name range = self.request.GET.get('range', None) if range is not None: dates = str(range).split(_(' to ')) self.request.datespan.startdate = datetime.datetime.combine( iso_string_to_date(dates[0]), datetime.time()) self.request.datespan.enddate = datetime.datetime.combine( iso_string_to_date(dates[1]), datetime.time()) self.datespan = DateSpan.since(self.default_days, timezone=self.timezone, inclusive=self.inclusive) if self.request.datespan.is_valid(): self.datespan.startdate = self.request.datespan.startdate self.datespan.enddate = self.request.datespan.enddate self.context['timezone'] = self.timezone.zone self.context['datespan'] = self.datespan report_labels = json.dumps({ 'year_to_date': _('Year to Date'), 'last_month': _('Last Month'), 'last_quarter': _('Last Quarter'), 'last_two_quarters': _('Last Two Quarters'), 'last_three_quarters': _('Last Three Quarters'), 'last_year': _('Last Year'), 'last_two_years': _('Last Two Years'), 'last_three_years': _('Last Three Years'), 'last_four_years': _('Last Four Years') }) self.context['report_labels'] = report_labels self.context['separator'] = _(' to ')
def district_dashboard(request, template="logistics/district_dashboard.html"): districts = get_districts() if request.location is None: # pick a random location to start location_code = settings.COUNTRY request.location = get_object_or_404(Location, code=location_code) facilities = SupplyPoint.objects.all() #request.location = districts[0] else: facilities = request.location.all_child_facilities() report = ReportingBreakdown(facilities, DateSpan.since(settings.LOGISTICS_DAYS_UNTIL_LATE_PRODUCT_REPORT), days_for_late=settings.LOGISTICS_DAYS_UNTIL_LATE_PRODUCT_REPORT) return render_to_response(template, {"reporting_data": report, "graph_width": 200, "graph_height": 200, "districts": districts.order_by("code"), "location": request.location}, context_instance=RequestContext(request))
def get_data(domain, user=None, datespan=None): """ Returns a data structure like: { <Form display name>: { <date>: { count: <count>, max: <time in ms>, min: <time in ms>, sum: <time in ms> } } } """ if datespan is None: datespan = DateSpan.since(days=30, format="%Y-%m-%dT%H:%M:%S") all_data = defaultdict(lambda: defaultdict(lambda: 0)) startkey = ["udx", domain, user, datespan.startdate_param] if user \ else ["dx", domain, datespan.startdate_param] endkey = ["udx", domain, user, datespan.enddate_param] if user \ else ["dx", domain, datespan.enddate_param] view = get_db().view("formtrends/form_duration_by_user", startkey=startkey, endkey=endkey, group=True, reduce=True) for row in view: date = row["key"][-2] xmlns = row["key"][-1] form_name = xmlns_to_name(domain, xmlns, app_id=None) data = all_data[form_name] if not date in data: data[date] = defaultdict(lambda: 0) thisrow = row["value"] for key, val in thisrow.items(): data[date][key] = data[date][key] + thisrow[key] return all_data
def _last_month_datespan(): today = datetime.date.today() first_of_this_month = datetime.date(day=1, month=today.month, year=today.year) last_month = first_of_this_month - datetime.timedelta(days=1) return DateSpan.from_month(last_month.month, last_month.year)
def update_current_MALT(): today = datetime.date.today() this_month = DateSpan.from_month(today.month, today.year) MALTTableGenerator([this_month]).build_table()
def datespan_from_beginning(domain_object, timezone): startdate = domain_object.date_created now = datetime.utcnow() datespan = DateSpan(startdate, now, timezone=timezone) datespan.is_default = True return datespan
def datespan(self): datespan = DateSpan.since(self.default_days, timezone=self.timezone, inclusive=self.inclusive) if self.request.datespan.is_valid() and self.slug == "datespan": datespan.startdate = self.request.datespan.startdate datespan.enddate = self.request.datespan.enddate return datespan
def default_datespan(self): datespan = DateSpan.since(self.datespan_default_days, timezone=self.timezone, inclusive=self.inclusive) datespan.is_default = True return datespan
def datespan(self): return DateSpan.from_month(month, year)
def datespan_from_beginning(domain, timezone): now = datetime.utcnow() startdate = get_first_form_submission_received(domain) datespan = DateSpan(startdate, now, timezone=timezone) datespan.is_default = True return datespan