# -*- coding: utf-8 -*- # Copyright 2026 Nexa Systems Inc. # License OPL-1 (Odoo Proprietary License v1.0) # # One-time port of Odoo Enterprise Planning data into the native Fusion Clock # models, so a deployment that previously used the `planning` bridge keeps all # its roles, employee role assignments and shifts after `planning` / # `fusion_planning` are removed. # # Guarded: a no-op on Community / fresh installs where planning data is absent. # Idempotent: a marker param stops it re-running. import logging from odoo import api, SUPERUSER_ID _logger = logging.getLogger(__name__) def migrate(cr, version): """Drop the legacy one-shift-per-day constraint and attempt the planning -> native port. The port (fusion.clock.schedule._fclk_port_planning_data) is marker-guarded and self-defers: because fusion_clock doesn't depend on planning, planning's ORM may not be loaded here, in which case the deploy shell step finishes the port. Lives in the model so it's unit-testable.""" env = api.Environment(cr, SUPERUSER_ID, {}) # Phase B drops the hard one-shift-per-day uniqueness so split/open shifts # are allowed. Odoo drops removed declarative constraints on upgrade, but be # explicit so the upgrade can never leave the old constraint behind. cr.execute( "ALTER TABLE fusion_clock_schedule " "DROP CONSTRAINT IF EXISTS fusion_clock_schedule_employee_date_unique") counts = env['fusion.clock.schedule'].sudo()._fclk_port_planning_data() if counts.get('deferred'): _logger.info("Fusion Clock: planning models not loaded during migration; " "data will be ported by the deploy shell step.") else: _logger.info("Fusion Clock: planning -> native migration: %s", counts)