planning_slot.py 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657
  1. import calendar
  2. from collections import defaultdict
  3. from datetime import date, datetime, timedelta, time
  4. from dateutil.relativedelta import relativedelta
  5. import logging
  6. import pytz
  7. import uuid
  8. from math import modf
  9. from random import randint
  10. from odoo import api, fields, models, _
  11. from odoo.addons.resource.models.resource import Intervals, sum_intervals, string_to_datetime
  12. from odoo.addons.resource.models.resource_mixin import timezone_datetime
  13. from odoo.exceptions import UserError, AccessError
  14. from odoo.osv import expression
  15. from odoo.tools import DEFAULT_SERVER_DATETIME_FORMAT, float_utils, format_datetime
  16. _logger = logging.getLogger(__name__)
  17. class PlanningSlot(models.Model):
  18. _inherit = 'planning.slot'
  19. real_working_days_count = fields.Float(
  20. string='Real Working Days',
  21. compute='_compute_working_days_count',
  22. store=True,
  23. help='Number of working days available in the month, regardless of slot start and end dates'
  24. )
  25. @api.depends('start_datetime', 'end_datetime', 'resource_id', 'company_id')
  26. def _compute_working_days_count(self):
  27. for slot in self:
  28. if not slot.start_datetime:
  29. slot.real_working_days_count = 0
  30. continue
  31. # Obtener el primer día del mes
  32. start_of_month = slot.start_datetime.replace(day=1, hour=0, minute=0, second=0)
  33. # Obtener el último día del mes
  34. end_of_month = (start_of_month + relativedelta(months=1, days=-1)).replace(hour=23, minute=59, second=59)
  35. # Obtener el calendario de trabajo
  36. calendar = slot.resource_id.calendar_id or slot.company_id.resource_calendar_id
  37. if not calendar:
  38. slot.real_working_days_count = 0
  39. continue
  40. # Calcular los días laborables del mes completo
  41. real_working_days = calendar.get_work_duration_data(
  42. timezone_datetime(start_of_month),
  43. timezone_datetime(end_of_month),
  44. compute_leaves=True
  45. )
  46. # El resultado viene en horas, lo convertimos a días
  47. slot.real_working_days_count = real_working_days['hours'] / calendar.hours_per_day