planning_slot.py 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869
  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_real_working_days_count',
  22. store=True,
  23. )
  24. @api.depends('start_datetime', 'end_datetime', 'resource_id')
  25. def _compute_real_working_days_count(self):
  26. slots_per_calendar = defaultdict(set)
  27. planned_dates_per_calendar_id = defaultdict(lambda: (datetime.max, datetime.min))
  28. for slot in self:
  29. if not slot.employee_id:
  30. slot.real_working_days_count = 0
  31. continue
  32. slots_per_calendar[slot.resource_id.calendar_id].add(slot.id)
  33. datetime_begin, datetime_end = planned_dates_per_calendar_id[slot.resource_id.calendar_id.id]
  34. start_datetime = slot.start_datetime
  35. first_day_of_month = datetime(start_datetime.year, start_datetime.month, 1, 0, 0, 0)
  36. last_day = calendar.monthrange(start_datetime.year, start_datetime.month)[1]
  37. last_day_of_month = datetime(start_datetime.year, start_datetime.month, last_day, 23, 59, 59)
  38. datetime_begin = min(datetime_begin, first_day_of_month)
  39. datetime_end = max(datetime_end, last_day_of_month)
  40. planned_dates_per_calendar_id[slot.resource_id.calendar_id.id] = datetime_begin, datetime_end
  41. for calendar_slot, slot_ids in slots_per_calendar.items():
  42. slots = self.env['planning.slot'].browse(list(slot_ids))
  43. if not calendar_slot:
  44. slots.real_working_days_count = 0
  45. continue
  46. datetime_begin, datetime_end = planned_dates_per_calendar_id[calendar_slot.id]
  47. datetime_begin = timezone_datetime(datetime_begin)
  48. datetime_end = timezone_datetime(datetime_end)
  49. resources = slots.resource_id
  50. day_total = calendar_slot._get_resources_day_total(datetime_begin, datetime_end, resources)
  51. _logger.info('DAY TOTAL %s', day_total)
  52. intervals = calendar_slot._work_intervals_batch(datetime_begin, datetime_end, resources)
  53. for slot in slots:
  54. slot.real_working_days_count = calendar_slot._get_days_data(
  55. intervals[slot.resource_id.id] & Intervals([(
  56. timezone_datetime(first_day_of_month),
  57. timezone_datetime(last_day_of_month),
  58. self.env['resource.calendar.attendance']
  59. )]),
  60. day_total[slot.resource_id.id]
  61. )['days']