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.

208 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. # -*- coding: utf-8 -*-
  2. from openerp import models, fields, api, _
  3. from openerp.exceptions import UserError
  4. from pytz import timezone, UTC
  5. import math
  6. from datetime import datetime, timedelta
  7. def float_to_time(f):
  8. decimal, integer = math.modf(f)
  9. return "%s:%s" % (str(int(integer)).zfill(2), str(int(round(decimal * 60))).zfill(2))
  10. def floatime_to_hour_minute(f):
  11. decimal, integer = math.modf(f)
  12. return int(integer), int(round(decimal * 60))
  13. def get_first_day_of_week():
  14. today = datetime.now()
  15. return (datetime.now() - timedelta(days=today.weekday())).strftime("%Y-%m-%d")
  16. class TaskType(models.Model):
  17. _name = 'beesdoo.shift.type'
  18. name = fields.Char()
  19. description = fields.Text()
  20. active = fields.Boolean(default=True)
  21. class DayNumber(models.Model):
  22. _name = 'beesdoo.shift.daynumber'
  23. _order = 'number asc'
  24. name = fields.Char()
  25. 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...")
  26. active = fields.Boolean(default=True)
  27. class Planning(models.Model):
  28. _name = 'beesdoo.shift.planning'
  29. _order = 'sequence asc'
  30. sequence = fields.Integer()
  31. name = fields.Char()
  32. task_template_ids = fields.One2many('beesdoo.shift.template', 'planning_id')
  33. @api.model
  34. def _get_next_planning(self, sequence):
  35. next_planning = self.search([('sequence', '>', sequence)])
  36. if not next_planning:
  37. return self.search([])[0]
  38. return next_planning[0]
  39. @api.multi
  40. def _get_next_planning_date(self, date):
  41. self.ensure_one()
  42. nb_of_day = max(self.task_template_ids.mapped('day_nb_id.number'))
  43. return fields.Date.to_string(fields.Date.from_string(date) + timedelta(days=nb_of_day))
  44. @api.model
  45. def _generate_next_planning(self):
  46. config = self.env['ir.config_parameter']
  47. last_seq = int(config.get_param('last_planning_seq', 0))
  48. date = config.get_param('next_planning_date', 0)
  49. planning = self._get_next_planning(last_seq)
  50. planning = planning.with_context(visualize_date=date)
  51. planning.task_template_ids._generate_task_day()
  52. next_date = planning._get_next_planning_date(date)
  53. config.set_param('last_planning_seq', planning.sequence)
  54. config.set_param('next_planning_date', next_date)
  55. class TaskTemplate(models.Model):
  56. _name = 'beesdoo.shift.template'
  57. _order = 'start_time'
  58. name = fields.Char(required=True)
  59. planning_id = fields.Many2one('beesdoo.shift.planning', required=True)
  60. day_nb_id = fields.Many2one('beesdoo.shift.daynumber', string='Day', required=True)
  61. task_type_id = fields.Many2one('beesdoo.shift.type', string="Type")
  62. attendance_sheet_id = fields.Many2one('beesdoo.shift.sheet', string="Attendance Sheet")
  63. start_time = fields.Float(required=True)
  64. end_time = fields.Float(required=True)
  65. super_coop_id = fields.Many2one('res.users', string="Super Cooperative", domain=[('partner_id.super', '=', True)])
  66. duration = fields.Float(help="Duration in Hour")
  67. worker_nb = fields.Integer(string="Number of worker", help="Max number of worker for this task", default=1)
  68. worker_ids = fields.Many2many('res.partner', string="Recurrent worker assigned", domain=[('eater', '=', 'worker_eater'), ('working_mode', '=', 'regular')])
  69. remaining_worker = fields.Integer(compute="_get_remaining", store=True, string="Remaining Place")
  70. active = fields.Boolean(default=True)
  71. #For Kanban View Only
  72. color = fields.Integer('Color Index')
  73. worker_name = fields.Char(compute="_get_worker_name")
  74. #For calendar View
  75. start_date = fields.Datetime(compute="_get_fake_date", search="_dummy_search")
  76. end_date = fields.Datetime(compute="_get_fake_date", search="_dummy_search")
  77. def _get_utc_date(self, day, hour, minute):
  78. #Don't catch error since the error should be raise on the log as an error
  79. #because generate time with UTC timezone is worse than not generate them
  80. context_tz = timezone(self._context.get('tz') or self.env.user.tz)
  81. day_time = day.replace(hour=hour, minute=minute)
  82. day_local_time = context_tz.localize(day_time)
  83. day_utc_time = day_local_time.astimezone(UTC)
  84. return day_utc_time
  85. @api.depends('start_time', 'end_time')
  86. def _get_fake_date(self):
  87. today = self._context.get('visualize_date', get_first_day_of_week())
  88. today = datetime.strptime(today, '%Y-%m-%d')
  89. for rec in self:
  90. # Find the day of this task template 'rec'.
  91. day = today + timedelta(days=rec.day_nb_id.number - 1)
  92. # Compute the beginning and ending time according to the
  93. # context timezone.
  94. h_begin, m_begin = floatime_to_hour_minute(rec.start_time)
  95. h_end, m_end = floatime_to_hour_minute(rec.end_time)
  96. rec.start_date = self._get_utc_date(day, h_begin, m_begin)
  97. rec.end_date = self._get_utc_date(day, h_end, m_end)
  98. def _dummy_search(self, operator, value):
  99. return []
  100. @api.depends('worker_ids', 'worker_nb')
  101. def _get_remaining(self):
  102. for rec in self:
  103. rec.remaining_worker = rec.worker_nb - len(rec.worker_ids)
  104. @api.depends("worker_ids")
  105. def _get_worker_name(self):
  106. for rec in self:
  107. rec.worker_name = ','.join(rec.worker_ids.mapped('display_name'))
  108. @api.constrains('worker_nb', 'worker_ids')
  109. def _nb_worker_max(self):
  110. for rec in self:
  111. if len(rec.worker_ids) > rec.worker_nb:
  112. raise UserError(_('You cannot assign more workers than the maximal number defined on template.'))
  113. @api.onchange('start_time', 'end_time')
  114. def _get_duration(self):
  115. if self.start_time and self.end_time:
  116. self.duration = self.end_time - self.start_time
  117. @api.onchange('duration')
  118. def _set_duration(self):
  119. if self.start_time:
  120. self.end_time = self.start_time +self.duration
  121. def _generate_task_day(self):
  122. tasks = self.env['beesdoo.shift.shift']
  123. for rec in self:
  124. for i in xrange(0, rec.worker_nb):
  125. worker_id = rec.worker_ids[i] if len(rec.worker_ids) > i else False
  126. #remove worker in holiday and temporary exempted
  127. if worker_id and worker_id.cooperative_status_ids:
  128. status = worker_id.cooperative_status_ids[0]
  129. if status.holiday_start_time and status.holiday_end_time and \
  130. status.holiday_start_time <= rec.start_date[:10] and status.holiday_end_time >= rec.end_date[:10]:
  131. worker_id = False
  132. if status.temporary_exempt_start_date and status.temporary_exempt_end_date and \
  133. status.temporary_exempt_start_date <= rec.start_date[:10] and status.temporary_exempt_end_date >= rec.end_date[:10]:
  134. worker_id = False
  135. tasks |= tasks.create({
  136. 'name' : "[%s] %s %s (%s - %s) [%s]" % (
  137. rec.start_date[:10],
  138. rec.planning_id.name,
  139. rec.day_nb_id.name,
  140. float_to_time(rec.start_time),
  141. float_to_time(rec.end_time),
  142. i,
  143. ),
  144. 'task_template_id' : rec.id,
  145. 'task_type_id' : rec.task_type_id.id,
  146. 'super_coop_id': rec.super_coop_id.id,
  147. 'worker_id' : worker_id and worker_id.id or False,
  148. 'is_regular': True if worker_id else False,
  149. 'start_time' : rec.start_date,
  150. 'end_time' : rec.end_date,
  151. 'state': 'open',
  152. })
  153. return tasks
  154. @api.onchange('worker_ids')
  155. def check_for_multiple_shifts(self):
  156. original_ids = {worker.id for worker in self._origin.worker_ids}
  157. warnings = []
  158. for worker in self.worker_ids:
  159. if worker.id not in original_ids:
  160. shifts = [shift.name for shift in worker.subscribed_shift_ids if shift.id != self.id]
  161. if shifts:
  162. warnings.append(
  163. worker.name + _(' is already assigned to ') + ", ".join(shifts))
  164. if warnings:
  165. return {
  166. 'warning': {
  167. 'title': _("Warning"),
  168. 'message': "\n".join(warnings)
  169. }
  170. }