|
|
@@ -1,249 +0,0 @@
|
|
|
-# -*- coding: utf-8 -*-
|
|
|
-"""
|
|
|
-Migration script to integrate helpdesk.template with helpdesk.workflow.template
|
|
|
-
|
|
|
-This script migrates all helpdesk.template records to helpdesk.workflow.template,
|
|
|
-moving field_ids from template to workflow_template.
|
|
|
-"""
|
|
|
-import logging
|
|
|
-from odoo import api, SUPERUSER_ID
|
|
|
-
|
|
|
-_logger = logging.getLogger(__name__)
|
|
|
-
|
|
|
-
|
|
|
-def migrate(cr, version):
|
|
|
- """Migrate helpdesk.template to helpdesk.workflow.template"""
|
|
|
- try:
|
|
|
- env = api.Environment(cr, SUPERUSER_ID, {})
|
|
|
-
|
|
|
- _logger.info("=" * 80)
|
|
|
- _logger.info("Starting migration: helpdesk.template -> helpdesk.workflow.template")
|
|
|
- _logger.info("=" * 80)
|
|
|
-
|
|
|
- # 0. Verify pre-migration completed (workflow_template_id column exists)
|
|
|
- cr.execute("""
|
|
|
- SELECT column_name
|
|
|
- FROM information_schema.columns
|
|
|
- WHERE table_name = 'helpdesk_template_field'
|
|
|
- AND column_name = 'workflow_template_id'
|
|
|
- """)
|
|
|
- if not cr.fetchone():
|
|
|
- _logger.error("❌ Pre-migration not completed! workflow_template_id column does not exist.")
|
|
|
- _logger.error("Module update will fail. Please check pre-migration logs.")
|
|
|
- raise Exception("Pre-migration required: workflow_template_id column missing")
|
|
|
-
|
|
|
- _logger.info("✅ Pre-migration verified: workflow_template_id column exists")
|
|
|
-
|
|
|
- # 1. Get all helpdesk.template records
|
|
|
- templates = env['helpdesk.template'].search([])
|
|
|
- _logger.info(f"Found {len(templates)} template(s) to migrate")
|
|
|
-
|
|
|
- if not templates:
|
|
|
- _logger.info("No templates to migrate. Migration complete.")
|
|
|
- cr.commit()
|
|
|
- return
|
|
|
-
|
|
|
- migrated_count = 0
|
|
|
- skipped_count = 0
|
|
|
- error_count = 0
|
|
|
-
|
|
|
- # 2. For each template, migrate to workflow template
|
|
|
- for template in templates:
|
|
|
- try:
|
|
|
- _logger.info(f"\nProcessing template: {template.name} (ID: {template.id})")
|
|
|
-
|
|
|
- # First, check which teams use this template
|
|
|
- teams_using_template = env['helpdesk.team'].search([
|
|
|
- ('template_id', '=', template.id)
|
|
|
- ])
|
|
|
-
|
|
|
- _logger.info(f" Found {len(teams_using_template)} team(s) using this template")
|
|
|
-
|
|
|
- # Group teams by whether they have workflow_template_id or not
|
|
|
- teams_with_workflow = teams_using_template.filtered('workflow_template_id')
|
|
|
- teams_without_workflow = teams_using_template.filtered(lambda t: not t.workflow_template_id)
|
|
|
-
|
|
|
- workflow_template = None
|
|
|
-
|
|
|
- # Strategy 1: If teams have workflow_template_id, migrate fields to their existing workflow
|
|
|
- if teams_with_workflow:
|
|
|
- # Check if all teams use the same workflow_template_id
|
|
|
- workflow_ids = teams_with_workflow.mapped('workflow_template_id.id')
|
|
|
- unique_workflows = set(workflow_ids)
|
|
|
-
|
|
|
- if len(unique_workflows) == 1:
|
|
|
- # All teams use the same workflow template - migrate fields there
|
|
|
- workflow_template = teams_with_workflow[0].workflow_template_id
|
|
|
- _logger.info(f" All teams use workflow template '{workflow_template.name}' (ID: {workflow_template.id})")
|
|
|
- _logger.info(f" Migrating fields from template to existing workflow template...")
|
|
|
- else:
|
|
|
- # Teams use different workflow templates - use the most common one
|
|
|
- from collections import Counter
|
|
|
- workflow_counter = Counter(workflow_ids)
|
|
|
- most_common_workflow_id = workflow_counter.most_common(1)[0][0]
|
|
|
- workflow_template = env['helpdesk.workflow.template'].browse(most_common_workflow_id)
|
|
|
- _logger.info(f" Teams use different workflow templates. Using most common: '{workflow_template.name}' (ID: {workflow_template.id})")
|
|
|
- _logger.info(f" Migrating fields from template to this workflow template...")
|
|
|
-
|
|
|
- # Strategy 2: If no teams have workflow_template_id, create/find workflow template
|
|
|
- if not workflow_template:
|
|
|
- # Check if a workflow template with the same name already exists
|
|
|
- workflow_template = env['helpdesk.workflow.template'].search([
|
|
|
- ('name', '=', template.name)
|
|
|
- ], limit=1)
|
|
|
-
|
|
|
- if workflow_template:
|
|
|
- _logger.info(f" Workflow template '{workflow_template.name}' already exists (ID: {workflow_template.id})")
|
|
|
- _logger.info(f" Migrating fields from template into existing workflow template...")
|
|
|
- else:
|
|
|
- # Create new workflow template
|
|
|
- workflow_template = env['helpdesk.workflow.template'].create({
|
|
|
- 'name': template.name,
|
|
|
- 'description': template.description or False,
|
|
|
- 'active': template.active,
|
|
|
- })
|
|
|
- _logger.info(f" Created new workflow template: {workflow_template.name} (ID: {workflow_template.id})")
|
|
|
-
|
|
|
- # 3. Migrate field_ids from template to workflow_template
|
|
|
- field_count = 0
|
|
|
- for field in template.field_ids:
|
|
|
- try:
|
|
|
- # Check if field already exists in workflow template
|
|
|
- existing_field = env['helpdesk.template.field'].search([
|
|
|
- ('workflow_template_id', '=', workflow_template.id),
|
|
|
- ('field_id', '=', field.field_id.id)
|
|
|
- ], limit=1)
|
|
|
-
|
|
|
- if existing_field:
|
|
|
- _logger.warning(f" Field '{field.field_id.name}' already exists in workflow template. Skipping.")
|
|
|
- continue
|
|
|
-
|
|
|
- # Update field to point to workflow_template_id instead of template_id
|
|
|
- field.write({
|
|
|
- 'template_id': False, # Clear legacy reference
|
|
|
- 'workflow_template_id': workflow_template.id, # Set new reference
|
|
|
- })
|
|
|
- field_count += 1
|
|
|
- _logger.info(f" Migrated field: {field.field_id.name}")
|
|
|
- except Exception as e:
|
|
|
- _logger.error(f" Error migrating field {field.id}: {e}", exc_info=True)
|
|
|
- error_count += 1
|
|
|
- continue
|
|
|
-
|
|
|
- _logger.info(f" Migrated {field_count} field(s) to workflow template")
|
|
|
-
|
|
|
- # 4. Update teams that use this template
|
|
|
- team_count = 0
|
|
|
- for team in teams_using_template:
|
|
|
- try:
|
|
|
- # If team doesn't have workflow_template_id, assign it
|
|
|
- if not team.workflow_template_id:
|
|
|
- team.write({
|
|
|
- 'workflow_template_id': workflow_template.id,
|
|
|
- 'template_id': False, # Clear legacy reference
|
|
|
- })
|
|
|
- team_count += 1
|
|
|
- _logger.info(f" Updated team: {team.name} (ID: {team.id}) - assigned workflow template")
|
|
|
- else:
|
|
|
- # Team already has workflow_template_id
|
|
|
- # If we migrated fields to a different workflow, update it
|
|
|
- if team.workflow_template_id.id != workflow_template.id:
|
|
|
- _logger.info(f" Team {team.name} had workflow '{team.workflow_template_id.name}', updating to '{workflow_template.name}'")
|
|
|
- team.write({
|
|
|
- 'workflow_template_id': workflow_template.id,
|
|
|
- 'template_id': False, # Clear legacy reference
|
|
|
- })
|
|
|
- team_count += 1
|
|
|
- else:
|
|
|
- # Same workflow template - just clear template_id
|
|
|
- team.write({
|
|
|
- 'template_id': False, # Clear legacy reference
|
|
|
- })
|
|
|
- _logger.info(f" Team {team.name} already uses workflow '{workflow_template.name}'. Cleared template_id only.")
|
|
|
- except Exception as e:
|
|
|
- _logger.error(f" Error updating team {team.id}: {e}", exc_info=True)
|
|
|
- error_count += 1
|
|
|
- continue
|
|
|
-
|
|
|
- _logger.info(f" Updated {team_count} team(s)")
|
|
|
-
|
|
|
- # 5. Regenerate forms for affected teams (skip in production if too many)
|
|
|
- teams_affected = env['helpdesk.team'].search([
|
|
|
- ('workflow_template_id', '=', workflow_template.id),
|
|
|
- ('use_website_helpdesk_form', '=', True)
|
|
|
- ])
|
|
|
-
|
|
|
- # Limit regeneration to avoid timeout in production
|
|
|
- max_teams_to_regenerate = 50
|
|
|
- if len(teams_affected) > max_teams_to_regenerate:
|
|
|
- _logger.warning(f" Too many teams ({len(teams_affected)}) to regenerate. Skipping automatic regeneration.")
|
|
|
- _logger.warning(f" Please regenerate forms manually or via cron.")
|
|
|
- else:
|
|
|
- for team in teams_affected:
|
|
|
- if team.website_form_view_id:
|
|
|
- try:
|
|
|
- team._regenerate_form_from_template()
|
|
|
- _logger.info(f" Regenerated form for team: {team.name}")
|
|
|
- except Exception as e:
|
|
|
- _logger.warning(f" Could not regenerate form for team {team.id}: {e}")
|
|
|
- # Don't fail migration if form regeneration fails
|
|
|
- continue
|
|
|
-
|
|
|
- migrated_count += 1
|
|
|
- _logger.info(f"✅ Successfully migrated template: {template.name}")
|
|
|
-
|
|
|
- except Exception as e:
|
|
|
- _logger.error(f"❌ Error migrating template {template.id} ({template.name}): {e}", exc_info=True)
|
|
|
- error_count += 1
|
|
|
- skipped_count += 1
|
|
|
- continue
|
|
|
-
|
|
|
- # 6. Summary
|
|
|
- _logger.info("\n" + "=" * 80)
|
|
|
- _logger.info("Migration Summary:")
|
|
|
- _logger.info(f" Templates processed: {len(templates)}")
|
|
|
- _logger.info(f" Successfully migrated: {migrated_count}")
|
|
|
- _logger.info(f" Skipped/Errors: {skipped_count}")
|
|
|
- _logger.info(f" Total errors: {error_count}")
|
|
|
- _logger.info("=" * 80)
|
|
|
-
|
|
|
- # 7. Verify migration
|
|
|
- remaining_templates = env['helpdesk.template'].search([])
|
|
|
- if remaining_templates:
|
|
|
- _logger.warning(f"⚠️ {len(remaining_templates)} template(s) still exist. They may have errors or were skipped.")
|
|
|
- else:
|
|
|
- _logger.info("✅ All templates migrated successfully")
|
|
|
-
|
|
|
- # Check for orphaned fields (fields with template_id but no workflow_template_id)
|
|
|
- orphaned_fields = env['helpdesk.template.field'].search([
|
|
|
- ('template_id', '!=', False),
|
|
|
- ('workflow_template_id', '=', False)
|
|
|
- ])
|
|
|
- if orphaned_fields:
|
|
|
- _logger.warning(f"⚠️ Found {len(orphaned_fields)} orphaned field(s) (have template_id but no workflow_template_id)")
|
|
|
- _logger.warning(f" These fields will need manual migration or will be cleaned up later.")
|
|
|
-
|
|
|
- # Commit only if we have successful migrations or no templates to migrate
|
|
|
- if migrated_count > 0 or len(templates) == 0:
|
|
|
- cr.commit()
|
|
|
- _logger.info("✅ Migration completed successfully")
|
|
|
- else:
|
|
|
- # If all templates failed, rollback but don't block module update
|
|
|
- # (data might be corrupted, but module structure is OK)
|
|
|
- _logger.error("⚠️ All templates failed to migrate. Rolling back data changes.")
|
|
|
- try:
|
|
|
- cr.rollback()
|
|
|
- except Exception:
|
|
|
- pass
|
|
|
- _logger.error("Module update will continue, but data migration needs manual intervention.")
|
|
|
-
|
|
|
- except Exception as e:
|
|
|
- _logger.error(f"❌ Critical error in migration: {e}", exc_info=True)
|
|
|
- try:
|
|
|
- cr.rollback()
|
|
|
- except Exception:
|
|
|
- pass
|
|
|
- # Don't raise - allow module update to complete even if migration fails
|
|
|
- # The module structure is OK, only data migration failed
|
|
|
- _logger.error("Migration failed but module update will continue. Please review logs and fix manually if needed.")
|
|
|
-
|