feat(fusion_planning): auto-publish new shifts + bulk-assign to many employees
Two manager-side time savers on the Add Shift dialog: 1. Auto-publish on create Override planning.slot.create() to default state='published' for every new shift (was: 'draft', requiring a separate Publish step per slot — painful with recurrence which can generate dozens at a time). Recurrency-generated copies inherit the parent slot's state, so a single recurring shift now publishes the whole series in one save. Manager can still pass state='draft' explicitly to opt out. 2. Apply Also To (multi-resource bulk create) New x_fc_additional_resource_ids m2m on planning.slot. When set, create() splits the vals into one slot per additional resource (deduped against the primary). Combined with recurrence, picking N employees and a date range now creates the full N x M shift matrix in a single Save instead of N manual repeats. Field appears in the Add Shift dialog under Role, hidden once the slot is saved (it's a create-time helper, not ongoing data), and gated to planning.group_planning_manager. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1,2 +1,3 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from . import controllers
|
||||
from . import models
|
||||
|
||||
@@ -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',
|
||||
],
|
||||
|
||||
2
fusion_planning/models/__init__.py
Normal file
2
fusion_planning/models/__init__.py
Normal file
@@ -0,0 +1,2 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from . import planning_slot
|
||||
65
fusion_planning/models/planning_slot.py
Normal file
65
fusion_planning/models/planning_slot.py
Normal file
@@ -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
|
||||
22
fusion_planning/views/planning_slot_views.xml
Normal file
22
fusion_planning/views/planning_slot_views.xml
Normal file
@@ -0,0 +1,22 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
|
||||
<!-- Add "Apply Also To" m2m field to the Add Shift dialog so a
|
||||
manager can create the same shift for many employees in one save. -->
|
||||
<record id="planning_view_form_inherit_fusion_planning" model="ir.ui.view">
|
||||
<field name="name">planning.slot.form.inherit.fusion_planning</field>
|
||||
<field name="model">planning.slot</field>
|
||||
<field name="inherit_id" ref="planning.planning_view_form"/>
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr="//field[@name='role_id']" position="after">
|
||||
<field name="x_fc_additional_resource_ids"
|
||||
widget="many2many_tags"
|
||||
options="{'no_create': True, 'no_quick_create': True}"
|
||||
placeholder="Pick more employees to apply this shift to"
|
||||
invisible="id"
|
||||
groups="planning.group_planning_manager"/>
|
||||
</xpath>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
</odoo>
|
||||
Reference in New Issue
Block a user