res_partner.py 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173
  1. # -*- coding: utf-8 -*-
  2. # (c) 2016 Alfredo de la Fuente - AvanzOSC
  3. # License AGPL-3 - See http://www.gnu.org/licenses/agpl-3.0.html
  4. from openerp import models, fields, api, exceptions, _
  5. from dateutil.relativedelta import relativedelta
  6. class ResPartner(models.Model):
  7. _inherit = 'res.partner'
  8. def _generate_calendar(self, year):
  9. calendar_obj = self.env['res.partner.calendar']
  10. day_vals = []
  11. start_date = fields.Date.from_string('{}-01-01'.format(year))
  12. end_date = fields.Date.from_string('{}-12-31'.format(year))
  13. while start_date <= end_date:
  14. day_vals.append((0, 0, {'partner': self.id, 'date': start_date}))
  15. start_date = (fields.Date.from_string(str(start_date)) +
  16. (relativedelta(days=1)))
  17. cond = [('partner', '=', self.id),
  18. ('year', '=', year)]
  19. calendar = calendar_obj.search(cond, limit=1)
  20. if calendar:
  21. calendar.dates.unlink()
  22. calendar.write({'dates': day_vals})
  23. else:
  24. calendar_vals = {
  25. 'partner': self.id,
  26. 'year': year,
  27. 'dates': day_vals,
  28. }
  29. calendar = calendar_obj.create(calendar_vals)
  30. self._put_contract_in_partner_calendar_day(year)
  31. def _put_contract_in_partner_calendar_day(self, year):
  32. contract_obj = self.env['hr.contract']
  33. date_begin = '{}-01-01'.format(year)
  34. cond = [('type_id', '=',
  35. self.env.ref('hr_contract.hr_contract_type_emp').id),
  36. ('employee_id', '=', self.employee_id.id),
  37. '|', ('date_end', '=', False),
  38. ('date_end', '>=', date_begin)]
  39. contracts = contract_obj.search(cond)
  40. for contract in contracts:
  41. date_start = '{}-01-01'.format(year)
  42. if contract.date_start > date_start:
  43. date_start = contract.date_start
  44. date_end = '{}-12-31'.format(year)
  45. if contract.date_end and contract.date_end < date_end:
  46. date_end = contract.date_end
  47. cond = [('partner', '=', self.id),
  48. ('date', '>=', date_start),
  49. ('date', '<=', date_end)]
  50. days = self.env['res.partner.calendar.day'].search(cond)
  51. days.write({'contract': contract.id})
  52. def _put_estimated_hours_in_calendar(self, year, contract):
  53. partner_calendar_day_obj = self.env['res.partner.calendar.day']
  54. for attendance in contract.working_hours.attendance_ids:
  55. cond = [('partner', '=', contract.partner.id),
  56. ('year', '=', year),
  57. ('weekday', '=', attendance.dayofweek)]
  58. if attendance.date_from:
  59. cond.append(('date', '>=', attendance.date_from))
  60. elif contract.date_start:
  61. cond.append(('date', '>=', contract.date_start))
  62. if contract.date_end:
  63. cond.append(('date', '<=', contract.date_end))
  64. else:
  65. cond.append(('date', '<=', "{}-12-31".format(year)))
  66. partner_calendar_days = partner_calendar_day_obj.search(cond)
  67. if partner_calendar_days:
  68. for day in partner_calendar_days:
  69. hours = attendance.hour_to - attendance.hour_from
  70. day.estimated_hours = day.estimated_hours + hours
  71. def _generate_festives_in_calendar(self, year, calendar):
  72. calendar_obj = self.env['res.partner.calendar']
  73. calendar_day_obj = self.env['res.partner.calendar.day']
  74. for line in calendar.lines:
  75. date = fields.Datetime.from_string(line.date).date()
  76. new_date = str(year) + '-' + str(date.month) + '-' + str(date.day)
  77. cond = [('partner', '=', self.id),
  78. ('year', '=', year)]
  79. partner_calendar = calendar_obj.search(cond, limit=1)
  80. if not partner_calendar:
  81. raise exceptions.Warning(
  82. _('The calendar %s was not found, for employee %s')
  83. % (str(year), self.name))
  84. cond = [('partner', '=', self.id),
  85. ('date', '=', new_date)]
  86. calendar_day = calendar_day_obj.search(cond, limit=1)
  87. if not calendar_day:
  88. raise exceptions.Warning(
  89. _('The day %s was not found in the calendar %s, for'
  90. ' employee %s') % (new_date, str(year), self.name))
  91. calendar_day.write({'estimated_hours': 0,
  92. 'festive': True,
  93. 'absence_type': line.absence_type.id,
  94. 'calendar_holiday_day': line.id,
  95. 'absence_type_from_employee_contract':
  96. line.absence_type.id})
  97. class ResPartnerCalendar(models.Model):
  98. _name = 'res.partner.calendar'
  99. _inherit = ['mail.thread', 'ir.needaction_mixin']
  100. _description = 'Employee calendar'
  101. _rec_name = 'year'
  102. partner = fields.Many2one(
  103. comodel_name='res.partner', string='Partner', ondelete='cascade')
  104. year = fields.Integer(string='Year', size=4)
  105. dates = fields.One2many(
  106. comodel_name='res.partner.calendar.day', inverse_name='calendar',
  107. string='Calendar dates')
  108. @api.model
  109. def create(self, values):
  110. res = super(ResPartnerCalendar, self).create(values)
  111. if values.get('partner', False):
  112. res.message_subscribe([values.get('partner')])
  113. return res
  114. @api.multi
  115. def write(self, values):
  116. res = super(ResPartnerCalendar, self).write(values)
  117. if values.get('partner', False):
  118. self.message_subscribe([values.get('partner')])
  119. return res
  120. class ResPartnerCalendarDay(models.Model):
  121. _name = 'res.partner.calendar.day'
  122. _description = 'Employee calendar day'
  123. _rec_name = 'date'
  124. @api.depends('date')
  125. def _compute_weekday(self):
  126. for day in self:
  127. date = fields.Date.from_string(day.date)
  128. day.year = date.year
  129. day.weekday = str(date.weekday())
  130. calendar = fields.Many2one(
  131. comodel_name='res.partner.calendar', string='Calendar',
  132. ondelete='cascade')
  133. partner = fields.Many2one(
  134. comodel_name='res.partner', related='calendar.partner',
  135. string='Partner', store=True, select=True)
  136. date = fields.Date(string='Date', select=True)
  137. year = fields.Integer(
  138. string='year', compute='_compute_weekday', store=True)
  139. weekday = fields.Selection(
  140. [('0', 'Monday'),
  141. ('1', 'Tuesday'),
  142. ('2', 'Wednesday'),
  143. ('3', 'Thursday'),
  144. ('4', 'Friday'),
  145. ('5', 'Saturday'),
  146. ('6', 'Sunday')],
  147. string='Weekday', compute='_compute_weekday', store=True)
  148. contract = fields.Many2one(
  149. comodel_name='hr.contract', string='Partner contract')
  150. estimated_hours = fields.Float(string='Estimated hours', default=0.0)
  151. real_hours = fields.Float(string='Real hours', default=0.0)
  152. festive = fields.Boolean(string='Festive', default=False)
  153. absence_type = fields.Many2one(
  154. comodel_name='hr.holidays.status', string='Absence type')
  155. absence_type_from_employee_contract = fields.Many2one(
  156. comodel_name='hr.holidays.status', string='Absence type')
  157. calendar_holiday_day = fields.Many2one(
  158. comodel_name='calendar.holiday.day', string='Calendar holiday day')