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 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)
Example #4
0
    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
Example #5
0
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
Example #6
0
 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
Example #8
0
    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))
Example #9
0
 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])
Example #10
0
    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])
Example #11
0
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