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>
66 lines
2.5 KiB
Python
66 lines
2.5 KiB
Python
# -*- 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
|