diff --git a/models/calendar.py b/models/calendar.py index 40a3251b5770b57a49e1f6049ea29b1e9a633f3d..a26276009883a9490b20675c9b3ebd599c9bae7d 100644 --- a/models/calendar.py +++ b/models/calendar.py @@ -8,6 +8,16 @@ from odoo import models, fields, api from odoo.exceptions import UserError, ValidationError +class CGScopAttendee(models.Model): + _inherit = 'calendar.attendee' + + timesheet_id = fields.Many2one( + comodel_name='account.analytic.line', + string='Timesheet linked', + ondelete='set null', + copy=False) + + class CGScopCalendar(models.Model): _inherit = 'calendar.event' @@ -61,6 +71,26 @@ class CGScopCalendar(models.Model): ur_regional_convention_nb = fields.Integer( string="Nb conventions régionales", compute="_compute_ur_system_nb") + attendees_initial = fields.Char( + string='Initiales Participants', + compute='_compute_attendees_initial') + state = fields.Selection([ + ('needsAction', 'Non répondu'), + ('tentative', 'Incertain'), + ('declined', 'Refusé'), + ('accepted', 'Accepté')], + string='Statut', + compute='_compute_attendee_state', + help="Statut du participant", + default='needsAction') + is_attendee = fields.Boolean( + string='Est participant', + compute='_compute_is_attendee', + default=False) + is_transfered = fields.Boolean( + string='Transféré', + compute='_compute_is_transfered', + default=False) # ------------------------------------------------------ # Compute @@ -79,6 +109,38 @@ class CGScopCalendar(models.Model): event.ur_regional_convention_nb = len( regional_convention) + @api.depends('partner_ids') + def _compute_attendees_initial(self): + for event in self: + initials = '' + for partner in event.partner_ids: + initials += partner.lastname[0] + '.' + partner.firstname[0] + ', ' + event.attendees_initial = initials + + def _compute_attendee_state(self): + for event in self: + attendee = self.env['calendar.attendee'].search([ + ('event_id', '=', event.id), + ('partner_id', '=', self.env.user.partner_id.id)]) + event.state = attendee.state + + def _compute_is_attendee(self): + for event in self: + if self.env.user.partner_id in event.partner_ids: + event.is_attendee = True + else: + event.is_attendee = False + + def _compute_is_transfered(self): + for event in self: + attendee = self.env['calendar.attendee'].search([ + ('event_id', '=', event.id), + ('partner_id', '=', self.env.user.partner_id.id)]) + if attendee.timesheet_id: + event.is_transfered = True + else: + event.is_transfered = False + # ------------------------------------------------------ # Onchange # ------------------------------------------------------ @@ -133,67 +195,116 @@ class CGScopCalendar(models.Model): # ------------------------------------------------------ # Fonction boutons # ------------------------------------------------------ + @api.multi + def do_accept(self): + """ Accepte l'invitation + Modifie le statut de la table Attendees + """ + for event in self: + attendee = self.env['calendar.attendee'].search([ + ('event_id', '=', event.id), + ('partner_id', '=', self.env.user.partner_id.id)]) + attendee.state = 'accepted' + + @api.multi + def do_decline(self): + """ Refuse l'invitation + Modifie le statut de la table Attendees + """ + for event in self: + attendee = self.env['calendar.attendee'].search([ + ('event_id', '=', event.id), + ('partner_id', '=', self.env.user.partner_id.id)]) + attendee.state = 'declined' + + @api.multi + def do_tentative(self): + """ Incertain pour l'invitation + Modifie le statut de la table Attendees + """ + for event in self: + attendee = self.env['calendar.attendee'].search([ + ('event_id', '=', event.id), + ('partner_id', '=', self.env.user.partner_id.id)]) + attendee.state = 'tentative' + @api.multi def create_timesheet(self): """ Crée une ligne de temps à partir de l'entrée d'agenda """ + partner = self.env.user.partner_id for event in self: + if not partner in event.partner_ids: + raise UserError("Vous ne faites pas partie des participants, \ + vous ne pouvez donc pas transformer cette entrée d'agenda \ + en ligne de temps.") if not event.project_id.analytic_account_id: raise UserError("Le code activité UR doit être \ renseigné sur chaque entrée d'agenda") else: - values = { - 'user_id': self.env.user.id, - 'project_id': event.project_id.id, - 'account_id': event.project_id.analytic_account_id.id, - 'ur_financial_system_id': event.ur_financial_system_id.id, - 'name': event.name, - 'company_id': self.env.user.company_id.id, - 'partner_id': event.coop_id.id, - 'event_id': event.id, - } - # Gestion des évènements sur toute la journée - if event.allday: - # Création d'une ligne de 8h pour chaque jour - for i in range((event.stop - event.start).days + 1): - values['date'] = event.start + timedelta(days=i) - values['unit_amount'] = 8.0 - self.env['account.analytic.line'].create(values) - # Gestion des évènements sur plusieurs jours non flagués allday - if (event.stop - event.start).days > 0: - user_tz = self.env.user.tz - local = pytz.timezone(user_tz) - # Pour chaque jour - for i in range((event.stop - event.start).days + 1): - day = event.start + timedelta(days=i) - # si premier jour calcul heures - if i == 0: - end_day_tz = local.localize( - day.replace(hour=18)) - start_tz = fields.Datetime.context_timestamp( - record=self.env.user, - timestamp=event.start) - hours_cal = (end_day_tz - start_tz).seconds//3600 - hours = hours_cal if hours_cal <= 8 else 8.0 - # si dernier jour - elif i == (event.stop - event.start).days: - start_day_tz = local.localize( - day.replace(hour=8)) - stop_tz = fields.Datetime.context_timestamp( - record=self.env.user, - timestamp=event.stop) - hours_cal = (stop_tz - start_day_tz).seconds//3600 - hours = hours_cal if hours_cal <= 8 else 8.0 - else: - hours = 8.0 - values['date'] = day - values['unit_amount'] = hours - self.env['account.analytic.line'].create(values) - # Gestion des évènements classiques + attendee = self.env['calendar.attendee'].search([ + ('event_id', '=', event.id), + ('partner_id', '=', partner.id)]) + if attendee.timesheet_id: + raise UserError("Vous avez déjà transféré cette entrée \ + d'agenda : %s" % event.name) else: - values['date'] = event.start - values['unit_amount'] = event.duration - self.env['account.analytic.line'].create(values) + values = { + 'user_id': self.env.user.id, + 'project_id': event.project_id.id, + 'account_id': event.project_id.analytic_account_id.id, + 'ur_financial_system_id': event.ur_financial_system_id.id, + 'name': event.name, + 'company_id': self.env.user.company_id.id, + 'partner_id': event.coop_id.id, + 'event_id': event.id, + 'attendee_id': attendee.id, + } + # Gestion des évènements sur toute la journée + if event.allday: + # Création d'une ligne de 8h pour chaque jour + for i in range((event.stop - event.start).days + 1): + values['date'] = event.start + timedelta(days=i) + values['unit_amount'] = 8.0 + ts = self.env['account.analytic.line'].create(values) + attendee.write({'timesheet_id': ts.id}) + # Gestion des évènements sur plusieurs jours non flagués allday + if (event.stop - event.start).days > 0: + user_tz = self.env.user.tz + local = pytz.timezone(user_tz) + # Pour chaque jour + for i in range((event.stop - event.start).days + 1): + day = event.start + timedelta(days=i) + # si premier jour calcul heures + if i == 0: + end_day_tz = local.localize( + day.replace(hour=18)) + start_tz = fields.Datetime.context_timestamp( + record=self.env.user, + timestamp=event.start) + hours_cal = (end_day_tz - start_tz).seconds//3600 + hours = hours_cal if hours_cal <= 8 else 8.0 + # si dernier jour + elif i == (event.stop - event.start).days: + start_day_tz = local.localize( + day.replace(hour=8)) + stop_tz = fields.Datetime.context_timestamp( + record=self.env.user, + timestamp=event.stop) + hours_cal = (stop_tz - start_day_tz).seconds//3600 + hours = hours_cal if hours_cal <= 8 else 8.0 + else: + hours = 8.0 + values['date'] = day + values['unit_amount'] = hours + ts = self.env['account.analytic.line'].create(values) + attendee.write({'timesheet_id': ts.id}) + # Gestion des évènements classiques + else: + values['date'] = event.start + values['unit_amount'] = event.duration + ts = self.env['account.analytic.line'].create(values) + attendee.write({'timesheet_id': ts.id}) @api.multi def duplicate_entry(self): diff --git a/models/hr_timesheet.py b/models/hr_timesheet.py index 4210d82325380868fa8636794dcca3eb16d570d2..60071dca7345332781f8ed9cc9b97c222a102ca6 100644 --- a/models/hr_timesheet.py +++ b/models/hr_timesheet.py @@ -12,6 +12,11 @@ class ScopHrTimesheetCalendar(models.Model): string="Entrée d'Agenda", copy=False, ondelete="set null") + attendee_id = fields.Many2one( + comodel_name='calendar.attendee', + string="Invitation", + copy=False, + ondelete="set null") type_event = fields.Selection([ ('outside', 'Extérieur'), ('ur', 'UR'),