diff --git a/fusion_planning/__init__.py b/fusion_planning/__init__.py index 153a9e31..9e5827f9 100644 --- a/fusion_planning/__init__.py +++ b/fusion_planning/__init__.py @@ -1,2 +1,3 @@ # -*- coding: utf-8 -*- from . import controllers +from . import models diff --git a/fusion_planning/__manifest__.py b/fusion_planning/__manifest__.py index 20c04519..1cc9e100 100644 --- a/fusion_planning/__manifest__.py +++ b/fusion_planning/__manifest__.py @@ -5,7 +5,7 @@ { 'name': 'Fusion Planning', - 'version': '19.0.1.0.2', + 'version': '19.0.1.1.0', 'category': 'Human Resources/Planning', 'summary': 'Fusion Clock bridge to Odoo Planning - employee schedule on the portal', 'description': """ @@ -26,6 +26,7 @@ Adds Odoo Planning to the Fusion Clock product family: 'fusion_clock', ], 'data': [ + 'views/planning_slot_views.xml', 'views/portal_schedule_templates.xml', 'views/portal_nav_inherit.xml', ], diff --git a/fusion_planning/models/__init__.py b/fusion_planning/models/__init__.py new file mode 100644 index 00000000..3d3d7a1f --- /dev/null +++ b/fusion_planning/models/__init__.py @@ -0,0 +1,2 @@ +# -*- coding: utf-8 -*- +from . import planning_slot diff --git a/fusion_planning/models/planning_slot.py b/fusion_planning/models/planning_slot.py new file mode 100644 index 00000000..8ef49295 --- /dev/null +++ b/fusion_planning/models/planning_slot.py @@ -0,0 +1,65 @@ +# -*- coding: utf-8 -*- +# Copyright 2026 Nexa Systems Inc. +# License OPL-1 (Odoo Proprietary License v1.0) + +from odoo import api, fields, models + + +class PlanningSlot(models.Model): + _inherit = 'planning.slot' + + # Bulk-create helper: when set on a NEW slot, the system also creates + # one identical copy of the shift for each of these resources. + # Combined with the recurrence config, this lets a manager schedule + # the same shift across many employees in a single Save. + x_fc_additional_resource_ids = fields.Many2many( + 'resource.resource', + 'fc_planning_slot_extra_resource_rel', + 'slot_id', + 'resource_id', + string='Apply Also To', + help="Also create this same shift for each of these employees. " + "Useful when scheduling the same shift across many people in one go.", + ) + + @api.model_create_multi + def create(self, vals_list): + # 1. Auto-publish: every new shift is born published so employees + # see it immediately. Manager keeps full control via the existing + # Publish/Unpublish buttons after the fact. + # 2. Multi-resource expansion: if a manager fills the Apply Also To + # field, build one extra vals dict per additional resource. + expanded_vals_list = [] + for vals in vals_list: + vals.setdefault('state', 'published') + + extra_ids = self._fc_pop_additional_resource_ids(vals) + primary_rid = vals.get('resource_id') + + expanded_vals_list.append(vals) + + for rid in extra_ids: + if rid == primary_rid: + continue + copy_vals = dict(vals) + copy_vals['resource_id'] = rid + copy_vals.pop('x_fc_additional_resource_ids', None) + expanded_vals_list.append(copy_vals) + + return super().create(expanded_vals_list) + + @api.model + def _fc_pop_additional_resource_ids(self, vals): + """Pop and flatten the m2m vals into a plain list of resource ids.""" + cmds = vals.pop('x_fc_additional_resource_ids', None) or [] + ids = [] + for cmd in cmds: + # Odoo m2m commands: (6, 0, ids) replace, (4, id) link, (1, id, vals) update + if isinstance(cmd, (list, tuple)): + if cmd[0] == 6 and len(cmd) >= 3: + ids.extend(cmd[2]) + elif cmd[0] == 4 and len(cmd) >= 2: + ids.append(cmd[1]) + elif isinstance(cmd, int): + ids.append(cmd) + return ids diff --git a/fusion_planning/views/planning_slot_views.xml b/fusion_planning/views/planning_slot_views.xml new file mode 100644 index 00000000..818b3572 --- /dev/null +++ b/fusion_planning/views/planning_slot_views.xml @@ -0,0 +1,22 @@ + + + + + + planning.slot.form.inherit.fusion_planning + planning.slot + + + + + + + + +