Files
Enofirm-Temp/odoo/upgrade_code/17.6-06-report-to-record.py
2026-09-18 13:55:25 +07:00

109 lines
4.1 KiB
Python

# -*- coding: utf-8 -*-
import re
from pathlib import Path
import logging
# Set up logging
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)
def upgrade(file_manager):
"""Convert <report> tags to <record model='ir.actions.report'> format in XML files."""
# Filter files to only XML files
files = [file for file in file_manager if file.path.suffix == ".xml"]
if not files:
logger.info("No XML files found to process")
return
# Regex pattern to match <report> tags (both self-closing and with content)
report_tag_re = re.compile(
r"""
<report\s+ # Opening <report tag with whitespace
([^>]*?) # Capture all attributes (non-greedy)
(?:/>|>.*?</report>) # Either self-closing or with closing tag
""",
re.VERBOSE | re.DOTALL,
)
def convert_report_to_record(match):
"""Convert report tag to record format."""
attributes_str = match.group(1).strip()
# Parse attributes using regex
attr_pattern = r'(\w+)=(["\'])(.*?)\2'
attributes = dict(re.findall(attr_pattern, attributes_str))
if not attributes:
return match.group(0) # Return original if no attributes found
# Extract id for the record
record_id = attributes.get('id', '')
if not record_id:
logger.warning("Found report tag without id attribute, skipping conversion")
return match.group(0)
# Map report attributes to record fields
field_mapping = {
'string': 'name',
'model': 'model',
'report_type': 'report_type',
'name': 'report_name',
'file': 'report_file',
'attachment_use': 'attachment_use',
'print_report_name': 'print_report_name',
'binding_model_id': 'binding_model_id',
'binding_type': 'binding_type',
'multi': 'multi',
'paperformat_id': 'paperformat_id',
'groups_id': 'groups_id',
}
# Build the record tag
record_lines = [f'<record id="{record_id}" model="ir.actions.report">']
# Add fields based on mapping
for report_attr, field_name in field_mapping.items():
if report_attr in attributes:
value = attributes[report_attr]
# Handle special cases
if report_attr == 'attachment_use':
# Convert string to boolean representation
if value.lower() in ('false', '0', 'no'):
value = 'False'
elif value.lower() in ('true', '1', 'yes'):
value = 'True'
# Handle reference fields (those ending with _id)
if field_name.endswith('_id') and not value.startswith('ref(') and not value.startswith('eval('):
if '.' in value: # Looks like an XML ID reference
record_lines.append(f' <field name="{field_name}" ref="{value}"/>')
else:
record_lines.append(f' <field name="{field_name}">{value}</field>')
else:
record_lines.append(f' <field name="{field_name}">{value}</field>')
record_lines.append(' </record>')
return '\n'.join(record_lines)
# Process each file
for fileno, file in enumerate(files, start=1):
content = file.content
original_content = content
# Replace matching <report> tags
content = report_tag_re.sub(convert_report_to_record, content)
# Only update if changes were made
if content != original_content:
file.content = content
logger.info(
f"Converted <report> tags to <record> format in {file.path}"
)
else:
logger.debug(f"No <report> tags found in {file.path}")
file_manager.print_progress(fileno, len(files))