You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

209 lines
8.4 KiB

[ADD] Improve Shift management après avoir généré les shifts pour une semaine, rediriger vers les shifts générés : ok Ajouter un supercoopérateur au niveau du template de shift. Pas de champs related car il faut pouvoir gérer les remplacements entre supercoopérateurs. : Rajouter un boolean sur res.users pour dire qu'ils sont super coopérateur du coup on peut choisir qu'un utilisateur super coopérateur : Ok Sur la vue des shifts, permettre de sélectionner un ensemble de shifts pour pouvoir changer son supercoopérateur en une action : Ok Avoir une vue des shifts par défaut plus lisible que le calendrier : KANBAN avec TODAY par défaut et les colonnes selon le type de shift : ok Dans la vue KANBAN du planning des semaines, faire un tri sur la start date pour que ça ressemble à une vue calendrier :ok Droits d'accès : 3 groupes : modifier un shift existant et confirmer son statut : absence/présence générer et supprimer des shifts à partir du template modifier le template des semaines et gérer la config En réfléchissant à ceux qui vont gérer les présences : il faudrait avoir une vue facile sur les shifts du jour et une manière simple de dire présent/absent/remplacé pour l'ensemble des coopérateurs présents (éviter de devoir chaque fois sélectionner le shift, cliquer sur le statut, aller au shift suivant, cliquer sur le statut...). J'ai fait un nouveau point de menu avec une vue Kanban grouper par status, il suffit de faire du drag and drop pour changer le status, les shifts sont aussi filtré sur aujourd'hui et seulement ceux ayant un worker assigné.
8 years ago
[ADD] Improve Shift management après avoir généré les shifts pour une semaine, rediriger vers les shifts générés : ok Ajouter un supercoopérateur au niveau du template de shift. Pas de champs related car il faut pouvoir gérer les remplacements entre supercoopérateurs. : Rajouter un boolean sur res.users pour dire qu'ils sont super coopérateur du coup on peut choisir qu'un utilisateur super coopérateur : Ok Sur la vue des shifts, permettre de sélectionner un ensemble de shifts pour pouvoir changer son supercoopérateur en une action : Ok Avoir une vue des shifts par défaut plus lisible que le calendrier : KANBAN avec TODAY par défaut et les colonnes selon le type de shift : ok Dans la vue KANBAN du planning des semaines, faire un tri sur la start date pour que ça ressemble à une vue calendrier :ok Droits d'accès : 3 groupes : modifier un shift existant et confirmer son statut : absence/présence générer et supprimer des shifts à partir du template modifier le template des semaines et gérer la config En réfléchissant à ceux qui vont gérer les présences : il faudrait avoir une vue facile sur les shifts du jour et une manière simple de dire présent/absent/remplacé pour l'ensemble des coopérateurs présents (éviter de devoir chaque fois sélectionner le shift, cliquer sur le statut, aller au shift suivant, cliquer sur le statut...). J'ai fait un nouveau point de menu avec une vue Kanban grouper par status, il suffit de faire du drag and drop pour changer le status, les shifts sont aussi filtré sur aujourd'hui et seulement ceux ayant un worker assigné.
8 years ago
[ADD] Improve Shift management après avoir généré les shifts pour une semaine, rediriger vers les shifts générés : ok Ajouter un supercoopérateur au niveau du template de shift. Pas de champs related car il faut pouvoir gérer les remplacements entre supercoopérateurs. : Rajouter un boolean sur res.users pour dire qu'ils sont super coopérateur du coup on peut choisir qu'un utilisateur super coopérateur : Ok Sur la vue des shifts, permettre de sélectionner un ensemble de shifts pour pouvoir changer son supercoopérateur en une action : Ok Avoir une vue des shifts par défaut plus lisible que le calendrier : KANBAN avec TODAY par défaut et les colonnes selon le type de shift : ok Dans la vue KANBAN du planning des semaines, faire un tri sur la start date pour que ça ressemble à une vue calendrier :ok Droits d'accès : 3 groupes : modifier un shift existant et confirmer son statut : absence/présence générer et supprimer des shifts à partir du template modifier le template des semaines et gérer la config En réfléchissant à ceux qui vont gérer les présences : il faudrait avoir une vue facile sur les shifts du jour et une manière simple de dire présent/absent/remplacé pour l'ensemble des coopérateurs présents (éviter de devoir chaque fois sélectionner le shift, cliquer sur le statut, aller au shift suivant, cliquer sur le statut...). J'ai fait un nouveau point de menu avec une vue Kanban grouper par status, il suffit de faire du drag and drop pour changer le status, les shifts sont aussi filtré sur aujourd'hui et seulement ceux ayant un worker assigné.
8 years ago
[ADD] Improve Shift management après avoir généré les shifts pour une semaine, rediriger vers les shifts générés : ok Ajouter un supercoopérateur au niveau du template de shift. Pas de champs related car il faut pouvoir gérer les remplacements entre supercoopérateurs. : Rajouter un boolean sur res.users pour dire qu'ils sont super coopérateur du coup on peut choisir qu'un utilisateur super coopérateur : Ok Sur la vue des shifts, permettre de sélectionner un ensemble de shifts pour pouvoir changer son supercoopérateur en une action : Ok Avoir une vue des shifts par défaut plus lisible que le calendrier : KANBAN avec TODAY par défaut et les colonnes selon le type de shift : ok Dans la vue KANBAN du planning des semaines, faire un tri sur la start date pour que ça ressemble à une vue calendrier :ok Droits d'accès : 3 groupes : modifier un shift existant et confirmer son statut : absence/présence générer et supprimer des shifts à partir du template modifier le template des semaines et gérer la config En réfléchissant à ceux qui vont gérer les présences : il faudrait avoir une vue facile sur les shifts du jour et une manière simple de dire présent/absent/remplacé pour l'ensemble des coopérateurs présents (éviter de devoir chaque fois sélectionner le shift, cliquer sur le statut, aller au shift suivant, cliquer sur le statut...). J'ai fait un nouveau point de menu avec une vue Kanban grouper par status, il suffit de faire du drag and drop pour changer le status, les shifts sont aussi filtré sur aujourd'hui et seulement ceux ayant un worker assigné.
8 years ago
[ADD] Improve Shift management après avoir généré les shifts pour une semaine, rediriger vers les shifts générés : ok Ajouter un supercoopérateur au niveau du template de shift. Pas de champs related car il faut pouvoir gérer les remplacements entre supercoopérateurs. : Rajouter un boolean sur res.users pour dire qu'ils sont super coopérateur du coup on peut choisir qu'un utilisateur super coopérateur : Ok Sur la vue des shifts, permettre de sélectionner un ensemble de shifts pour pouvoir changer son supercoopérateur en une action : Ok Avoir une vue des shifts par défaut plus lisible que le calendrier : KANBAN avec TODAY par défaut et les colonnes selon le type de shift : ok Dans la vue KANBAN du planning des semaines, faire un tri sur la start date pour que ça ressemble à une vue calendrier :ok Droits d'accès : 3 groupes : modifier un shift existant et confirmer son statut : absence/présence générer et supprimer des shifts à partir du template modifier le template des semaines et gérer la config En réfléchissant à ceux qui vont gérer les présences : il faudrait avoir une vue facile sur les shifts du jour et une manière simple de dire présent/absent/remplacé pour l'ensemble des coopérateurs présents (éviter de devoir chaque fois sélectionner le shift, cliquer sur le statut, aller au shift suivant, cliquer sur le statut...). J'ai fait un nouveau point de menu avec une vue Kanban grouper par status, il suffit de faire du drag and drop pour changer le status, les shifts sont aussi filtré sur aujourd'hui et seulement ceux ayant un worker assigné.
8 years ago
[ADD] Improve Shift management après avoir généré les shifts pour une semaine, rediriger vers les shifts générés : ok Ajouter un supercoopérateur au niveau du template de shift. Pas de champs related car il faut pouvoir gérer les remplacements entre supercoopérateurs. : Rajouter un boolean sur res.users pour dire qu'ils sont super coopérateur du coup on peut choisir qu'un utilisateur super coopérateur : Ok Sur la vue des shifts, permettre de sélectionner un ensemble de shifts pour pouvoir changer son supercoopérateur en une action : Ok Avoir une vue des shifts par défaut plus lisible que le calendrier : KANBAN avec TODAY par défaut et les colonnes selon le type de shift : ok Dans la vue KANBAN du planning des semaines, faire un tri sur la start date pour que ça ressemble à une vue calendrier :ok Droits d'accès : 3 groupes : modifier un shift existant et confirmer son statut : absence/présence générer et supprimer des shifts à partir du template modifier le template des semaines et gérer la config En réfléchissant à ceux qui vont gérer les présences : il faudrait avoir une vue facile sur les shifts du jour et une manière simple de dire présent/absent/remplacé pour l'ensemble des coopérateurs présents (éviter de devoir chaque fois sélectionner le shift, cliquer sur le statut, aller au shift suivant, cliquer sur le statut...). J'ai fait un nouveau point de menu avec une vue Kanban grouper par status, il suffit de faire du drag and drop pour changer le status, les shifts sont aussi filtré sur aujourd'hui et seulement ceux ayant un worker assigné.
8 years ago
  1. from odoo import models, fields, api, _
  2. from odoo.exceptions import UserError
  3. from pytz import timezone, UTC
  4. import math
  5. from datetime import datetime, time, timedelta
  6. def float_to_time(f):
  7. decimal, integer = math.modf(f)
  8. return "%s:%s" % (str(int(integer)).zfill(2), str(int(round(decimal * 60))).zfill(2))
  9. def floatime_to_hour_minute(f):
  10. decimal, integer = math.modf(f)
  11. return int(integer), int(round(decimal * 60))
  12. def get_first_day_of_week():
  13. today = datetime.now()
  14. return (datetime.now() - timedelta(days=today.weekday())).date()
  15. class TaskType(models.Model):
  16. _name = 'beesdoo.shift.type'
  17. name = fields.Char()
  18. description = fields.Text()
  19. active = fields.Boolean(default=True)
  20. class DayNumber(models.Model):
  21. _name = 'beesdoo.shift.daynumber'
  22. _order = 'number asc'
  23. name = fields.Char()
  24. number = fields.Integer("Day Number", help="From 1 to N, When you will instanciate your planning, Day 1 will be the start date of the instance, Day 2 the second, etc...")
  25. active = fields.Boolean(default=True)
  26. class Planning(models.Model):
  27. _name = 'beesdoo.shift.planning'
  28. _order = 'sequence asc'
  29. sequence = fields.Integer()
  30. name = fields.Char()
  31. task_template_ids = fields.One2many('beesdoo.shift.template', 'planning_id')
  32. @api.model
  33. def _get_next_planning(self, sequence):
  34. next_planning = self.search([('sequence', '>', sequence)])
  35. if not next_planning:
  36. return self.search([])[0]
  37. return next_planning[0]
  38. @api.multi
  39. def _get_next_planning_date(self, date):
  40. self.ensure_one()
  41. nb_of_day = max(self.task_template_ids.mapped('day_nb_id.number'))
  42. return date + timedelta(days=nb_of_day)
  43. @api.model
  44. def _generate_next_planning(self):
  45. config = self.env['ir.config_parameter'].sudo()
  46. last_seq = int(config.get_param('last_planning_seq', 0))
  47. date = fields.Date.from_string(
  48. config.get_param('next_planning_date', 0)
  49. )
  50. planning = self._get_next_planning(last_seq)
  51. planning = planning.with_context(visualize_date=date)
  52. planning.task_template_ids._generate_task_day()
  53. next_date = planning._get_next_planning_date(date)
  54. config.set_param('last_planning_seq', planning.sequence)
  55. config.set_param('next_planning_date', next_date)
  56. class TaskTemplate(models.Model):
  57. _name = 'beesdoo.shift.template'
  58. _order = 'start_time'
  59. name = fields.Char(required=True)
  60. planning_id = fields.Many2one('beesdoo.shift.planning', required=True)
  61. day_nb_id = fields.Many2one('beesdoo.shift.daynumber', string='Day', required=True)
  62. task_type_id = fields.Many2one('beesdoo.shift.type', string="Type")
  63. # attendance_sheet_id = fields.Many2one('beesdoo.shift.sheet', string="Attendance Sheet") FIXME removed because beesdoo.shift.sheet is from another module.
  64. start_time = fields.Float(required=True)
  65. end_time = fields.Float(required=True)
  66. super_coop_id = fields.Many2one('res.users', string="Super Cooperative", domain=[('partner_id.super', '=', True)])
  67. duration = fields.Float(help="Duration in Hour")
  68. worker_nb = fields.Integer(string="Number of worker", help="Max number of worker for this task", default=1)
  69. worker_ids = fields.Many2many('res.partner', string="Recurrent worker assigned", domain=[('is_worker', '=', True)])
  70. remaining_worker = fields.Integer(compute="_get_remaining", store=True, string="Remaining Place")
  71. active = fields.Boolean(default=True)
  72. #For Kanban View Only
  73. color = fields.Integer('Color Index')
  74. worker_name = fields.Char(compute="_get_worker_name")
  75. #For calendar View
  76. start_date = fields.Datetime(compute="_get_fake_date", search="_dummy_search")
  77. end_date = fields.Datetime(compute="_get_fake_date", search="_dummy_search")
  78. def _get_utc_date(self, day, hour, minute):
  79. """Combine day number, hours and minutes to save
  80. corresponding UTC datetime in database.
  81. """
  82. context_tz = timezone(self._context.get('tz') or self.env.user.tz)
  83. day_local_time = datetime.combine(day, time(hour=hour, minute=minute))
  84. day_local_time = context_tz.localize(day_local_time)
  85. day_utc_time = day_local_time.astimezone(UTC)
  86. # Return naïve datetime so as to be saved in database
  87. return day_utc_time.replace(tzinfo=None)
  88. @api.depends('start_time', 'end_time')
  89. def _get_fake_date(self):
  90. today = self._context.get('visualize_date', get_first_day_of_week())
  91. for rec in self:
  92. # Find the day of this task template 'rec'.
  93. day = today + timedelta(days=rec.day_nb_id.number - 1)
  94. # Compute the beginning and ending time according to the
  95. # context timezone.
  96. h_begin, m_begin = floatime_to_hour_minute(rec.start_time)
  97. h_end, m_end = floatime_to_hour_minute(rec.end_time)
  98. rec.start_date = self._get_utc_date(day, h_begin, m_begin)
  99. rec.end_date = self._get_utc_date(day, h_end, m_end)
  100. def _dummy_search(self, operator, value):
  101. return []
  102. @api.depends('worker_ids', 'worker_nb')
  103. def _get_remaining(self):
  104. for rec in self:
  105. rec.remaining_worker = rec.worker_nb - len(rec.worker_ids)
  106. @api.depends("worker_ids")
  107. def _get_worker_name(self):
  108. for rec in self:
  109. rec.worker_name = ','.join(rec.worker_ids.mapped('display_name'))
  110. @api.constrains('worker_nb', 'worker_ids')
  111. def _nb_worker_max(self):
  112. for rec in self:
  113. if len(rec.worker_ids) > rec.worker_nb:
  114. raise UserError(_('You cannot assign more workers than the maximal number defined on template.'))
  115. @api.onchange('start_time', 'end_time')
  116. def _get_duration(self):
  117. if self.start_time and self.end_time:
  118. self.duration = self.end_time - self.start_time
  119. @api.onchange('duration')
  120. def _set_duration(self):
  121. if self.start_time:
  122. self.end_time = self.start_time +self.duration
  123. def _generate_task_day(self):
  124. tasks = self.env['beesdoo.shift.shift']
  125. for rec in self:
  126. for i in range(0, rec.worker_nb):
  127. worker_id = rec.worker_ids[i] if len(rec.worker_ids) > i else False
  128. #remove worker in holiday and temporary exempted
  129. if worker_id and worker_id.cooperative_status_ids:
  130. status = worker_id.cooperative_status_ids[0]
  131. if status.holiday_start_time and status.holiday_end_time and \
  132. status.holiday_start_time <= rec.start_date.date() and status.holiday_end_time >= rec.end_date.date():
  133. worker_id = False
  134. if status.temporary_exempt_start_date and status.temporary_exempt_end_date and \
  135. status.temporary_exempt_start_date <= rec.start_date.date() and status.temporary_exempt_end_date >= rec.end_date.date():
  136. worker_id = False
  137. tasks |= tasks.create({
  138. 'name' : "[%s] %s %s (%s - %s) [%s]" % (
  139. rec.start_date.date(),
  140. rec.planning_id.name,
  141. rec.day_nb_id.name,
  142. float_to_time(rec.start_time),
  143. float_to_time(rec.end_time),
  144. i,
  145. ),
  146. 'task_template_id' : rec.id,
  147. 'task_type_id' : rec.task_type_id.id,
  148. 'super_coop_id': rec.super_coop_id.id,
  149. 'worker_id' : worker_id and worker_id.id or False,
  150. 'is_regular': True if worker_id else False,
  151. 'start_time' : rec.start_date,
  152. 'end_time' : rec.end_date,
  153. 'state': 'open',
  154. })
  155. return tasks
  156. @api.onchange('worker_ids')
  157. def check_for_multiple_shifts(self):
  158. original_ids = {worker.id for worker in self._origin.worker_ids}
  159. warnings = []
  160. for worker in self.worker_ids:
  161. if worker.id not in original_ids:
  162. shifts = [shift.name for shift in worker.subscribed_shift_ids if shift.id != self.id]
  163. if shifts:
  164. warnings.append(
  165. worker.name + _(' is already assigned to ') + ", ".join(shifts))
  166. if warnings:
  167. return {
  168. 'warning': {
  169. 'title': _("Warning"),
  170. 'message': "\n".join(warnings)
  171. }
  172. }