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.

117 lines
4.7 KiB

  1. # -*- coding: utf-8 -*-
  2. from openerp import models, fields, api, _
  3. from openerp.exceptions import UserError
  4. from pytz import 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())
  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. name = fields.Char()
  30. task_template_ids = fields.One2many('beesdoo.shift.template', 'planning_id')
  31. class TaskTemplate(models.Model):
  32. _name = 'beesdoo.shift.template'
  33. name = fields.Char(required=True)
  34. planning_id = fields.Many2one('beesdoo.shift.planning', required=True)
  35. day_nb_id = fields.Many2one('beesdoo.shift.daynumber', string='Day', required=True)
  36. task_type_id = fields.Many2one('beesdoo.shift.type', string="Type")
  37. start_time = fields.Float(required=True)
  38. end_time = fields.Float(required=True)
  39. duration = fields.Float(help="Duration in Hour")
  40. worker_nb = fields.Integer(string="Number of worker", help="Max number of worker for this task", default=1)
  41. worker_ids = fields.Many2many('res.partner', string="Recurrent worker assigned", domain=[('eater', '=', 'worker_eater')])
  42. remaining_worker = fields.Integer(compute="_get_remaining", store=True, string="Remaining Place")
  43. active = fields.Boolean(default=True)
  44. #For Kanban View Only
  45. color = fields.Integer('Color Index')
  46. worker_name = fields.Char(compute="_get_worker_name")
  47. #For calendar View
  48. start_date = fields.Datetime(compute="_get_fake_date", search="_dummy_search")
  49. end_date = fields.Datetime(compute="_get_fake_date", search="_dummy_search")
  50. @api.depends('start_time', 'end_time')
  51. def _get_fake_date(self):
  52. today = datetime.strptime(self._context.get('visualize_date'), '%Y-%m-%d') if self._context.get('visualize_date') else get_first_day_of_week()
  53. for rec in self:
  54. day = today + timedelta(days=rec.day_nb_id.number - 1)
  55. h_begin, m_begin = floatime_to_hour_minute(rec.start_time)
  56. h_end, m_end = floatime_to_hour_minute(rec.end_time)
  57. rec.start_date = fields.Datetime.context_timestamp(self, day).replace(hour=h_begin, minute=m_begin, second=0).astimezone(UTC)
  58. rec.end_date = fields.Datetime.context_timestamp(self, day).replace(hour=h_end, minute=m_end, second=0).astimezone(UTC)
  59. def _dummy_search(self, operator, value):
  60. return []
  61. @api.depends('worker_ids', 'worker_nb')
  62. def _get_remaining(self):
  63. for rec in self:
  64. rec.remaining_worker = rec.worker_nb - len(rec.worker_ids)
  65. @api.depends("worker_ids")
  66. def _get_worker_name(self):
  67. for rec in self:
  68. rec.worker_name = ','.join(rec.worker_ids.mapped('display_name'))
  69. @api.constrains('worker_nb', 'worker_ids')
  70. def _nb_worker_max(self):
  71. for rec in self:
  72. if len(rec.worker_ids) > rec.worker_nb:
  73. raise UserError(_('you cannot assign more worker then the number maximal define on the template'))
  74. @api.onchange('start_time', 'end_time')
  75. def _get_duration(self):
  76. if self.start_time and self.end_time:
  77. self.duration = self.end_time - self.start_time
  78. @api.onchange('duration')
  79. def _set_duration(self):
  80. if self.start_time:
  81. self.end_time = self.start_time +self.duration
  82. def _generate_task_day(self):
  83. tasks = self.env['beesdoo.shift.shift']
  84. for rec in self:
  85. for i in xrange(0, rec.worker_nb):
  86. tasks |= tasks.create({
  87. 'name' : "%s (%s) - (%s) [%s]" % (rec.name, float_to_time(rec.start_time), float_to_time(rec.end_time), i),
  88. 'task_template_id' : rec.id,
  89. 'task_type_id' : rec.task_type_id.id,
  90. 'worker_id' : rec.worker_ids[i].id if len(rec.worker_ids) > i else False,
  91. 'start_time' : rec.start_date,
  92. 'end_time' : rec.end_date,
  93. })
  94. return tasks