|
|
@@ -2,6 +2,7 @@
|
|
|
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
|
|
|
|
|
import logging
|
|
|
+import pytz
|
|
|
from datetime import datetime, date
|
|
|
from dateutil.relativedelta import relativedelta
|
|
|
from odoo import api, fields, models, _
|
|
|
@@ -413,7 +414,24 @@ class HrEfficiency(models.Model):
|
|
|
total_non_billable = 0.0
|
|
|
|
|
|
for slot in planning_slots:
|
|
|
- hours = slot.allocated_hours or 0.0
|
|
|
+ # Use the same logic as Odoo Planning to calculate allocated hours
|
|
|
+ if slot.start_datetime and slot.end_datetime and slot.resource_id:
|
|
|
+ # Calculate the intersection between slot and working intervals
|
|
|
+ start_utc = pytz.utc.localize(slot.start_datetime)
|
|
|
+ end_utc = pytz.utc.localize(slot.end_datetime)
|
|
|
+
|
|
|
+ # Get working intervals for the resource
|
|
|
+ resource_work_intervals, calendar_work_intervals = slot.resource_id._get_valid_work_intervals(
|
|
|
+ start_utc, end_utc, calendars=slot.company_id.resource_calendar_id
|
|
|
+ )
|
|
|
+
|
|
|
+ # Calculate duration over working periods
|
|
|
+ hours = slot._get_duration_over_period(
|
|
|
+ start_utc, end_utc,
|
|
|
+ resource_work_intervals, calendar_work_intervals, has_allocated_hours=False
|
|
|
+ )
|
|
|
+ else:
|
|
|
+ hours = slot.allocated_hours or 0.0
|
|
|
|
|
|
# Check if the slot is linked to a billable project
|
|
|
if slot.project_id and slot.project_id.allow_billable:
|