def test_user_to_server(self): cases = [ ('2015-03-20T08:00:00', pytz.FixedOffset(-4 * 60), '2015-03-20T12:00:00'), ('2015-03-20T20:30:00', pytz.FixedOffset(-4 * 60), '2015-03-21T00:30:00'), ] for in_, tz, out in cases: user_dt = dateutil.parser.parse(in_) server_dt = UserTime(user_dt, tz).server_time().done() self.assertEqual(server_dt.isoformat(), out)
def get_start_and_end_timestamps(self, start_date, end_date): start_timestamp = UserTime(datetime.combine(start_date, time( 0, 0)), self.timezone).server_time().done().replace(tzinfo=None) end_timestamp = UserTime(datetime.combine(end_date, time( 0, 0)), self.timezone).server_time().done().replace(tzinfo=None) # end_date is inclusive end_timestamp += timedelta(days=1) return start_timestamp, end_timestamp
def additional_deactivation_condition_reached(self): from corehq.apps.data_interfaces.models import _try_date_conversion if self.memoized_schedule.stop_date_case_property_name and self.case: values = self.case.resolve_case_property(self.memoized_schedule.stop_date_case_property_name) values = [element.value for element in values] timezone = pytz.UTC if self.memoized_schedule.use_utc_as_default_timezone else self.domain_timezone for stop_date in values: if isinstance(stop_date, datetime): pass elif isinstance(stop_date, date): stop_date = datetime.combine(stop_date, time(0, 0)) else: stop_date = _try_date_conversion(stop_date) if not isinstance(stop_date, datetime): continue if stop_date.tzinfo: stop_date = stop_date.astimezone(pytz.UTC).replace(tzinfo=None) else: stop_date = UserTime(stop_date, timezone).server_time().done() if self.next_event_due >= stop_date: return True return False
def should_sync(domain, last_sync, utcnow=None): # definitely sync if we haven't synced before if not last_sync or not last_sync.date: return True # utcnow only used in tests to mock other times utcnow = utcnow or datetime.utcnow() try: timezone = domain.get_default_timezone() except pytz.UnknownTimeZoneError: timezone = utc _assert = soft_assert(to=['droberts' + '@' + 'dimagi.com']) last_sync_utc = last_sync.date if not _assert(last_sync_utc.tzinfo is None, 'last_sync.date should be an offset-naive dt'): last_sync_utc = UserTime(last_sync_utc).server_time().done() # check if user has already synced today (in local timezone). # Indicators only change daily. last_sync_local = ServerTime(last_sync_utc).user_time(timezone).done() current_date_local = ServerTime(utcnow).user_time(timezone).done() if current_date_local.date() != last_sync_local.date(): return True return False
def raw_value(self, **kwargs): user_id = kwargs.get('user_id') datespan_keys = None if self.inactivity_milestone > 0: # inactivity milestone takes precedence over any ignore_datespan configurations milestone_days_ago = UserTime( self.report_datespan.enddate, self.report_datespan.timezone ).server_time().done() - datetime.timedelta(days=self.inactivity_milestone) # in refactoring tz stuff, # milestone_days_ago is now tz naive, so isoformat() # no longer has +00:00 at the end. I think that's fine. datespan_keys = [[], [milestone_days_ago.isoformat()]] elif not self.ignore_datespan: datespan_keys = [[self.report_datespan.startdate_param_utc], [self.report_datespan.enddate_param_utc]] status = self.case_status if self.case_status else None cases = self.get_filtered_cases(self.report_domain, user_id, status=status, datespan_keys=datespan_keys) return len(cases) if isinstance(cases, list) else None
def get_start_and_end_timestamps(self, for_date): timezone = pytz.timezone('Asia/Kolkata') start_timestamp = UserTime(datetime.combine(for_date, time( 0, 0)), timezone).server_time().done().replace(tzinfo=None) end_timestamp = start_timestamp + timedelta(days=1) return start_timestamp, end_timestamp
def set_next_event_due_timestamp(self, instance): if self.is_monthly: user_timestamp = self.get_local_next_event_due_timestamp_for_monthly_schedule( instance) else: user_timestamp = self.get_local_next_event_due_timestamp(instance) instance.next_event_due = (UserTime( user_timestamp, instance.timezone).server_time().done().replace(tzinfo=None))
def midnights(self): """Returns a list containing a datetime for midnight in the domains timezone on either side of the current date. """ tz = pytz.timezone(self.default_timezone) now = datetime.utcnow() midnight_utc = now.replace(hour=0, minute=0, second=0, microsecond=0) midnight_tz1 = UserTime(midnight_utc, tz).server_time().done() midnight_tz2 = midnight_tz1 + timedelta( days=(1 if midnight_tz1 < now else -1)) return sorted([midnight_tz1, midnight_tz2])
def midnights(self, utcnow=None): """Returns a list containing two datetimes in UTC that corresponds to midnight in the domains timezone on either side of the current UTC datetime. i.e. [<previous midnight in TZ>, <next midnight in TZ>] >>> d = DomainLite('', 'Asia/Kolkata', '', True) >>> d.midnights(datetime(2015, 8, 27, 18, 30, 0 )) [datetime.datetime(2015, 8, 26, 18, 30), datetime.datetime(2015, 8, 27, 18, 30)] >>> d.midnights(datetime(2015, 8, 27, 18, 31, 0 )) [datetime.datetime(2015, 8, 27, 18, 30), datetime.datetime(2015, 8, 28, 18, 30)] """ utcnow = utcnow or datetime.utcnow() tz = pytz.timezone(self.default_timezone) current_time_tz = ServerTime(utcnow).user_time(tz).done() midnight_tz1 = current_time_tz.replace(hour=0, minute=0, second=0, microsecond=0) midnight_tz_utc1 = UserTime(midnight_tz1).server_time().done() midnight_tz_utc2 = midnight_tz_utc1 + timedelta(days=(1 if midnight_tz_utc1 < utcnow else -1)) return sorted([midnight_tz_utc1, midnight_tz_utc2])
class SurveyResponsesReport(FRIReport): name = ugettext_noop("Survey Responses") slug = "fri_survey_responses" description = ugettext_noop( "Shows information pertaining to survey responses.") emailable = False fields = [ "custom.fri.reports.filters.SurveyDateSelector", ] @property def survey_report_date(self): return SurveyDateSelector.get_value(self.request, self.domain) @property def headers(self): cols = [ DataTablesColumn(_("PID")), DataTablesColumn(_("Name")), DataTablesColumn(_("Arm")), DataTablesColumn(_("Week 1")), DataTablesColumn(_("Week 2")), DataTablesColumn(_("Week 3")), DataTablesColumn(_("Week 4")), DataTablesColumn(_("Week 5")), DataTablesColumn(_("Week 6")), DataTablesColumn(_("Week 7")), DataTablesColumn(_("Week 8")), ] header = DataTablesHeader(*cols) header.custom_sort = [[0, "asc"]] return header @property def rows(self): participants = self.get_participants() result = [] for case in participants: pid = case.get_case_property("pid") study_arm = case.get_case_property("study_arm") registration_date = get_date(case, "start_date") first_name = case.get_case_property("first_name") or "" if registration_date is None: continue first_survey_date = self.get_first_tuesday(registration_date) row = [ self._fmt(pid), self._fmt(first_name), self._fmt(study_arm), ] for i in range(8): next_survey_date = first_survey_date + timedelta(days=7 * i) response = self.get_first_survey_response( case, next_survey_date) if response == RESPONSE_NOT_APPLICABLE: row.append(self._fmt("-")) elif response == NO_RESPONSE: row.append(self._fmt(_("No Response"))) else: response_timestamp = ServerTime(response.date).user_time( self.timezone).done() row.append(self._fmt_timestamp(response_timestamp)) result.append(row) return result def get_first_tuesday(self, dt): while dt.weekday() != 1: dt = dt + timedelta(days=1) return dt def get_participants(self): result = get_cases_in_domain(self.domain, 'participant') survey_report_date = parse(self.survey_report_date).date() def filter_function(case): registration_date = get_date(case, "start_date") if registration_date is None: return False first_tuesday = self.get_first_tuesday(registration_date) last_tuesday = first_tuesday + timedelta(days=49) return first_tuesday <= survey_report_date <= last_tuesday result = filter(filter_function, result) return result def get_first_survey_response(self, case, dt): timestamp_start = datetime.combine(dt, time(20, 45)) timestamp_start = UserTime(timestamp_start, self.timezone).server_time().done() timestamp_end = datetime.combine(dt + timedelta(days=1), time(11, 45)) timestamp_end = UserTime(timestamp_end, self.timezone).server_time().done() if timestamp_end > datetime.utcnow(): return RESPONSE_NOT_APPLICABLE survey_responses = SMS.by_recipient( 'CommCareCase', case.get_id).filter(direction=INCOMING, xforms_session_couch_id__isnull=False, date__gte=timestamp_start, date__lte=timestamp_end).order_by('date')[:1] if survey_responses: return survey_responses[0] return NO_RESPONSE