diff options
Diffstat (limited to 'addons/timer/models/timer_mixin.py')
| -rw-r--r-- | addons/timer/models/timer_mixin.py | 135 |
1 files changed, 135 insertions, 0 deletions
diff --git a/addons/timer/models/timer_mixin.py b/addons/timer/models/timer_mixin.py new file mode 100644 index 00000000000..201628a16af --- /dev/null +++ b/addons/timer/models/timer_mixin.py @@ -0,0 +1,135 @@ +# -*- coding: utf-8 -*- +# Part of Odoo. See LICENSE file for full copyright and licensing details. + +from odoo import models, fields, api +from math import ceil + +class TimerMixin(models.AbstractModel): + _name = 'timer.mixin' + _description = 'Timer Mixin' + + timer_start = fields.Datetime(related='user_timer_id.timer_start') + timer_pause = fields.Datetime(related='user_timer_id.timer_pause') + is_timer_running = fields.Boolean(related='user_timer_id.is_timer_running') + user_timer_id = fields.One2many('timer.timer', compute='_compute_user_timer_id', search='_search_user_timer_id') + + display_timer_start_primary = fields.Boolean(compute='_compute_display_timer_buttons') + display_timer_stop = fields.Boolean(compute='_compute_display_timer_buttons') + display_timer_pause = fields.Boolean(compute='_compute_display_timer_buttons') + display_timer_resume = fields.Boolean(compute='_compute_display_timer_buttons') + + def _search_user_timer_id(self, operator, value): + timers = self.env['timer.timer'].search([ + ('id', operator, value), + ('user_id', '=', self.env.user.id), + ]) + return [('id', 'in', timers.mapped('res_id'))] + + @api.depends_context('uid') + def _compute_user_timer_id(self): + """ Get the timers according these conditions + :user_id is is the current user + :res_id is the current record + :res_model is the current model + limit=1 by security but the search should never have more than one record + """ + for record in self: + record.user_timer_id = self.env['timer.timer'].search([ + ('user_id', '=', record.env.user.id), + ('res_id', '=', record.id), + ('res_model', '=', record._name) + ], limit=1) + + @api.model + def _get_user_timers(self): + # Return user's timers. Can have multiple timers if some are in pause + return self.env['timer.timer'].search([('user_id', '=', self.env.user.id)]) + + def action_timer_start(self): + """ Start the timer of the current record + First, if a timer is running, stop or pause it + If there isn't a timer for the current record, create one then start it + Otherwise, resume or start it + """ + self.ensure_one() + self._stop_timer_in_progress() + timer = self.user_timer_id + if not timer: + timer = self.env['timer.timer'].create({ + 'timer_start' : False, + 'timer_pause' : False, + 'is_timer_running' : False, + 'res_model' : self._name, + 'res_id' : self.id, + 'user_id' : self.env.user.id, + }) + timer.action_timer_start() + else: + # Check if it is in pause then resume it or start it + if timer.timer_pause: + timer.action_timer_resume() + else: + timer.action_timer_start() + + def action_timer_stop(self): + """ Stop the timer of the current record + Unlink the timer, it's useless to keep the stopped timer. + A new timer can be create if needed + Return the amount of minutes spent + """ + self.ensure_one() + timer = self.user_timer_id + minutes_spent = timer.action_timer_stop() + timer.unlink() + return minutes_spent + + def action_timer_pause(self): + self.ensure_one() + timer = self.user_timer_id + timer.action_timer_pause() + + def action_timer_resume(self): + self.ensure_one() + self._stop_timer_in_progress() + timer = self.user_timer_id + timer.action_timer_resume() + + def _action_interrupt_user_timers(self): + # Interruption is the action called when the timer is stoped by the start of another one + self.action_timer_pause() + + def _stop_timer_in_progress(self): + """ + Cancel the timer in progress if there is one + Each model can interrupt the running timer in a specific way + By setting it in pause or stop by example + """ + timer = self._get_user_timers().filtered(lambda t: t.is_timer_running) + if timer: + model = self.env[timer.res_model].browse(timer.res_id) + model._action_interrupt_user_timers() + + @api.depends('timer_start', 'timer_pause') + def _compute_display_timer_buttons(self): + for record in self: + start_p, stop, pause, resume = True, True, True, True + if record.timer_start: + start_p = False + if record.timer_pause: + pause = False + else: + resume = False + record.write({ + 'display_timer_start_primary': start_p, + 'display_timer_stop': stop, + 'display_timer_pause': pause, + 'display_timer_resume': resume, + }) + return {'start_p': start_p, 'stop': stop, 'pause': pause, 'resume': resume} + + @api.model + def _timer_rounding(self, minutes_spent, minimum, rounding): + minutes_spent = max(minimum, minutes_spent) + if rounding and ceil(minutes_spent % rounding) != 0: + minutes_spent = ceil(minutes_spent / rounding) * rounding + return minutes_spent |
