129 lines
4.3 KiB
Python
129 lines
4.3 KiB
Python
# -*- coding: utf-8 -*-
|
|
|
|
import logging
|
|
from odoo import api, SUPERUSER_ID
|
|
|
|
_logger = logging.getLogger(__name__)
|
|
|
|
|
|
def post_init_hook(env):
|
|
"""
|
|
Post-installation hook to migrate existing ratings from 0-3 scale to 0-5 scale.
|
|
|
|
Migration mapping:
|
|
- 0 → 0 (no rating)
|
|
- 1 → 3 (poor becomes 3 stars)
|
|
- 2 → 4 (okay becomes 4 stars)
|
|
- 3 → 5 (good becomes 5 stars)
|
|
|
|
Args:
|
|
env: Odoo environment
|
|
"""
|
|
_logger.info("Starting rating migration from 0-3 scale to 0-5 scale...")
|
|
|
|
cr = env.cr
|
|
|
|
# Check if we're running in test mode by checking if commit is forbidden
|
|
test_mode = False
|
|
try:
|
|
# Try to check if we're in test mode by looking at the cursor
|
|
test_mode = hasattr(cr, '__class__') and 'TestCursor' in cr.__class__.__name__
|
|
except:
|
|
test_mode = False
|
|
|
|
try:
|
|
# Define the migration mapping
|
|
migration_mapping = {
|
|
0: 0, # No rating stays 0
|
|
1: 3, # Poor (1) becomes 3 stars
|
|
2: 4, # Okay (2) becomes 4 stars
|
|
3: 5, # Good (3) becomes 5 stars
|
|
}
|
|
|
|
# Get all ratings that need migration (values 0-3)
|
|
# We need to use SQL to avoid triggering constraints during migration
|
|
cr.execute("""
|
|
SELECT id, rating
|
|
FROM rating_rating
|
|
WHERE rating IN (0, 1, 2, 3)
|
|
""")
|
|
|
|
ratings_to_migrate = cr.fetchall()
|
|
total_count = len(ratings_to_migrate)
|
|
|
|
if total_count == 0:
|
|
_logger.info("No ratings found to migrate. Migration complete.")
|
|
return
|
|
|
|
_logger.info(f"Found {total_count} ratings to migrate.")
|
|
|
|
# Migrate ratings in batches for better performance
|
|
batch_size = 1000
|
|
migrated_count = 0
|
|
error_count = 0
|
|
|
|
for i in range(0, total_count, batch_size):
|
|
batch = ratings_to_migrate[i:i + batch_size]
|
|
|
|
try:
|
|
# Use SQL UPDATE for better performance and to avoid constraint issues
|
|
for rating_id, old_value in batch:
|
|
# Only migrate if the value is in the old scale (0-3)
|
|
if old_value in migration_mapping:
|
|
new_value = migration_mapping[old_value]
|
|
|
|
# Update using SQL to bypass ORM constraints temporarily
|
|
cr.execute("""
|
|
UPDATE rating_rating
|
|
SET rating = %s
|
|
WHERE id = %s AND rating = %s
|
|
""", (new_value, rating_id, old_value))
|
|
|
|
migrated_count += 1
|
|
|
|
# Only commit if not in test mode
|
|
if not test_mode:
|
|
cr.commit()
|
|
|
|
_logger.info(f"Migrated batch: {migrated_count}/{total_count} ratings")
|
|
|
|
except Exception as batch_error:
|
|
_logger.error(f"Error migrating batch: {batch_error}")
|
|
error_count += len(batch)
|
|
# Only rollback if not in test mode
|
|
if not test_mode:
|
|
cr.rollback()
|
|
continue
|
|
|
|
# Final commit (only if not in test mode)
|
|
if not test_mode:
|
|
cr.commit()
|
|
|
|
# Log final results
|
|
_logger.info(f"Rating migration complete!")
|
|
_logger.info(f"Successfully migrated: {migrated_count} ratings")
|
|
|
|
if error_count > 0:
|
|
_logger.warning(f"Failed to migrate: {error_count} ratings")
|
|
|
|
# Verify migration results
|
|
cr.execute("""
|
|
SELECT COUNT(*)
|
|
FROM rating_rating
|
|
WHERE rating > 0 AND rating < 1
|
|
""")
|
|
invalid_count = cr.fetchone()[0]
|
|
|
|
if invalid_count > 0:
|
|
_logger.warning(f"Found {invalid_count} ratings with invalid values after migration")
|
|
|
|
_logger.info("Rating migration process finished.")
|
|
|
|
except Exception as e:
|
|
_logger.error(f"Critical error during rating migration: {e}")
|
|
# Only rollback if not in test mode
|
|
if not test_mode:
|
|
cr.rollback()
|
|
_logger.error("Migration rolled back due to critical error.")
|
|
raise
|