[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:
@@ -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, ...
|
||||
####################################################
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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)]}"/>
|
||||
|
||||
@@ -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())
|
||||
|
||||
Reference in New Issue
Block a user