def phonecall_workflow_postponed(request): pcall = _get_pcall(request) if pcall is not None: # NB: we avoid a double save here (clone() + save()) # by modifying our live copy before cloning postponed = deepcopy(pcall) # NB: deepcopy to copy cache too (_state) _set_pcall_as_failed(pcall, request) else: pcall, me, person = _create_failed_pcall(request) postponed = deepcopy(pcall) # NB: idem postponed.title = _('Call to {} from Creme Mobile').format(person) postponed.sub_type_id = act_constants.ACTIVITYSUBTYPE_PHONECALL_OUTGOING postponed.status = None postponed.floating_type = act_constants.FLOATING_TIME tomorrow = now() + timedelta(days=1) dt_combine = datetime.combine postponed.start = make_aware_dt( dt_combine(tomorrow, time(hour=0, minute=0))) postponed.end = make_aware_dt( dt_combine(tomorrow, time(hour=23, minute=59))) postponed.clone() return ''
def clean(self): cleaned_data = super().clean() if cleaned_data['type'] == SENDING_TYPE_DEFERRED: sending_date = cleaned_data['sending_date'] if sending_date is None: self.add_error('sending_date', _('Sending date required for a deferred sending')) else: get_data = cleaned_data.get sending_date = make_aware_dt(datetime.combine(sending_date, time(hour=int(get_data('hour') or 0), minute=int(get_data('minute') or 0), ), ) ) if sending_date < now(): self.add_error('sending_date', _('Sending date must be is the future')) else: cleaned_data['sending_date'] = sending_date else: cleaned_data['sending_date'] = now() return cleaned_data
def _get_datetime(*, request, key): timestamp = request.GET.get(key) if timestamp is not None: try: return make_aware_dt(datetime.fromtimestamp(float(timestamp))) except Exception: logger.exception('ActivitiesData._get_datetime(key=%s)', key)
def test_make_aware_dt02(self): dt = make_aware_dt(datetime(year=2016, month=12, day=13, hour=14, minute=35)) self.assertTrue(is_aware(dt)) self.assertEqual(2016, dt.year) self.assertEqual(12, dt.month) self.assertEqual(13, dt.day) self.assertEqual(14, dt.hour) self.assertEqual(35, dt.minute) self.assertEqual(timedelta(hours=1), dt.tzinfo.utcoffset(dt))
def _get_datetime(data, key, default_func): timestamp = data.get(key) if timestamp is not None: try: return make_aware_dt(datetime.fromtimestamp(float(timestamp))) except Exception: logger.exception('_get_datetime(key=%s)', key) return default_func()
def test_make_aware_dt03(self): with self.assertNoException(): # NB: date of change for the UTC offset dt = make_aware_dt(datetime(year=2016, month=10, day=30, hour=2, minute=30)) self.assertTrue(is_aware(dt)) self.assertEqual(2016, dt.year) self.assertEqual(10, dt.month) self.assertEqual(30, dt.day) self.assertEqual(2, dt.hour) self.assertEqual(30, dt.minute) self.assertEqual(timedelta(hours=1), dt.tzinfo.utcoffset(dt))
def test_make_aware_dt01(self): dt = datetime(year=2016, month=12, day=13, hour=14, minute=35) self.assertTrue(is_naive(dt)) dt2 = make_aware_dt(dt) self.assertTrue(is_aware(dt2)) self.assertEqual(2016, dt2.year) self.assertEqual(12, dt2.month) self.assertEqual(13, dt2.day) self.assertEqual(14, dt2.hour) self.assertEqual(35, dt2.minute) self.assertEqual(timedelta(hours=0), dt2.tzinfo.utcoffset(dt2))
def clean(self): cleaned_data = super().clean() if not self._errors: trigger_time = cleaned_data.get('trigger_time') if trigger_time: cleaned_data['trigger_date'] = make_aware_dt( datetime.combine(cleaned_data['trigger_date'], trigger_time), ) return cleaned_data
def clean(self): cdata = super().clean() if not self._errors: deadline_time = cdata.get('deadline_time') if deadline_time: cdata['deadline'] = make_aware_dt(datetime.combine(cdata['deadline'], deadline_time, ) ) return cdata
def _pre_instance_save(self, instance, line): instance.type, instance.sub_type = self.cleaned_data['type_selector'] instance.floating_type = constants.NARROW start = instance.start end = instance.end if start: null_time = time(0) if start.time() == null_time and (not end or end.time() == null_time): instance.end = make_aware_dt(datetime.combine(start, time(hour=23, minute=59))) instance.floating_type = constants.FLOATING_TIME elif not end: instance.end = start + instance.type.as_timedelta() elif start > instance.end: instance.end = start + instance.type.as_timedelta() self.append_error(_('End time is before start time')) else: instance.floating_type = constants.FLOATING
def clean(self): cdata = super().clean() if not self._errors: get_data = cdata.get deadline = get_data('deadline') if deadline: deadline_hour = get_data('deadline_hour') if deadline_hour is None: self.add_error( 'deadline_hour', _('The hour is required if you set a date.')) else: cdata['deadline'] = make_aware_dt( datetime.combine(deadline, time(deadline_hour))) return cdata
def _js_timestamp_to_datetime(timestamp): "@raise ValueError" # JS gives us milliseconds return make_aware_dt(datetime.fromtimestamp(float(timestamp) / 1000))
def _clean_interval(self, atype): cdata = self.cleaned_data start = cdata['start'] end = cdata['end'] if not start and not end: return constants.FLOATING floating_type = constants.NARROW get = cdata.get is_all_day = get('is_all_day', False) start_time = get('start_time') end_time = get('end_time') # TODO: not start, not end, start time, end time => floating activity with time set but lost in the process if start_time is None and end_time is None: if not is_all_day: if get('busy', False): raise ValidationError( self.error_messages['floating_cannot_busy'], code='floating_cannot_busy', ) floating_type = constants.FLOATING_TIME if not start and end: raise ValidationError(self.error_messages['no_start'], code='no_start') if start and start_time: start = make_aware_dt(datetime.combine(start, start_time)) if end and end_time: end = make_aware_dt(datetime.combine(end, end_time)) if start and not end: if end_time is not None: end = make_aware_dt(datetime.combine(start, end_time)) else: tdelta = atype.as_timedelta() if (is_all_day or floating_type == constants.FLOATING_TIME) and tdelta.days: # In 'all day' mode, we round the number of day days = tdelta.days - 1 # Activity already takes 1 day (we do not want it takes 2) if tdelta.seconds: days += 1 tdelta = timedelta(days=days) end = start + tdelta if is_all_day or floating_type == constants.FLOATING_TIME: start = make_aware_dt( datetime.combine(start, time(hour=0, minute=0))) end = make_aware_dt(datetime.combine(end, time(hour=23, minute=59))) if start > end: raise ValidationError( self.error_messages['end_before_start_time'], code='end_before_start_time', ) cdata['start'] = start cdata['end'] = end return floating_type
def _clean_temporal_data(self, activity_type): instance = self.instance get_data = self.cleaned_data.get get_key = self.subcell_key start = end = None start_date, start_time = get_data(get_key(StartSubCell)) or (None, None) end_date, end_time = get_data(get_key(EndSubCell)) or (None, None) if not start_date: if end_date: raise ValidationError(self.error_messages['no_start'], code='no_start') floating_type = constants.FLOATING else: is_all_day = get_data('is_all_day', False) floating_type = ( constants.NARROW if start_time or end_time or is_all_day else constants.FLOATING_TIME ) # TODO: not start_date, not end_date, start time, end time => # floating activity with time set but lost in the process if floating_type == constants.FLOATING_TIME and get_data('busy', False): raise ValidationError( self.error_messages['floating_cannot_busy'], code='floating_cannot_busy', ) start = make_aware_dt(datetime.combine(start_date, start_time or time())) if end_date: end = make_aware_dt(datetime.combine(end_date, end_time or time())) elif end_time is not None: end = make_aware_dt(datetime.combine(start_date, end_time)) else: tdelta = activity_type.as_timedelta() if (is_all_day or floating_type == constants.FLOATING_TIME) and tdelta.days: # In 'all day' mode, we round the number of day # Activity already takes 1 day (we do not want it takes 2) days = tdelta.days - 1 if tdelta.seconds: days += 1 tdelta = timedelta(days=days) end = start + tdelta if is_all_day or floating_type == constants.FLOATING_TIME: start = make_aware_dt(datetime.combine(start, time(hour=0, minute=0))) end = make_aware_dt(datetime.combine(end, time(hour=23, minute=59))) if start > end: raise ValidationError( self.error_messages['end_before_start'], code='end_before_start', ) instance.start = start instance.end = end instance.floating_type = floating_type