[REM] calendar: Remove useless time fields

The fields `start_datetime` and `stop_datetime` are the exact miror
of fields `start` and `stop` respectively.

The field `display_start` is never used.

Hence those fields are removed.

Task 2126717
PR #42031
PR Enterprise odoo/enterprise#8006
This commit is contained in:
Lucas Lefèvre
2020-04-09 10:56:37 +02:00
parent 658c062e6d
commit 6bafd7c677
5 changed files with 44 additions and 87 deletions
+36 -59
View File
@@ -26,7 +26,6 @@ _logger = logging.getLogger(__name__)
SORT_ALIASES = {
'start': 'sort_start',
'start_date': 'sort_start',
'start_datetime': 'sort_start',
}
def get_weekday_occurence(date):
@@ -115,13 +114,13 @@ class Meeting(models.Model):
@api.model
def _get_time_fields(self):
return {'start', 'stop', 'start_date', 'stop_date', 'start_datetime', 'stop_datetime'}
return {'start', 'stop', 'start_date', 'stop_date'}
@api.model
def _get_public_fields(self):
return self._get_recurrent_fields() | {
'id', 'active', 'allday', 'start', 'stop', 'display_start',
'display_stop', 'duration', 'user_id', 'interval',
'id', 'active', 'allday', 'start', 'stop',
'duration', 'user_id', 'interval',
'count', 'rrule', 'recurrence_id', 'show_as'}
@api.model
@@ -170,12 +169,10 @@ class Meeting(models.Model):
def _get_duration(self, start, stop):
""" Get the duration value between the 2 given dates. """
if start and stop:
diff = fields.Datetime.from_string(stop) - fields.Datetime.from_string(start)
if diff:
duration = float(diff.days) * 24 + (float(diff.seconds) / 3600)
return round(duration, 2)
return 0.0
if not start or not stop:
return 0
duration = (stop - start).total_seconds() / 3600
return round(duration, 2)
def _compute_is_highlighted(self):
if self.env.context.get('active_model') == 'res.partner':
@@ -194,17 +191,15 @@ class Meeting(models.Model):
is_attendee = fields.Boolean('Attendee', compute='_compute_attendee')
attendee_status = fields.Selection(Attendee.STATE_SELECTION, string='Attendee Status', compute='_compute_attendee')
display_time = fields.Char('Event Time', compute='_compute_display_time')
display_start = fields.Char('Date', compute='_compute_display_start', store=True)
start = fields.Datetime('Start', required=True, help="Start date of an event, without time for full days events")
stop = fields.Datetime('Stop', required=True, help="Stop date of an event, without time for full days events")
start = fields.Datetime('Start', required=True, tracking=True, default=fields.Date.today, help="Start date of an event, without time for full days events")
stop = fields.Datetime('Stop', required=True, tracking=True, default=fields.Date.today, compute='_compute_stop', readonly=False, store=True,
help="Stop date of an event, without time for full days events")
allday = fields.Boolean('All Day', default=False)
start_date = fields.Date('Start Date', compute='_compute_dates', inverse='_inverse_dates', store=True, tracking=True)
start_datetime = fields.Datetime('Start DateTime', compute='_compute_dates', inverse='_inverse_dates', store=True, tracking=True)
stop_date = fields.Date('End Date', compute='_compute_dates', inverse='_inverse_dates', store=True, tracking=True)
stop_datetime = fields.Datetime('End Datetime', compute='_compute_dates', inverse='_inverse_dates', store=True, tracking=True) # old date_deadline
event_tz = fields.Selection('_event_tz_get', string='Timezone', default=lambda self: self.env.context.get('tz') or self.user_id.tz)
duration = fields.Float('Duration', compute='_compute_dates', inverse='_inverse_duration', compute_sudo=True)
duration = fields.Float('Duration', compute='_compute_duration', store=True, readonly=False)
description = fields.Text('Description')
privacy = fields.Selection([('public', 'Everyone'), ('private', 'Only me'), ('confidential', 'Only internal users')], 'Privacy', default='public', required=True)
location = fields.Char('Location', tracking=True, help="Location of Event")
@@ -284,11 +279,6 @@ class Meeting(models.Model):
for meeting in self:
meeting.display_time = self._get_display_time(meeting.start, meeting.stop, meeting.duration, meeting.allday)
@api.depends('allday', 'start_date', 'start_datetime')
def _compute_display_start(self):
for meeting in self:
meeting.display_start = meeting.start_date if meeting.allday else meeting.start_datetime
@api.depends('allday', 'start', 'stop')
def _compute_dates(self):
""" Adapt the value of start_date(time)/stop_date(time) according to start/stop fields and allday. Also, compute
@@ -297,18 +287,33 @@ class Meeting(models.Model):
for meeting in self:
if meeting.allday and meeting.start and meeting.stop:
meeting.start_date = meeting.start.date()
meeting.start_datetime = False
meeting.stop_date = meeting.stop.date()
meeting.stop_datetime = False
meeting.duration = 0.0
else:
meeting.start_date = False
meeting.start_datetime = meeting.start
meeting.stop_date = False
meeting.stop_datetime = meeting.stop
meeting.duration = self._get_duration(meeting.start, meeting.stop)
@api.depends('stop', 'start')
def _compute_duration(self):
for event in self.with_context(dont_notify=True):
event.duration = self._get_duration(event.start, event.stop)
@api.depends('start', 'duration')
def _compute_stop(self):
# stop and duration fields both depends on the start field.
# But they also depends on each other.
# When start is updated, we want to update the stop datetime based on
# the *current* duration. In other words, we want: change start => keep the duration fixed and
# recompute stop accordingly.
# However, while computing stop, duration is marked to be recomputed. Calling `event.duration` would trigger
# its recomputation. To avoid this we manually mark the field as computed.
duration_field = self._fields['duration']
self.env.remove_to_compute(duration_field, self)
for event in self.filtered('duration'):
# Round the duration (in hours) to the minute to avoid weird situations where the event
# stops at 4:19:59, later displayed as 4:19.
event.stop = event.start + timedelta(minutes=round(event.duration * 60))
if event.allday:
event.stop -= timedelta(seconds=1)
def _inverse_dates(self):
for meeting in self:
@@ -330,21 +335,14 @@ class Meeting(models.Model):
'start': startdate.replace(tzinfo=None),
'stop': enddate.replace(tzinfo=None)
})
else:
meeting.write({'start': meeting.start_datetime,
'stop': meeting.stop_datetime})
def _inverse_duration(self):
for event in self:
event.stop = event.start + relativedelta(hours=event.duration)
@api.constrains('start_datetime', 'stop_datetime', 'start_date', 'stop_date')
@api.constrains('start', 'stop', 'start_date', 'stop_date')
def _check_closing_date(self):
for meeting in self:
if meeting.start_datetime and meeting.stop_datetime and meeting.stop_datetime < meeting.start_datetime:
if meeting.start and meeting.stop and meeting.stop < meeting.start:
raise ValidationError(
_('The ending date and time cannot be earlier than the starting date and time.') + '\n' +
_("Meeting '%s' starts '%s' and ends '%s'") % (meeting.name, meeting.start_datetime, meeting.stop_datetime)
_("Meeting '%s' starts '%s' and ends '%s'") % (meeting.name, meeting.start, meeting.stop)
)
if meeting.start_date and meeting.stop_date and meeting.stop_date < meeting.start_date:
raise ValidationError(
@@ -352,27 +350,6 @@ class Meeting(models.Model):
_("Meeting '%s' starts '%s' and ends '%s'") % (meeting.name, meeting.start_date, meeting.stop_date)
)
@api.onchange('start_datetime', 'duration')
def _onchange_duration(self):
if self.start_datetime:
start = self.start_datetime
self.start = self.start_datetime
# Round the duration (in hours) to the minute to avoid weird situations where the event
# stops at 4:19:59, later displayed as 4:19.
self.stop = start + timedelta(minutes=round(self.duration * 60))
if self.allday:
self.stop -= timedelta(seconds=1)
@api.onchange('start_date')
def _onchange_start_date(self):
if self.start_date:
self.start = datetime.datetime.combine(self.start_date, datetime.time.min)
@api.onchange('stop_date')
def _onchange_stop_date(self):
if self.stop_date:
self.stop = datetime.datetime.combine(self.stop_date, datetime.time.max)
####################################################
# Calendar Business, Reccurency, ...
####################################################
+1 -20
View File
@@ -27,20 +27,6 @@ class TestCalendar(SavepointCaseWithUserDemo):
'name': 'Technical Presentation'
})
def test_calender_simple_event(self):
m = self.CalendarEvent.create({
'name': "Test compute",
'start': '2017-07-12 14:30:00',
'allday': False,
'stop': '2017-07-12 15:00:00',
})
self.assertEqual(
(str(m.start_datetime), str(m.stop_datetime)),
(u'2017-07-12 14:30:00', u'2017-07-12 15:00:00'),
"Sanity check"
)
def test_event_order(self):
""" check the ordering of events when searching """
def create_event(name, date):
@@ -48,7 +34,6 @@ class TestCalendar(SavepointCaseWithUserDemo):
'name': name,
'start': date + ' 12:00:00',
'stop': date + ' 14:00:00',
'duration': 2.0,
})
foo1 = create_event('foo', '2011-04-01')
foo2 = create_event('foo', '2011-06-01')
@@ -162,13 +147,11 @@ class TestCalendar(SavepointCaseWithUserDemo):
'name': 'All Day',
'start': "2018-10-16 00:00:00",
'start_date': "2018-10-16",
'start_datetime': False,
'stop': "2018-10-18 00:00:00",
'stop_date': "2018-10-18",
'stop_datetime': False,
'allday': True,
})
event.invalidate_cache()
self.assertEqual(str(event.start), '2018-10-16 08:00:00')
self.assertEqual(str(event.stop), '2018-10-18 18:00:00')
@@ -243,10 +226,8 @@ class TestCalendar(SavepointCaseWithUserDemo):
'name': 'All Day',
'start': "2018-10-16 00:00:00",
'start_date': "2018-10-16",
'start_datetime': False,
'stop': "2018-10-18 00:00:00",
'stop_date': "2018-10-18",
'stop_datetime': False,
'allday': True,
'activity_ids': [(6, False, activity_id.ids)],
})
@@ -249,8 +249,10 @@ class TestCreateRecurrentEvents(TestRecurrentEvents):
def test_ambiguous_full_day(self):
""" Test date stays the same, regardless of DST changes """
self.event.start = datetime(2020, 3, 23, 0, 0)
self.event.stop = datetime(2020, 3, 23, 23, 59)
self.event.write({
'start': datetime(2020, 3, 23, 0, 0),
'stop': datetime(2020, 3, 23, 23, 59),
})
self.event.allday = True
self.event._apply_recurrence_values({
'interval': 1,
+2 -5
View File
@@ -117,15 +117,12 @@
<page name="page_details" string="Meeting Details">
<group>
<group>
<field name="start" attrs="{'invisible': True}"/>
<field name="stop" attrs="{'invisible': True}"/>
<field name="id" attrs="{'invisible': True}"/>
<field name="start_date" string="Starting at" attrs="{'required': [('allday','=',True)], 'invisible': [('allday','=',False)]}" force_save="1"/>
<field name="stop_date" string="Ending at" attrs="{'required': [('allday','=',True)],'invisible': [('allday','=',False)]}" force_save="1"/>
<field name="start_datetime" string="Starting at" attrs="{'required': [('allday','=',False)], 'invisible': [('allday','=',True)]}"/>
<field name="stop_datetime" invisible="1"/>
<field name="start" string="Starting at" attrs="{'required': [('allday','=',False)], 'invisible': [('allday','=',True)]}"/>
<field name="stop" invisible="1"/>
<label for="duration" attrs="{'invisible': [('allday','=',True)]}"/>
<div attrs="{'invisible': [('allday','=',True)]}">
<field name="duration" widget="float_time" string="Duration" class="oe_inline" attrs="{'readonly': [('id', '!=', False), ('recurrency','=',True)]}"/>
+1 -1
View File
@@ -15,7 +15,7 @@ class Meeting(models.Model):
recurrent_fields = self._get_recurrent_fields()
return recurrent_fields | {'name', 'description', 'allday', 'start', 'date_end', 'stop',
'attendee_ids', 'alarm_ids', 'location', 'privacy', 'active',
'start_date', 'start_datetime', 'stop_date', 'stop_datetime'}
'start_date', 'stop_date'}
def write(self, values):
sync_fields = set(self.get_fields_need_update_google())