From 2c0e612cb99edefb53599328b26940221736dde3 Mon Sep 17 00:00:00 2001
From: Sylvain LE GAL
Date: Fri, 6 Nov 2020 21:39:26 +0100
Subject: [PATCH 01/67] [MOVE] openupgrade_records : move module from
OCA/OpenUpgrade (branch 13.0) to OCA/server-tools
Based on commit 746b7acbd90d62f9ffe6ee17472a1a3533e36597 (Fri Nov 6 17:18:47 2020 +0100)
Co-authored-by: Stefan Rijnhart
---
upgrade_analysis/apriori.py | 98 ++++++++
upgrade_analysis/compare.py | 438 ++++++++++++++++++++++++++++++++++++
2 files changed, 536 insertions(+)
create mode 100644 upgrade_analysis/apriori.py
create mode 100644 upgrade_analysis/compare.py
diff --git a/upgrade_analysis/apriori.py b/upgrade_analysis/apriori.py
new file mode 100644
index 000000000..973300fa0
--- /dev/null
+++ b/upgrade_analysis/apriori.py
@@ -0,0 +1,98 @@
+""" Encode any known changes to the database here
+to help the matching process
+"""
+
+renamed_modules = {
+ # Odoo
+ 'crm_reveal': 'crm_iap_lead',
+ 'document': 'attachment_indexation',
+ 'payment_ogone': 'payment_ingenico',
+ # OCA/hr
+ # TODO: Transform possible data
+ 'hr_skill': 'hr_skills'
+}
+
+merged_modules = {
+ # Odoo
+ 'account_cancel': 'account',
+ 'account_voucher': 'account',
+ 'crm_phone_validation': 'crm',
+ 'decimal_precision': 'base',
+ 'delivery_hs_code': 'delivery',
+ 'hw_scale': 'hw_drivers',
+ 'hw_scanner': 'hw_drivers',
+ 'hw_screen': 'hw_drivers',
+ 'l10n_fr_certification': 'account',
+ 'l10n_fr_sale_closing': 'l10n_fr',
+ 'mrp_bom_cost': 'mrp_account',
+ 'mrp_byproduct': 'mrp',
+ 'payment_stripe_sca': 'payment_stripe',
+ 'stock_zebra': 'stock',
+ 'survey_crm': 'survey',
+ 'test_pylint': 'test_lint',
+ 'web_settings_dashboard': 'base_setup',
+ 'website_crm_phone_validation': 'website_crm',
+ 'website_sale_link_tracker': 'website_sale',
+ 'website_survey': 'survey',
+ # OCA/account-financial-tools
+ 'account_move_chatter': 'account',
+ # OCA/account-reconcile
+ 'account_set_reconcilable': 'account',
+ # OCA/l10n-spain
+ 'l10n_es_aeat_sii': 'l10n_es_aeat_sii_oca',
+ # OCA/server-backend
+ 'base_suspend_security': 'base',
+ # OCA/social
+ 'mass_mailing_unique': 'mass_mailing',
+ # OCA/timesheet
+ 'sale_timesheet_existing_project': 'sale_timesheet',
+ # OCA/web
+ 'web_favicon': 'base',
+ 'web_widget_color': 'web',
+ 'web_widget_many2many_tags_multi_selection': 'web',
+ # OCA/website
+ 'website_canonical_url': 'website',
+ 'website_logo': 'website',
+}
+
+# only used here for openupgrade_records analysis:
+renamed_models = {
+ # Odoo
+ 'account.register.payments': 'account.payment.register',
+ 'crm.reveal.industry': 'crm.iap.lead.industry',
+ 'crm.reveal.role': 'crm.iap.lead.role',
+ 'crm.reveal.seniority': 'crm.iap.lead.seniority',
+ 'mail.blacklist.mixin': 'mail.thread.blacklist',
+ 'mail.mail.statistics': 'mailing.trace',
+ 'mail.statistics.report': 'mailing.trace.report',
+ 'mail.mass_mailing': 'mailing.mailing',
+ 'mail.mass_mailing.contact': 'mailing.contact',
+ 'mail.mass_mailing.list': 'mailing.list',
+ 'mail.mass_mailing.list_contact_rel': 'mailing.contact.subscription',
+ 'mail.mass_mailing.stage': 'utm.stage',
+ 'mail.mass_mailing.tag': 'utm.tag',
+ 'mail.mass_mailing.test': 'mailing.mailing.test',
+ 'mass.mailing.list.merge': 'mailing.list.merge',
+ 'mass.mailing.schedule.date': 'mailing.mailing.schedule.date',
+ 'mrp.subproduct': 'mrp.bom.byproduct',
+ 'sms.send_sms': 'sms.composer',
+ 'stock.fixed.putaway.strat': 'stock.putaway.rule',
+ 'survey.mail.compose.message': 'survey.invite',
+ 'website.redirect': 'website.rewrite',
+ # OCA/...
+}
+
+# only used here for openupgrade_records analysis:
+merged_models = {
+ # Odoo
+ 'account.invoice': 'account.move',
+ 'account.invoice.line': 'account.move.line',
+ 'account.invoice.tax': 'account.move.line',
+ 'account.voucher': 'account.move',
+ 'account.voucher.line': 'account.move.line',
+ 'lunch.order.line': 'lunch.order',
+ 'mail.mass_mailing.campaign': 'utm.campaign',
+ 'slide.category': 'slide.slide',
+ 'survey.page': 'survey.question',
+ # OCA/...
+}
diff --git a/upgrade_analysis/compare.py b/upgrade_analysis/compare.py
new file mode 100644
index 000000000..52ac7bbe8
--- /dev/null
+++ b/upgrade_analysis/compare.py
@@ -0,0 +1,438 @@
+# coding: utf-8
+# Copyright 2011-2015 Therp BV
+# Copyright 2015-2016 Opener B.V.
+# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
+
+#####################################################################
+# library providing a function to analyse two progressive database
+# layouts from the OpenUpgrade server.
+#####################################################################
+
+import collections
+import copy
+
+from odoo.addons.openupgrade_records.lib import apriori
+
+
+def module_map(module):
+ return apriori.renamed_modules.get(
+ module, apriori.merged_modules.get(module, module))
+
+
+def model_rename_map(model):
+ return apriori.renamed_models.get(model, model)
+
+
+def model_map(model):
+ return apriori.renamed_models.get(
+ model, apriori.merged_models.get(model, model))
+
+
+def inv_model_map(model):
+ inv_model_map_dict = {v: k for k, v in apriori.renamed_models.items()}
+ return inv_model_map_dict.get(model, model)
+
+
+IGNORE_FIELDS = [
+ 'create_date',
+ 'create_uid',
+ 'id',
+ 'write_date',
+ 'write_uid',
+ ]
+
+
+def compare_records(dict_old, dict_new, fields):
+ """
+ Check equivalence of two OpenUpgrade field representations
+ with respect to the keys in the 'fields' arguments.
+ Take apriori knowledge into account for mapped modules or
+ model names.
+ Return True of False.
+ """
+ for field in fields:
+ if field == 'module':
+ if module_map(dict_old['module']) != dict_new['module']:
+ return False
+ elif field == 'model':
+ if model_rename_map(dict_old['model']) != dict_new['model']:
+ return False
+ elif field == 'other_prefix':
+ if dict_old['module'] != dict_old['prefix'] or \
+ dict_new['module'] != dict_new['prefix']:
+ return False
+ if dict_old['model'] == 'ir.ui.view':
+ # basically, to avoid the assets_backend case
+ return False
+ elif dict_old[field] != dict_new[field]:
+ return False
+ return True
+
+
+def search(item, item_list, fields):
+ """
+ Find a match of a dictionary in a list of similar dictionaries
+ with respect to the keys in the 'fields' arguments.
+ Return the item if found or None.
+ """
+ for other in item_list:
+ if not compare_records(item, other, fields):
+ continue
+ return other
+ # search for renamed fields
+ if 'field' in fields:
+ for other in item_list:
+ if not item['field'] or item['field'] is not None or \
+ item['isproperty']:
+ continue
+ if compare_records(
+ dict(item, field=other['field']), other, fields):
+ return other
+ return None
+
+
+def fieldprint(old, new, field, text, reprs):
+ fieldrepr = "%s (%s)" % (old['field'], old['type'])
+ fullrepr = '%-12s / %-24s / %-30s' % (
+ old['module'], old['model'], fieldrepr)
+ if not text:
+ text = "%s is now '%s' ('%s')" % (field, new[field], old[field])
+ if field == 'relation':
+ text += ' [nothing to do]'
+ reprs[module_map(old['module'])].append("%s: %s" % (fullrepr, text))
+ if field == 'module':
+ text = "previously in module %s" % old[field]
+ fullrepr = '%-12s / %-24s / %-30s' % (
+ new['module'], old['model'], fieldrepr)
+ reprs[module_map(new['module'])].append("%s: %s" % (fullrepr, text))
+
+
+def report_generic(new, old, attrs, reprs):
+ for attr in attrs:
+ if attr == 'required':
+ if old[attr] != new['required'] and new['required']:
+ text = "now required"
+ if new['req_default']:
+ text += ', req_default: %s' % new['req_default']
+ fieldprint(old, new, '', text, reprs)
+ elif attr == 'stored':
+ if old[attr] != new[attr]:
+ if new['stored']:
+ text = "is now stored"
+ else:
+ text = "not stored anymore"
+ fieldprint(old, new, '', text, reprs)
+ elif attr == 'isfunction':
+ if old[attr] != new[attr]:
+ if new['isfunction']:
+ text = "now a function"
+ else:
+ text = "not a function anymore"
+ fieldprint(old, new, '', text, reprs)
+ elif attr == 'isproperty':
+ if old[attr] != new[attr]:
+ if new[attr]:
+ text = "now a property"
+ else:
+ text = "not a property anymore"
+ fieldprint(old, new, '', text, reprs)
+ elif attr == 'isrelated':
+ if old[attr] != new[attr]:
+ if new[attr]:
+ text = "now related"
+ else:
+ text = "not related anymore"
+ fieldprint(old, new, '', text, reprs)
+ elif old[attr] != new[attr]:
+ fieldprint(old, new, attr, '', reprs)
+
+
+def compare_sets(old_records, new_records):
+ """
+ Compare a set of OpenUpgrade field representations.
+ Try to match the equivalent fields in both sets.
+ Return a textual representation of changes in a dictionary with
+ module names as keys. Special case is the 'general' key
+ which contains overall remarks and matching statistics.
+ """
+ reprs = collections.defaultdict(list)
+
+ def clean_records(records):
+ result = []
+ for record in records:
+ if record['field'] not in IGNORE_FIELDS:
+ result.append(record)
+ return result
+
+ old_records = clean_records(old_records)
+ new_records = clean_records(new_records)
+
+ origlen = len(old_records)
+ new_models = set([column['model'] for column in new_records])
+ old_models = set([column['model'] for column in old_records])
+
+ matched_direct = 0
+ matched_other_module = 0
+ matched_other_type = 0
+ in_obsolete_models = 0
+
+ obsolete_models = []
+ for model in old_models:
+ if model not in new_models:
+ if model_map(model) not in new_models:
+ obsolete_models.append(model)
+
+ non_obsolete_old_records = []
+ for column in copy.copy(old_records):
+ if column['model'] in obsolete_models:
+ in_obsolete_models += 1
+ else:
+ non_obsolete_old_records.append(column)
+
+ def match(match_fields, report_fields, warn=False):
+ count = 0
+ for column in copy.copy(non_obsolete_old_records):
+ found = search(column, new_records, match_fields)
+ if found:
+ if warn:
+ pass
+ # print "Tentatively"
+ report_generic(found, column, report_fields, reprs)
+ old_records.remove(column)
+ non_obsolete_old_records.remove(column)
+ new_records.remove(found)
+ count += 1
+ return count
+
+ matched_direct = match(
+ ['module', 'mode', 'model', 'field'],
+ ['relation', 'type', 'selection_keys', 'inherits', 'stored',
+ 'isfunction', 'isrelated', 'required', 'table'])
+
+ # other module, same type and operation
+ matched_other_module = match(
+ ['mode', 'model', 'field', 'type'],
+ ['module', 'relation', 'selection_keys', 'inherits', 'stored',
+ 'isfunction', 'isrelated', 'required', 'table'])
+
+ # other module, same operation, other type
+ matched_other_type = match(
+ ['mode', 'model', 'field'],
+ ['relation', 'type', 'selection_keys', 'inherits', 'stored',
+ 'isfunction', 'isrelated', 'required', 'table'])
+
+ printkeys = [
+ 'relation', 'required', 'selection_keys',
+ 'req_default', 'inherits', 'mode', 'attachment',
+ ]
+ for column in old_records:
+ # we do not care about removed non stored function fields
+ if not column['stored'] and (
+ column['isfunction'] or column['isrelated']):
+ continue
+ if column['mode'] == 'create':
+ column['mode'] = ''
+ extra_message = ", ".join(
+ [k + ': ' + str(column[k]) if k != str(column[k]) else k
+ for k in printkeys if column[k]]
+ )
+ if extra_message:
+ extra_message = " " + extra_message
+ fieldprint(
+ column, '', '', "DEL" + extra_message, reprs)
+
+ printkeys.extend([
+ 'hasdefault',
+ ])
+ for column in new_records:
+ # we do not care about newly added non stored function fields
+ if not column['stored'] and (
+ column['isfunction'] or column['isrelated']):
+ continue
+ if column['mode'] == 'create':
+ column['mode'] = ''
+ printkeys_plus = printkeys.copy()
+ if column['isfunction'] or column['isrelated']:
+ printkeys_plus.extend(['isfunction', 'isrelated', 'stored'])
+ extra_message = ", ".join(
+ [k + ': ' + str(column[k]) if k != str(column[k]) else k
+ for k in printkeys_plus if column[k]]
+ )
+ if extra_message:
+ extra_message = " " + extra_message
+ fieldprint(
+ column, '', '', "NEW" + extra_message, reprs)
+
+ for line in [
+ "# %d fields matched," % (origlen - len(old_records)),
+ "# Direct match: %d" % matched_direct,
+ "# Found in other module: %d" % matched_other_module,
+ "# Found with different type: %d" % matched_other_type,
+ "# In obsolete models: %d" % in_obsolete_models,
+ "# Not matched: %d" % len(old_records),
+ "# New columns: %d" % len(new_records)
+ ]:
+ reprs['general'].append(line)
+ return reprs
+
+
+def compare_xml_sets(old_records, new_records):
+ reprs = collections.defaultdict(list)
+
+ def match(match_fields, match_type='direct'):
+ matched_records = []
+ for column in copy.copy(old_records):
+ found = search(column, new_records, match_fields)
+ if found:
+ old_records.remove(column)
+ new_records.remove(found)
+ if match_type != 'direct':
+ column['old'] = True
+ found['new'] = True
+ column[match_type] = found['module']
+ found[match_type] = column['module']
+ found['domain'] = column['domain'] != found['domain'] and \
+ column['domain'] != '[]' and found['domain'] is False
+ column['domain'] = False
+ column['noupdate_switched'] = False
+ found['noupdate_switched'] = \
+ column['noupdate'] != found['noupdate']
+ if match_type != 'direct':
+ matched_records.append(column)
+ matched_records.append(found)
+ elif (match_type == 'direct' and found['domain']) or \
+ found['noupdate_switched']:
+ matched_records.append(found)
+ return matched_records
+
+ # direct match
+ modified_records = match(['module', 'model', 'name'])
+
+ # other module, same full xmlid
+ moved_records = match(['model', 'name'], 'moved')
+
+ # other module, same suffix, other prefix
+ renamed_records = match(['model', 'suffix', 'other_prefix'], 'renamed')
+
+ for record in old_records:
+ record['old'] = True
+ record['domain'] = False
+ record['noupdate_switched'] = False
+ for record in new_records:
+ record['new'] = True
+ record['domain'] = False
+ record['noupdate_switched'] = False
+
+ sorted_records = sorted(
+ old_records + new_records + moved_records + renamed_records +
+ modified_records,
+ key=lambda k: (k['model'], 'old' in k, k['name'])
+ )
+ for entry in sorted_records:
+ content = ''
+ if 'old' in entry:
+ content = 'DEL %(model)s: %(name)s' % entry
+ if 'moved' in entry:
+ content += ' [potentially moved to %(moved)s module]' % entry
+ elif 'renamed' in entry:
+ content += ' [renamed to %(renamed)s module]' % entry
+ elif 'new' in entry:
+ content = 'NEW %(model)s: %(name)s' % entry
+ if 'moved' in entry:
+ content += ' [potentially moved from %(moved)s module]' % entry
+ elif 'renamed' in entry:
+ content += ' [renamed from %(renamed)s module]' % entry
+ if 'old' not in entry and 'new' not in entry:
+ content = '%(model)s: %(name)s' % entry
+ if entry['domain']:
+ content += ' (deleted domain)'
+ if entry['noupdate']:
+ content += ' (noupdate)'
+ if entry['noupdate_switched']:
+ content += ' (noupdate switched)'
+ reprs[module_map(entry['module'])].append(content)
+ return reprs
+
+
+def compare_model_sets(old_records, new_records):
+ """
+ Compare a set of OpenUpgrade model representations.
+ """
+ reprs = collections.defaultdict(list)
+
+ new_models = {column['model']: column['module'] for column in new_records}
+ old_models = {column['model']: column['module'] for column in old_records}
+
+ obsolete_models = []
+ for column in copy.copy(old_records):
+ model = column['model']
+ if model in old_models:
+ if model not in new_models:
+ if model_map(model) not in new_models:
+ obsolete_models.append(model)
+ text = 'obsolete model %s' % model
+ if column['model_type']:
+ text += " [%s]" % column['model_type']
+ reprs[module_map(column['module'])].append(text)
+ reprs['general'].append('obsolete model %s [module %s]' % (
+ model, module_map(column['module'])))
+ else:
+ moved_module = ''
+ if module_map(column['module']) != new_models[model_map(
+ model)]:
+ moved_module = ' in module %s' % new_models[model_map(
+ model)]
+ text = 'obsolete model %s (renamed to %s%s)' % (
+ model, model_map(model), moved_module)
+ if column['model_type']:
+ text += " [%s]" % column['model_type']
+ reprs[module_map(column['module'])].append(text)
+ reprs['general'].append(
+ 'obsolete model %s (renamed to %s) [module %s]' % (
+ model, model_map(model),
+ module_map(column['module'])))
+ else:
+ if module_map(column['module']) != new_models[model]:
+ text = 'model %s (moved to %s)' % (
+ model, new_models[model])
+ if column['model_type']:
+ text += " [%s]" % column['model_type']
+ reprs[module_map(column['module'])].append(text)
+ text = 'model %s (moved from %s)' % (
+ model, old_models[model])
+ if column['model_type']:
+ text += " [%s]" % column['model_type']
+
+ for column in copy.copy(new_records):
+ model = column['model']
+ if model in new_models:
+ if model not in old_models:
+ if inv_model_map(model) not in old_models:
+ text = 'new model %s' % model
+ if column['model_type']:
+ text += " [%s]" % column['model_type']
+ reprs[column['module']].append(text)
+ reprs['general'].append('new model %s [module %s]' % (
+ model, column['module']))
+ else:
+ moved_module = ''
+ if column['module'] != module_map(old_models[inv_model_map(
+ model)]):
+ moved_module = ' in module %s' % old_models[
+ inv_model_map(model)]
+ text = 'new model %s (renamed from %s%s)' % (
+ model, inv_model_map(model), moved_module)
+ if column['model_type']:
+ text += " [%s]" % column['model_type']
+ reprs[column['module']].append(text)
+ reprs['general'].append(
+ 'new model %s (renamed from %s) [module %s]' % (
+ model, inv_model_map(model), column['module']))
+ else:
+ if column['module'] != module_map(old_models[model]):
+ text = 'model %s (moved from %s)' % (
+ model, old_models[model])
+ if column['model_type']:
+ text += " [%s]" % column['model_type']
+ reprs[column['module']].append(text)
+ return reprs
From 3ada67d9e7bec3d86961e02746eb0c8adbe124f2 Mon Sep 17 00:00:00 2001
From: Sylvain LE GAL
Date: Fri, 6 Nov 2020 22:24:04 +0100
Subject: [PATCH 02/67] [REF] rename module openupgrade_records into
upgrade_analysis
---
upgrade_analysis/README.rst | 59 ++++++
upgrade_analysis/__init__.py | 2 +
upgrade_analysis/__manifest__.py | 23 +++
upgrade_analysis/blacklist.py | 7 +
upgrade_analysis/models/__init__.py | 5 +
upgrade_analysis/models/analysis_wizard.py | 182 ++++++++++++++++++
upgrade_analysis/models/comparison_config.py | 88 +++++++++
.../models/generate_records_wizard.py | 119 ++++++++++++
upgrade_analysis/models/install_all_wizard.py | 51 +++++
upgrade_analysis/models/openupgrade_record.py | 113 +++++++++++
upgrade_analysis/security/ir.model.access.csv | 4 +
upgrade_analysis/views/analysis_wizard.xml | 36 ++++
upgrade_analysis/views/comparison_config.xml | 77 ++++++++
.../views/generate_records_wizard.xml | 47 +++++
upgrade_analysis/views/install_all_wizard.xml | 48 +++++
upgrade_analysis/views/openupgrade_record.xml | 96 +++++++++
16 files changed, 957 insertions(+)
create mode 100644 upgrade_analysis/README.rst
create mode 100644 upgrade_analysis/__init__.py
create mode 100644 upgrade_analysis/__manifest__.py
create mode 100644 upgrade_analysis/blacklist.py
create mode 100644 upgrade_analysis/models/__init__.py
create mode 100644 upgrade_analysis/models/analysis_wizard.py
create mode 100644 upgrade_analysis/models/comparison_config.py
create mode 100644 upgrade_analysis/models/generate_records_wizard.py
create mode 100644 upgrade_analysis/models/install_all_wizard.py
create mode 100644 upgrade_analysis/models/openupgrade_record.py
create mode 100644 upgrade_analysis/security/ir.model.access.csv
create mode 100644 upgrade_analysis/views/analysis_wizard.xml
create mode 100644 upgrade_analysis/views/comparison_config.xml
create mode 100644 upgrade_analysis/views/generate_records_wizard.xml
create mode 100644 upgrade_analysis/views/install_all_wizard.xml
create mode 100644 upgrade_analysis/views/openupgrade_record.xml
diff --git a/upgrade_analysis/README.rst b/upgrade_analysis/README.rst
new file mode 100644
index 000000000..f3d1c48de
--- /dev/null
+++ b/upgrade_analysis/README.rst
@@ -0,0 +1,59 @@
+.. image:: https://img.shields.io/badge/license-AGPL--3-blue.png
+ :target: https://www.gnu.org/licenses/agpl
+ :alt: License: AGPL-3
+
+===============================
+OpenUpgrade Database Comparison
+===============================
+
+This module provides the tool to generate the database analysis files that indicate how the Odoo data model and module data have changed between two versions of Odoo. Database analysis files for the core modules are included in the OpenUpgrade distribution so as a migration script developer you will not usually need to use this tool yourself. If you do need to run your analysis of a custom set of modules, please refer to the documentation here: https://doc.therp.nl/openupgrade/analysis.html
+
+Installation
+============
+
+This module has a python dependency on openerp-client-lib. You need to make this module available in your Python environment, for instance by installing it with the pip tool.
+
+Known issues / Roadmap
+======================
+
+* scripts/compare_noupdate_xml_records.py should be integrated in the analysis process (#590)
+* Log removed modules in the module that owned them (#468)
+* Detect renamed many2many tables (#213)
+
+Bug Tracker
+===========
+
+Bugs are tracked on `GitHub Issues
+`_. In case of trouble, please
+check there if your issue has already been reported. If you spotted it first,
+help us smash it by providing detailed and welcomed feedback.
+
+Images
+------
+
+* Odoo Community Association: `Icon `_.
+
+Contributors
+------------
+
+* Stefan Rijnhart
+* Holger Brunn
+* Pedro M. Baeza
+* Ferdinand Gassauer
+* Florent Xicluna
+* Miquel Raïch
+
+Maintainer
+----------
+
+.. image:: https://odoo-community.org/logo.png
+ :alt: Odoo Community Association
+ :target: https://odoo-community.org
+
+This module is maintained by the OCA.
+
+OCA, or the Odoo Community Association, is a nonprofit organization whose
+mission is to support the collaborative development of Odoo features and
+promote its widespread use.
+
+To contribute to this module, please visit https://odoo-community.org.
diff --git a/upgrade_analysis/__init__.py b/upgrade_analysis/__init__.py
new file mode 100644
index 000000000..c102a8ca6
--- /dev/null
+++ b/upgrade_analysis/__init__.py
@@ -0,0 +1,2 @@
+from . import models
+from . import blacklist
diff --git a/upgrade_analysis/__manifest__.py b/upgrade_analysis/__manifest__.py
new file mode 100644
index 000000000..79ebfc939
--- /dev/null
+++ b/upgrade_analysis/__manifest__.py
@@ -0,0 +1,23 @@
+# Copyright 2011-2015 Therp BV
+# Copyright 2016 Opener B.V.
+# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
+{
+ "name": "OpenUpgrade Records",
+ "version": "14.0.1.0.0",
+ "category": "Migration",
+ "author": "Therp BV, Opener B.V., Odoo Community Association (OCA)",
+ "website": "https://github.com/OCA/server-tools",
+ "data": [
+ "views/openupgrade_record.xml",
+ "views/comparison_config.xml",
+ "views/analysis_wizard.xml",
+ "views/generate_records_wizard.xml",
+ "views/install_all_wizard.xml",
+ "security/ir.model.access.csv",
+ ],
+ "installable": True,
+ "external_dependencies": {
+ "python": ["odoorpc", "openupgradelib"],
+ },
+ "license": "AGPL-3",
+}
diff --git a/upgrade_analysis/blacklist.py b/upgrade_analysis/blacklist.py
new file mode 100644
index 000000000..814396ad6
--- /dev/null
+++ b/upgrade_analysis/blacklist.py
@@ -0,0 +1,7 @@
+BLACKLIST_MODULES = [
+ # the hw_* modules are not affected by a migration as they don't
+ # contain any ORM functionality, but they do start up threads that
+ # delay the process and spit out annoying log messages continously.
+ "hw_escpos",
+ "hw_proxy",
+]
diff --git a/upgrade_analysis/models/__init__.py b/upgrade_analysis/models/__init__.py
new file mode 100644
index 000000000..6e4458424
--- /dev/null
+++ b/upgrade_analysis/models/__init__.py
@@ -0,0 +1,5 @@
+from . import openupgrade_record
+from . import comparison_config
+from . import analysis_wizard
+from . import generate_records_wizard
+from . import install_all_wizard
diff --git a/upgrade_analysis/models/analysis_wizard.py b/upgrade_analysis/models/analysis_wizard.py
new file mode 100644
index 000000000..61a5e2082
--- /dev/null
+++ b/upgrade_analysis/models/analysis_wizard.py
@@ -0,0 +1,182 @@
+# Copyright 2011-2015 Therp BV
+# Copyright 2016 Opener B.V.
+# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
+# flake8: noqa: C901
+
+import os
+
+from odoo import fields, models
+from odoo.modules import get_module_path
+
+from ..lib import compare
+
+
+class AnalysisWizard(models.TransientModel):
+ _name = "openupgrade.analysis.wizard"
+ _description = "OpenUpgrade Analysis Wizard"
+
+ server_config = fields.Many2one(
+ "openupgrade.comparison.config", "Configuration", required=True
+ )
+ state = fields.Selection(
+ [("init", "Init"), ("ready", "Ready")], readonly=True, default="init"
+ )
+ log = fields.Text()
+ write_files = fields.Boolean(
+ help="Write analysis files to the module directories", default=True
+ )
+
+ def get_communication(self):
+ """
+ Retrieve both sets of database representations,
+ perform the comparison and register the resulting
+ change set
+ """
+
+ def write_file(module, version, content, filename="openupgrade_analysis.txt"):
+ module_path = get_module_path(module)
+ if not module_path:
+ return "ERROR: could not find module path:\n"
+ full_path = os.path.join(module_path, "migrations", version)
+ if not os.path.exists(full_path):
+ try:
+ os.makedirs(full_path)
+ except os.error:
+ return "ERROR: could not create migrations directory:\n"
+ logfile = os.path.join(full_path, filename)
+ try:
+ f = open(logfile, "w")
+ except Exception:
+ return "ERROR: could not open file %s for writing:\n" % logfile
+ f.write(content)
+ f.close()
+ return None
+
+ self.ensure_one()
+ connection = self.server_config.get_connection()
+ remote_record_obj = connection.env["openupgrade.record"]
+ local_record_obj = self.env["openupgrade.record"]
+
+ # Retrieve field representations and compare
+ remote_records = remote_record_obj.field_dump()
+ local_records = local_record_obj.field_dump()
+ res = compare.compare_sets(remote_records, local_records)
+
+ # Retrieve xml id representations and compare
+ flds = [
+ "module",
+ "model",
+ "name",
+ "noupdate",
+ "prefix",
+ "suffix",
+ "domain",
+ ]
+ local_xml_records = [
+ {field: record[field] for field in flds}
+ for record in local_record_obj.search([("type", "=", "xmlid")])
+ ]
+ remote_xml_record_ids = remote_record_obj.search([("type", "=", "xmlid")])
+ remote_xml_records = [
+ {field: record[field] for field in flds}
+ for record in remote_record_obj.read(remote_xml_record_ids, flds)
+ ]
+ res_xml = compare.compare_xml_sets(remote_xml_records, local_xml_records)
+
+ # Retrieve model representations and compare
+ flds = [
+ "module",
+ "model",
+ "name",
+ "model_original_module",
+ "model_type",
+ ]
+ local_model_records = [
+ {field: record[field] for field in flds}
+ for record in local_record_obj.search([("type", "=", "model")])
+ ]
+ remote_model_record_ids = remote_record_obj.search([("type", "=", "model")])
+ remote_model_records = [
+ {field: record[field] for field in flds}
+ for record in remote_record_obj.read(remote_model_record_ids, flds)
+ ]
+ res_model = compare.compare_model_sets(
+ remote_model_records, local_model_records
+ )
+
+ affected_modules = sorted(
+ {
+ record["module"]
+ for record in remote_records
+ + local_records
+ + remote_xml_records
+ + local_xml_records
+ + remote_model_records
+ + local_model_records
+ }
+ )
+
+ # reorder and output the result
+ keys = ["general"] + affected_modules
+ modules = {
+ module["name"]: module
+ for module in self.env["ir.module.module"].search(
+ [("state", "=", "installed")]
+ )
+ }
+ general = ""
+ for key in keys:
+ contents = "---Models in module '%s'---\n" % key
+ if key in res_model:
+ contents += "\n".join([str(line) for line in res_model[key]])
+ if res_model[key]:
+ contents += "\n"
+ contents += "---Fields in module '%s'---\n" % key
+ if key in res:
+ contents += "\n".join([str(line) for line in sorted(res[key])])
+ if res[key]:
+ contents += "\n"
+ contents += "---XML records in module '%s'---\n" % key
+ if key in res_xml:
+ contents += "\n".join([str(line) for line in res_xml[key]])
+ if res_xml[key]:
+ contents += "\n"
+ if key not in res and key not in res_xml and key not in res_model:
+ contents += "---nothing has changed in this module--\n"
+ if key == "general":
+ general += contents
+ continue
+ if compare.module_map(key) not in modules:
+ general += (
+ "ERROR: module not in list of installed modules:\n" + contents
+ )
+ continue
+ if key not in modules:
+ # no need to log in general the merged/renamed modules
+ continue
+ if self.write_files:
+ error = write_file(key, modules[key].installed_version, contents)
+ if error:
+ general += error
+ general += contents
+ else:
+ general += contents
+
+ # Store the general log in as many places as possible ;-)
+ if self.write_files and "base" in modules:
+ write_file(
+ "base",
+ modules["base"].installed_version,
+ general,
+ "openupgrade_general_log.txt",
+ )
+ self.server_config.write({"last_log": general})
+ self.write({"state": "ready", "log": general})
+
+ return {
+ "name": self._description,
+ "view_mode": "form",
+ "res_model": self._name,
+ "type": "ir.actions.act_window",
+ "res_id": self.id,
+ }
diff --git a/upgrade_analysis/models/comparison_config.py b/upgrade_analysis/models/comparison_config.py
new file mode 100644
index 000000000..0e5274bdf
--- /dev/null
+++ b/upgrade_analysis/models/comparison_config.py
@@ -0,0 +1,88 @@
+# Copyright 2011-2015 Therp BV
+# Copyright 2016 Opener B.V.
+# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
+
+import logging
+
+from odoo import fields, models
+from odoo.exceptions import UserError
+from odoo.tools.translate import _
+
+from ..lib import apriori
+
+
+class OpenupgradeComparisonConfig(models.Model):
+ _name = "openupgrade.comparison.config"
+ _description = "OpenUpgrade Comparison Configuration"
+
+ name = fields.Char()
+ server = fields.Char(required=True)
+ port = fields.Integer(required=True, default=8069)
+ protocol = fields.Selection(
+ [("http://", "XML-RPC")],
+ # ('https://', 'XML-RPC Secure')], not supported by libopenerp
+ required=True,
+ default="http://",
+ )
+ database = fields.Char(required=True)
+ username = fields.Char(required=True)
+ password = fields.Char(required=True)
+ last_log = fields.Text()
+
+ def get_connection(self):
+ self.ensure_one()
+ import odoorpc
+
+ remote = odoorpc.ODOO(self.server, port=self.port)
+ remote.login(self.database, self.username, self.password)
+ return remote
+
+ def test_connection(self):
+ self.ensure_one()
+ try:
+ connection = self.get_connection()
+ user_model = connection.env["res.users"]
+ ids = user_model.search([("login", "=", "admin")])
+ user_info = user_model.read([ids[0]], ["name"])[0]
+ except Exception as e:
+ raise UserError(_("Connection failed.\n\nDETAIL: %s") % e)
+ raise UserError(_("%s is connected.") % user_info["name"])
+
+ def analyze(self):
+ """ Run the analysis wizard """
+ self.ensure_one()
+ wizard = self.env["openupgrade.analysis.wizard"].create(
+ {"server_config": self.id}
+ )
+ return {
+ "name": wizard._description,
+ "view_mode": "form",
+ "res_model": wizard._name,
+ "type": "ir.actions.act_window",
+ "target": "new",
+ "res_id": wizard.id,
+ "nodestroy": True,
+ }
+
+ def install_modules(self):
+ """ Install same modules as in source DB """
+ self.ensure_one()
+ connection = self.get_connection()
+ remote_module_obj = connection.env["ir.module.module"]
+ remote_module_ids = remote_module_obj.search([("state", "=", "installed")])
+
+ modules = []
+ for module_id in remote_module_ids:
+ mod = remote_module_obj.read([module_id], ["name"])[0]
+ mod_name = mod["name"]
+ mod_name = apriori.renamed_modules.get(mod_name, mod_name)
+ modules.append(mod_name)
+ _logger = logging.getLogger(__name__)
+ _logger.debug("remote modules %s", modules)
+ local_modules = self.env["ir.module.module"].search(
+ [("name", "in", modules), ("state", "=", "uninstalled")]
+ )
+ _logger.debug("local modules %s", ",".join(local_modules.mapped("name")))
+ if local_modules:
+ local_modules.write({"state": "to install"})
+ return {}
diff --git a/upgrade_analysis/models/generate_records_wizard.py b/upgrade_analysis/models/generate_records_wizard.py
new file mode 100644
index 000000000..b09f6839e
--- /dev/null
+++ b/upgrade_analysis/models/generate_records_wizard.py
@@ -0,0 +1,119 @@
+# Copyright 2011-2015 Therp BV
+# Copyright 2016 Opener B.V.
+# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
+
+from openupgradelib import openupgrade_tools
+
+from odoo import _, fields, models
+from odoo.exceptions import UserError
+from odoo.modules.registry import Registry
+
+
+class GenerateWizard(models.TransientModel):
+ _name = "openupgrade.generate.records.wizard"
+ _description = "OpenUpgrade Generate Records Wizard"
+ _rec_name = "state"
+
+ state = fields.Selection([("init", "init"), ("ready", "ready")], default="init")
+
+ def quirk_standard_calendar_attendances(self):
+ """Introduced in Odoo 13. The reinstallation causes a one2many value
+ in [(0, 0, {})] format to be loaded on top of the first load, causing a
+ violation of database constraint."""
+ for cal in ("resource_calendar_std_35h", "resource_calendar_std_38h"):
+ record = self.env.ref("resource.%s" % cal, False)
+ if record:
+ record.attendance_ids.unlink()
+
+ def generate(self):
+ """Main wizard step. Make sure that all modules are up-to-date,
+ then reinitialize all installed modules.
+ Equivalent of running the server with '-d --init all'
+
+ The goal of this is to fill the records table.
+
+ TODO: update module list and versions, then update all modules?"""
+ # Truncate the records table
+ if openupgrade_tools.table_exists(
+ self.env.cr, "openupgrade_attribute"
+ ) and openupgrade_tools.table_exists(self.env.cr, "openupgrade_record"):
+ self.env.cr.execute("TRUNCATE openupgrade_attribute, openupgrade_record;")
+
+ # Run any quirks
+ self.quirk_standard_calendar_attendances()
+
+ # Need to get all modules in state 'installed'
+ modules = self.env["ir.module.module"].search(
+ [("state", "in", ["to install", "to upgrade"])]
+ )
+ if modules:
+ self.env.cr.commit() # pylint: disable=invalid-commit
+ Registry.new(self.env.cr.dbname, update_module=True)
+ # Did we succeed above?
+ modules = self.env["ir.module.module"].search(
+ [("state", "in", ["to install", "to upgrade"])]
+ )
+ if modules:
+ raise UserError(
+ _("Cannot seem to install or upgrade modules %s")
+ % (", ".join([module.name for module in modules]))
+ )
+ # Now reinitialize all installed modules
+ self.env["ir.module.module"].search([("state", "=", "installed")]).write(
+ {"state": "to install"}
+ )
+ self.env.cr.commit() # pylint: disable=invalid-commit
+ Registry.new(self.env.cr.dbname, update_module=True)
+
+ # Set domain property
+ self.env.cr.execute(
+ """ UPDATE openupgrade_record our
+ SET domain = iaw.domain
+ FROM ir_model_data imd
+ JOIN ir_act_window iaw ON imd.res_id = iaw.id
+ WHERE our.type = 'xmlid'
+ AND imd.model = 'ir.actions.act_window'
+ AND our.model = imd.model
+ AND our.name = imd.module || '.' || imd.name
+ """
+ )
+ self.env.cache.invalidate(
+ [
+ (self.env["openupgrade.record"]._fields["domain"], None),
+ ]
+ )
+
+ # Set noupdate property from ir_model_data
+ self.env.cr.execute(
+ """ UPDATE openupgrade_record our
+ SET noupdate = imd.noupdate
+ FROM ir_model_data imd
+ WHERE our.type = 'xmlid'
+ AND our.model = imd.model
+ AND our.name = imd.module || '.' || imd.name
+ """
+ )
+ self.env.cache.invalidate(
+ [
+ (self.env["openupgrade.record"]._fields["noupdate"], None),
+ ]
+ )
+
+ # Log model records
+ self.env.cr.execute(
+ """INSERT INTO openupgrade_record
+ (module, name, model, type)
+ SELECT imd2.module, imd2.module || '.' || imd.name AS name,
+ im.model, 'model' AS type
+ FROM (
+ SELECT min(id) as id, name, res_id
+ FROM ir_model_data
+ WHERE name LIKE 'model_%' AND model = 'ir.model'
+ GROUP BY name, res_id
+ ) imd
+ JOIN ir_model_data imd2 ON imd2.id = imd.id
+ JOIN ir_model im ON imd.res_id = im.id
+ ORDER BY imd.name, imd.id""",
+ )
+
+ return self.write({"state": "ready"})
diff --git a/upgrade_analysis/models/install_all_wizard.py b/upgrade_analysis/models/install_all_wizard.py
new file mode 100644
index 000000000..c1085418e
--- /dev/null
+++ b/upgrade_analysis/models/install_all_wizard.py
@@ -0,0 +1,51 @@
+# Copyright 2011-2015 Therp BV
+# Copyright 2016 Opener B.V.
+# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
+
+from odoo import api, fields, models
+from odoo.modules.registry import Registry
+from odoo.osv.expression import AND
+
+from ..blacklist import BLACKLIST_MODULES
+
+
+class InstallAll(models.TransientModel):
+ _name = "openupgrade.install.all.wizard"
+ _description = "OpenUpgrade Install All Wizard"
+
+ state = fields.Selection(
+ [("init", "init"), ("ready", "ready")], readonly=True, default="init"
+ )
+ to_install = fields.Integer("Number of modules to install", readonly=True)
+
+ @api.model
+ def default_get(self, fields):
+ """Update module list and retrieve the number
+ of installable modules"""
+ res = super(InstallAll, self).default_get(fields)
+ update, add = self.env["ir.module.module"].update_list()
+ modules = self.env["ir.module.module"].search(
+ [("state", "not in", ["uninstallable", "unknown"])]
+ )
+ res["to_install"] = len(modules)
+ return res
+
+ def install_all(self, extra_domain=None):
+ """Main wizard step. Set all installable modules to install
+ and actually install them. Exclude testing modules."""
+ domain = [
+ "&",
+ "&",
+ ("state", "not in", ["uninstallable", "unknown"]),
+ ("category_id.name", "!=", "Tests"),
+ ("name", "not in", BLACKLIST_MODULES),
+ ]
+ if extra_domain:
+ domain = AND([domain, extra_domain])
+ modules = self.env["ir.module.module"].search(domain)
+ if modules:
+ modules.write({"state": "to install"})
+ self.env.cr.commit() # pylint: disable=invalid-commit
+ Registry.new(self.env.cr.dbname, update_module=True)
+ self.write({"state": "ready"})
+ return True
diff --git a/upgrade_analysis/models/openupgrade_record.py b/upgrade_analysis/models/openupgrade_record.py
new file mode 100644
index 000000000..80b5a8a3a
--- /dev/null
+++ b/upgrade_analysis/models/openupgrade_record.py
@@ -0,0 +1,113 @@
+# Copyright 2011-2015 Therp BV
+# Copyright 2016 Opener B.V.
+# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
+
+from odoo import api, fields, models
+
+
+class Attribute(models.Model):
+ _name = "openupgrade.attribute"
+ _description = "OpenUpgrade Attribute"
+
+ name = fields.Char(readonly=True)
+ value = fields.Char(readonly=True)
+ record_id = fields.Many2one(
+ "openupgrade.record",
+ ondelete="CASCADE",
+ readonly=True,
+ )
+
+
+class Record(models.Model):
+ _name = "openupgrade.record"
+ _description = "OpenUpgrade Record"
+
+ name = fields.Char(readonly=True)
+ module = fields.Char(readonly=True)
+ model = fields.Char(readonly=True)
+ field = fields.Char(readonly=True)
+ mode = fields.Selection(
+ [("create", "Create"), ("modify", "Modify")],
+ help="Set to Create if a field is newly created "
+ "in this module. If this module modifies an attribute of an "
+ "existing field, set to Modify.",
+ readonly=True,
+ )
+ type = fields.Selection( # Uh oh, reserved keyword
+ [("field", "Field"), ("xmlid", "XML ID"), ("model", "Model")],
+ readonly=True,
+ )
+ attribute_ids = fields.One2many("openupgrade.attribute", "record_id", readonly=True)
+ noupdate = fields.Boolean(readonly=True)
+ domain = fields.Char(readonly=True)
+ prefix = fields.Char(compute="_compute_prefix_and_suffix")
+ suffix = fields.Char(compute="_compute_prefix_and_suffix")
+ model_original_module = fields.Char(compute="_compute_model_original_module")
+ model_type = fields.Char(compute="_compute_model_type")
+
+ @api.depends("name")
+ def _compute_prefix_and_suffix(self):
+ for rec in self:
+ rec.prefix, rec.suffix = rec.name.split(".", 1)
+
+ @api.depends("model", "type")
+ def _compute_model_original_module(self):
+ for rec in self:
+ if rec.type == "model":
+ rec.model_original_module = self.env[rec.model]._original_module
+ else:
+ rec.model_original_module = ""
+
+ @api.depends("model", "type")
+ def _compute_model_type(self):
+ for rec in self:
+ if rec.type == "model":
+ model = self.env[rec.model]
+ if model._auto and model._transient:
+ rec.model_type = "transient"
+ elif model._auto:
+ rec.model_type = ""
+ elif not model._auto and model._abstract:
+ rec.model_type = "abstract"
+ else:
+ rec.model_type = "sql_view"
+ else:
+ rec.model_type = ""
+
+ @api.model
+ def field_dump(self):
+ keys = [
+ "attachment",
+ "module",
+ "mode",
+ "model",
+ "field",
+ "type",
+ "isfunction",
+ "isproperty",
+ "isrelated",
+ "relation",
+ "required",
+ "stored",
+ "selection_keys",
+ "req_default",
+ "hasdefault",
+ "table",
+ "inherits",
+ ]
+
+ template = {x: False for x in keys}
+ data = []
+ for record in self.search([("type", "=", "field")]):
+ repre = template.copy()
+ repre.update(
+ {
+ "module": record.module,
+ "model": record.model,
+ "field": record.field,
+ "mode": record.mode,
+ }
+ )
+ repre.update({x.name: x.value for x in record.attribute_ids})
+ data.append(repre)
+ return data
diff --git a/upgrade_analysis/security/ir.model.access.csv b/upgrade_analysis/security/ir.model.access.csv
new file mode 100644
index 000000000..2ab5e67c1
--- /dev/null
+++ b/upgrade_analysis/security/ir.model.access.csv
@@ -0,0 +1,4 @@
+"id","name","model_id:id","group_id:id","perm_read","perm_write","perm_create","perm_unlink"
+"access_openupgrade_record","openupgrade.record all","model_openupgrade_record",,1,0,0,0
+"access_openupgrade_attribute","openupgrade.attribute all","model_openupgrade_attribute",,1,0,0,0
+"access_openupgrade_comparison_config","openupgrade.comparison.config","model_openupgrade_comparison_config",base.group_system,1,1,1,1
diff --git a/upgrade_analysis/views/analysis_wizard.xml b/upgrade_analysis/views/analysis_wizard.xml
new file mode 100644
index 000000000..efaa5294f
--- /dev/null
+++ b/upgrade_analysis/views/analysis_wizard.xml
@@ -0,0 +1,36 @@
+
+
+
+
+ view.openupgrade.analysis_wizard.form
+ openupgrade.analysis.wizard
+
+
+
+
+
+
diff --git a/upgrade_analysis/views/comparison_config.xml b/upgrade_analysis/views/comparison_config.xml
new file mode 100644
index 000000000..db0ae7770
--- /dev/null
+++ b/upgrade_analysis/views/comparison_config.xml
@@ -0,0 +1,77 @@
+
+
+
+
+ view.openupgrade.comparison_config.tree
+ openupgrade.comparison.config
+
+
+
+
+
+
+
+
+
+
+
+
+ view.openupgrade.comparison_config.form
+ openupgrade.comparison.config
+
+
+
+
+)
+
+ OpenUpgrade Comparison Configs
+ ir.actions.act_window
+ openupgrade.comparison.config
+
+
+
+
+
diff --git a/upgrade_analysis/views/generate_records_wizard.xml b/upgrade_analysis/views/generate_records_wizard.xml
new file mode 100644
index 000000000..18dd59812
--- /dev/null
+++ b/upgrade_analysis/views/generate_records_wizard.xml
@@ -0,0 +1,47 @@
+
+
+
+
+ view.openupgrade.generate_records_wizard.form
+ openupgrade.generate.records.wizard
+
+
+
+
+
+
+ Generate Records
+ ir.actions.act_window
+ openupgrade.generate.records.wizard
+ form,tree
+ new
+
+
+
+
+
diff --git a/upgrade_analysis/views/install_all_wizard.xml b/upgrade_analysis/views/install_all_wizard.xml
new file mode 100644
index 000000000..73188afb2
--- /dev/null
+++ b/upgrade_analysis/views/install_all_wizard.xml
@@ -0,0 +1,48 @@
+
+
+
+
+ view.openupgrade.install_all_wizard.form
+ openupgrade.install.all.wizard
+
+
+
+
+
+
+ Install All Modules
+ ir.actions.act_window
+ openupgrade.install.all.wizard
+ form,tree
+ new
+
+
+
+
+
diff --git a/upgrade_analysis/views/openupgrade_record.xml b/upgrade_analysis/views/openupgrade_record.xml
new file mode 100644
index 000000000..a8d683d95
--- /dev/null
+++ b/upgrade_analysis/views/openupgrade_record.xml
@@ -0,0 +1,96 @@
+
+
+
+
+
+
+
+ Search view for openupgrade records
+ openupgrade.record
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ view.openupgrade.record.tree
+ openupgrade.record
+
+
+
+
+
+
+
+
+
+
+
+
+
+ view.openupgrade.record.form
+ openupgrade.record
+
+
+
+
+
+
+ OpenUpgrade Records
+ ir.actions.act_window
+ openupgrade.record
+
+
+
+
+
From 3a3ae2f8d8a8dd4c7b74993b07dda9fe08fe501a Mon Sep 17 00:00:00 2001
From: Sylvain LE GAL
Date: Fri, 6 Nov 2020 22:44:54 +0100
Subject: [PATCH 03/67] [REF] rename files, apply OCA convention, remove
obsolete 6.1 syntax, make the module installable, add readme folders
---
upgrade_analysis/README.rst | 65 +--
upgrade_analysis/__init__.py | 3 +
upgrade_analysis/__manifest__.py | 17 +-
upgrade_analysis/apriori.py | 97 +---
upgrade_analysis/compare.py | 456 ++++++++++--------
upgrade_analysis/models/__init__.py | 8 +-
upgrade_analysis/models/upgrade_attribute.py | 20 +
...config.py => upgrade_comparison_config.py} | 30 +-
...penupgrade_record.py => upgrade_record.py} | 35 +-
upgrade_analysis/readme/CONTRIBUTORS.rst | 7 +
upgrade_analysis/readme/DESCRIPTION.rst | 1 +
upgrade_analysis/readme/ROADMAP.rst | 3 +
upgrade_analysis/readme/USAGE.rst | 0
upgrade_analysis/security/ir.model.access.csv | 11 +-
upgrade_analysis/views/menu.xml | 12 +
...xml => view_upgrade_comparison_config.xml} | 33 +-
...ade_record.xml => view_upgrade_record.xml} | 39 +-
upgrade_analysis/wizards/__init__.py | 3 +
.../upgrade_analysis_wizard.py} | 24 +-
.../upgrade_generate_record_wizard.py} | 18 +-
.../upgrade_install_wizard.py} | 8 +-
.../view_upgrade_analysis_wizard.xml} | 9 +-
.../view_upgrade_generate_record_wizard.xml} | 19 +-
.../view_upgrade_install_wizard.xml} | 21 +-
24 files changed, 441 insertions(+), 498 deletions(-)
create mode 100644 upgrade_analysis/models/upgrade_attribute.py
rename upgrade_analysis/models/{comparison_config.py => upgrade_comparison_config.py} (80%)
rename upgrade_analysis/models/{openupgrade_record.py => upgrade_record.py} (85%)
create mode 100644 upgrade_analysis/readme/CONTRIBUTORS.rst
create mode 100644 upgrade_analysis/readme/DESCRIPTION.rst
create mode 100644 upgrade_analysis/readme/ROADMAP.rst
create mode 100644 upgrade_analysis/readme/USAGE.rst
create mode 100644 upgrade_analysis/views/menu.xml
rename upgrade_analysis/views/{comparison_config.xml => view_upgrade_comparison_config.xml} (63%)
rename upgrade_analysis/views/{openupgrade_record.xml => view_upgrade_record.xml} (65%)
create mode 100644 upgrade_analysis/wizards/__init__.py
rename upgrade_analysis/{models/analysis_wizard.py => wizards/upgrade_analysis_wizard.py} (90%)
rename upgrade_analysis/{models/generate_records_wizard.py => wizards/upgrade_generate_record_wizard.py} (88%)
rename upgrade_analysis/{models/install_all_wizard.py => wizards/upgrade_install_wizard.py} (89%)
rename upgrade_analysis/{views/analysis_wizard.xml => wizards/view_upgrade_analysis_wizard.xml} (74%)
rename upgrade_analysis/{views/generate_records_wizard.xml => wizards/view_upgrade_generate_record_wizard.xml} (65%)
rename upgrade_analysis/{views/install_all_wizard.xml => wizards/view_upgrade_install_wizard.xml} (65%)
diff --git a/upgrade_analysis/README.rst b/upgrade_analysis/README.rst
index f3d1c48de..2b99745a8 100644
--- a/upgrade_analysis/README.rst
+++ b/upgrade_analysis/README.rst
@@ -1,59 +1,8 @@
-.. image:: https://img.shields.io/badge/license-AGPL--3-blue.png
- :target: https://www.gnu.org/licenses/agpl
- :alt: License: AGPL-3
+================
+Upgrade Analysis
+================
-===============================
-OpenUpgrade Database Comparison
-===============================
-
-This module provides the tool to generate the database analysis files that indicate how the Odoo data model and module data have changed between two versions of Odoo. Database analysis files for the core modules are included in the OpenUpgrade distribution so as a migration script developer you will not usually need to use this tool yourself. If you do need to run your analysis of a custom set of modules, please refer to the documentation here: https://doc.therp.nl/openupgrade/analysis.html
-
-Installation
-============
-
-This module has a python dependency on openerp-client-lib. You need to make this module available in your Python environment, for instance by installing it with the pip tool.
-
-Known issues / Roadmap
-======================
-
-* scripts/compare_noupdate_xml_records.py should be integrated in the analysis process (#590)
-* Log removed modules in the module that owned them (#468)
-* Detect renamed many2many tables (#213)
-
-Bug Tracker
-===========
-
-Bugs are tracked on `GitHub Issues
-`_. In case of trouble, please
-check there if your issue has already been reported. If you spotted it first,
-help us smash it by providing detailed and welcomed feedback.
-
-Images
-------
-
-* Odoo Community Association: `Icon `_.
-
-Contributors
-------------
-
-* Stefan Rijnhart
-* Holger Brunn
-* Pedro M. Baeza
-* Ferdinand Gassauer
-* Florent Xicluna
-* Miquel Raïch
-
-Maintainer
-----------
-
-.. image:: https://odoo-community.org/logo.png
- :alt: Odoo Community Association
- :target: https://odoo-community.org
-
-This module is maintained by the OCA.
-
-OCA, or the Odoo Community Association, is a nonprofit organization whose
-mission is to support the collaborative development of Odoo features and
-promote its widespread use.
-
-To contribute to this module, please visit https://odoo-community.org.
+.. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+ !! This file is generated by oca-gen-addon-readme !!
+ !! changes will be overwritten. !!
+ !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
diff --git a/upgrade_analysis/__init__.py b/upgrade_analysis/__init__.py
index c102a8ca6..abe0f8c3c 100644
--- a/upgrade_analysis/__init__.py
+++ b/upgrade_analysis/__init__.py
@@ -1,2 +1,5 @@
from . import models
+from . import wizards
from . import blacklist
+from . import apriori
+from . import compare
diff --git a/upgrade_analysis/__manifest__.py b/upgrade_analysis/__manifest__.py
index 79ebfc939..1a83113a1 100644
--- a/upgrade_analysis/__manifest__.py
+++ b/upgrade_analysis/__manifest__.py
@@ -2,18 +2,21 @@
# Copyright 2016 Opener B.V.
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
{
- "name": "OpenUpgrade Records",
+ "name": "Upgrade Analysis",
+ "summary": "performs a difference analysis between modules"
+ " installed on two different Odoo instances",
"version": "14.0.1.0.0",
"category": "Migration",
- "author": "Therp BV, Opener B.V., Odoo Community Association (OCA)",
+ "author": "Therp BV, Opener B.V., GRAP, Odoo Community Association (OCA)",
"website": "https://github.com/OCA/server-tools",
"data": [
- "views/openupgrade_record.xml",
- "views/comparison_config.xml",
- "views/analysis_wizard.xml",
- "views/generate_records_wizard.xml",
- "views/install_all_wizard.xml",
"security/ir.model.access.csv",
+ "views/menu.xml",
+ "views/view_upgrade_comparison_config.xml",
+ "views/view_upgrade_record.xml",
+ "wizards/view_upgrade_analysis_wizard.xml",
+ "wizards/view_upgrade_generate_record_wizard.xml",
+ "wizards/view_upgrade_install_wizard.xml",
],
"installable": True,
"external_dependencies": {
diff --git a/upgrade_analysis/apriori.py b/upgrade_analysis/apriori.py
index 973300fa0..2e5883191 100644
--- a/upgrade_analysis/apriori.py
+++ b/upgrade_analysis/apriori.py
@@ -2,97 +2,12 @@
to help the matching process
"""
-renamed_modules = {
- # Odoo
- 'crm_reveal': 'crm_iap_lead',
- 'document': 'attachment_indexation',
- 'payment_ogone': 'payment_ingenico',
- # OCA/hr
- # TODO: Transform possible data
- 'hr_skill': 'hr_skills'
-}
+renamed_modules = {}
-merged_modules = {
- # Odoo
- 'account_cancel': 'account',
- 'account_voucher': 'account',
- 'crm_phone_validation': 'crm',
- 'decimal_precision': 'base',
- 'delivery_hs_code': 'delivery',
- 'hw_scale': 'hw_drivers',
- 'hw_scanner': 'hw_drivers',
- 'hw_screen': 'hw_drivers',
- 'l10n_fr_certification': 'account',
- 'l10n_fr_sale_closing': 'l10n_fr',
- 'mrp_bom_cost': 'mrp_account',
- 'mrp_byproduct': 'mrp',
- 'payment_stripe_sca': 'payment_stripe',
- 'stock_zebra': 'stock',
- 'survey_crm': 'survey',
- 'test_pylint': 'test_lint',
- 'web_settings_dashboard': 'base_setup',
- 'website_crm_phone_validation': 'website_crm',
- 'website_sale_link_tracker': 'website_sale',
- 'website_survey': 'survey',
- # OCA/account-financial-tools
- 'account_move_chatter': 'account',
- # OCA/account-reconcile
- 'account_set_reconcilable': 'account',
- # OCA/l10n-spain
- 'l10n_es_aeat_sii': 'l10n_es_aeat_sii_oca',
- # OCA/server-backend
- 'base_suspend_security': 'base',
- # OCA/social
- 'mass_mailing_unique': 'mass_mailing',
- # OCA/timesheet
- 'sale_timesheet_existing_project': 'sale_timesheet',
- # OCA/web
- 'web_favicon': 'base',
- 'web_widget_color': 'web',
- 'web_widget_many2many_tags_multi_selection': 'web',
- # OCA/website
- 'website_canonical_url': 'website',
- 'website_logo': 'website',
-}
+merged_modules = {}
-# only used here for openupgrade_records analysis:
-renamed_models = {
- # Odoo
- 'account.register.payments': 'account.payment.register',
- 'crm.reveal.industry': 'crm.iap.lead.industry',
- 'crm.reveal.role': 'crm.iap.lead.role',
- 'crm.reveal.seniority': 'crm.iap.lead.seniority',
- 'mail.blacklist.mixin': 'mail.thread.blacklist',
- 'mail.mail.statistics': 'mailing.trace',
- 'mail.statistics.report': 'mailing.trace.report',
- 'mail.mass_mailing': 'mailing.mailing',
- 'mail.mass_mailing.contact': 'mailing.contact',
- 'mail.mass_mailing.list': 'mailing.list',
- 'mail.mass_mailing.list_contact_rel': 'mailing.contact.subscription',
- 'mail.mass_mailing.stage': 'utm.stage',
- 'mail.mass_mailing.tag': 'utm.tag',
- 'mail.mass_mailing.test': 'mailing.mailing.test',
- 'mass.mailing.list.merge': 'mailing.list.merge',
- 'mass.mailing.schedule.date': 'mailing.mailing.schedule.date',
- 'mrp.subproduct': 'mrp.bom.byproduct',
- 'sms.send_sms': 'sms.composer',
- 'stock.fixed.putaway.strat': 'stock.putaway.rule',
- 'survey.mail.compose.message': 'survey.invite',
- 'website.redirect': 'website.rewrite',
- # OCA/...
-}
+# only used here for upgrade_analysis
+renamed_models = {}
-# only used here for openupgrade_records analysis:
-merged_models = {
- # Odoo
- 'account.invoice': 'account.move',
- 'account.invoice.line': 'account.move.line',
- 'account.invoice.tax': 'account.move.line',
- 'account.voucher': 'account.move',
- 'account.voucher.line': 'account.move.line',
- 'lunch.order.line': 'lunch.order',
- 'mail.mass_mailing.campaign': 'utm.campaign',
- 'slide.category': 'slide.slide',
- 'survey.page': 'survey.question',
- # OCA/...
-}
+# only used here for upgrade_analysis
+merged_models = {}
diff --git a/upgrade_analysis/compare.py b/upgrade_analysis/compare.py
index 52ac7bbe8..6af14263d 100644
--- a/upgrade_analysis/compare.py
+++ b/upgrade_analysis/compare.py
@@ -1,7 +1,7 @@
-# coding: utf-8
# Copyright 2011-2015 Therp BV
# Copyright 2015-2016 Opener B.V.
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
+# flake8: noqa: C901
#####################################################################
# library providing a function to analyse two progressive database
@@ -11,12 +11,13 @@
import collections
import copy
-from odoo.addons.openupgrade_records.lib import apriori
+from . import apriori
def module_map(module):
return apriori.renamed_modules.get(
- module, apriori.merged_modules.get(module, module))
+ module, apriori.merged_modules.get(module, module)
+ )
def model_rename_map(model):
@@ -24,8 +25,7 @@ def model_rename_map(model):
def model_map(model):
- return apriori.renamed_models.get(
- model, apriori.merged_models.get(model, model))
+ return apriori.renamed_models.get(model, apriori.merged_models.get(model, model))
def inv_model_map(model):
@@ -34,12 +34,12 @@ def inv_model_map(model):
IGNORE_FIELDS = [
- 'create_date',
- 'create_uid',
- 'id',
- 'write_date',
- 'write_uid',
- ]
+ "create_date",
+ "create_uid",
+ "id",
+ "write_date",
+ "write_uid",
+]
def compare_records(dict_old, dict_new, fields):
@@ -51,17 +51,19 @@ def compare_records(dict_old, dict_new, fields):
Return True of False.
"""
for field in fields:
- if field == 'module':
- if module_map(dict_old['module']) != dict_new['module']:
+ if field == "module":
+ if module_map(dict_old["module"]) != dict_new["module"]:
return False
- elif field == 'model':
- if model_rename_map(dict_old['model']) != dict_new['model']:
+ elif field == "model":
+ if model_rename_map(dict_old["model"]) != dict_new["model"]:
return False
- elif field == 'other_prefix':
- if dict_old['module'] != dict_old['prefix'] or \
- dict_new['module'] != dict_new['prefix']:
+ elif field == "other_prefix":
+ if (
+ dict_old["module"] != dict_old["prefix"]
+ or dict_new["module"] != dict_new["prefix"]
+ ):
return False
- if dict_old['model'] == 'ir.ui.view':
+ if dict_old["model"] == "ir.ui.view":
# basically, to avoid the assets_backend case
return False
elif dict_old[field] != dict_new[field]:
@@ -80,71 +82,69 @@ def search(item, item_list, fields):
continue
return other
# search for renamed fields
- if 'field' in fields:
+ if "field" in fields:
for other in item_list:
- if not item['field'] or item['field'] is not None or \
- item['isproperty']:
+ if not item["field"] or item["field"] is not None or item["isproperty"]:
continue
- if compare_records(
- dict(item, field=other['field']), other, fields):
+ if compare_records(dict(item, field=other["field"]), other, fields):
return other
return None
def fieldprint(old, new, field, text, reprs):
- fieldrepr = "%s (%s)" % (old['field'], old['type'])
- fullrepr = '%-12s / %-24s / %-30s' % (
- old['module'], old['model'], fieldrepr)
+ fieldrepr = "{} ({})".format(old["field"], old["type"])
+ fullrepr = "{:<12} / {:<24} / {:<30}".format(old["module"], old["model"], fieldrepr)
if not text:
- text = "%s is now '%s' ('%s')" % (field, new[field], old[field])
- if field == 'relation':
- text += ' [nothing to do]'
- reprs[module_map(old['module'])].append("%s: %s" % (fullrepr, text))
- if field == 'module':
+ text = "{} is now '{}' ('{}')".format(field, new[field], old[field])
+ if field == "relation":
+ text += " [nothing to do]"
+ reprs[module_map(old["module"])].append("{}: {}".format(fullrepr, text))
+ if field == "module":
text = "previously in module %s" % old[field]
- fullrepr = '%-12s / %-24s / %-30s' % (
- new['module'], old['model'], fieldrepr)
- reprs[module_map(new['module'])].append("%s: %s" % (fullrepr, text))
+ fullrepr = "{:<12} / {:<24} / {:<30}".format(
+ new["module"], old["model"], fieldrepr
+ )
+ reprs[module_map(new["module"])].append("{}: {}".format(fullrepr, text))
def report_generic(new, old, attrs, reprs):
for attr in attrs:
- if attr == 'required':
- if old[attr] != new['required'] and new['required']:
+ if attr == "required":
+ if old[attr] != new["required"] and new["required"]:
text = "now required"
- if new['req_default']:
- text += ', req_default: %s' % new['req_default']
- fieldprint(old, new, '', text, reprs)
- elif attr == 'stored':
+ if new["req_default"]:
+ text += ", req_default: %s" % new["req_default"]
+ fieldprint(old, new, "", text, reprs)
+ elif attr == "stored":
if old[attr] != new[attr]:
- if new['stored']:
+ if new["stored"]:
text = "is now stored"
else:
text = "not stored anymore"
- fieldprint(old, new, '', text, reprs)
- elif attr == 'isfunction':
+ fieldprint(old, new, "", text, reprs)
+ elif attr == "isfunction":
if old[attr] != new[attr]:
- if new['isfunction']:
+ if new["isfunction"]:
text = "now a function"
else:
text = "not a function anymore"
- fieldprint(old, new, '', text, reprs)
- elif attr == 'isproperty':
+ fieldprint(old, new, "", text, reprs)
+ elif attr == "isproperty":
if old[attr] != new[attr]:
if new[attr]:
text = "now a property"
else:
text = "not a property anymore"
- fieldprint(old, new, '', text, reprs)
- elif attr == 'isrelated':
+ fieldprint(old, new, "", text, reprs)
+ elif attr == "isrelated":
if old[attr] != new[attr]:
if new[attr]:
text = "now related"
else:
text = "not related anymore"
- fieldprint(old, new, '', text, reprs)
+ fieldprint(old, new, "", text, reprs)
elif old[attr] != new[attr]:
- fieldprint(old, new, attr, '', reprs)
+ fieldprint(old, new, attr, "", reprs)
def compare_sets(old_records, new_records):
@@ -160,7 +160,7 @@ def compare_sets(old_records, new_records):
def clean_records(records):
result = []
for record in records:
- if record['field'] not in IGNORE_FIELDS:
+ if record["field"] not in IGNORE_FIELDS:
result.append(record)
return result
@@ -168,8 +168,8 @@ def compare_sets(old_records, new_records):
new_records = clean_records(new_records)
origlen = len(old_records)
- new_models = set([column['model'] for column in new_records])
- old_models = set([column['model'] for column in old_records])
+ new_models = {column["model"] for column in new_records}
+ old_models = {column["model"] for column in old_records}
matched_direct = 0
matched_other_module = 0
@@ -184,7 +184,7 @@ def compare_sets(old_records, new_records):
non_obsolete_old_records = []
for column in copy.copy(old_records):
- if column['model'] in obsolete_models:
+ if column["model"] in obsolete_models:
in_obsolete_models += 1
else:
non_obsolete_old_records.append(column)
@@ -205,152 +205,193 @@ def compare_sets(old_records, new_records):
return count
matched_direct = match(
- ['module', 'mode', 'model', 'field'],
- ['relation', 'type', 'selection_keys', 'inherits', 'stored',
- 'isfunction', 'isrelated', 'required', 'table'])
+ ["module", "mode", "model", "field"],
+ [
+ "relation",
+ "type",
+ "selection_keys",
+ "inherits",
+ "stored",
+ "isfunction",
+ "isrelated",
+ "required",
+ "table",
+ ],
+ )
# other module, same type and operation
matched_other_module = match(
- ['mode', 'model', 'field', 'type'],
- ['module', 'relation', 'selection_keys', 'inherits', 'stored',
- 'isfunction', 'isrelated', 'required', 'table'])
+ ["mode", "model", "field", "type"],
+ [
+ "module",
+ "relation",
+ "selection_keys",
+ "inherits",
+ "stored",
+ "isfunction",
+ "isrelated",
+ "required",
+ "table",
+ ],
+ )
# other module, same operation, other type
matched_other_type = match(
- ['mode', 'model', 'field'],
- ['relation', 'type', 'selection_keys', 'inherits', 'stored',
- 'isfunction', 'isrelated', 'required', 'table'])
+ ["mode", "model", "field"],
+ [
+ "relation",
+ "type",
+ "selection_keys",
+ "inherits",
+ "stored",
+ "isfunction",
+ "isrelated",
+ "required",
+ "table",
+ ],
+ )
printkeys = [
- 'relation', 'required', 'selection_keys',
- 'req_default', 'inherits', 'mode', 'attachment',
- ]
+ "relation",
+ "required",
+ "selection_keys",
+ "req_default",
+ "inherits",
+ "mode",
+ "attachment",
+ ]
for column in old_records:
# we do not care about removed non stored function fields
- if not column['stored'] and (
- column['isfunction'] or column['isrelated']):
+ if not column["stored"] and (column["isfunction"] or column["isrelated"]):
continue
- if column['mode'] == 'create':
- column['mode'] = ''
+ if column["mode"] == "create":
+ column["mode"] = ""
extra_message = ", ".join(
- [k + ': ' + str(column[k]) if k != str(column[k]) else k
- for k in printkeys if column[k]]
+ [
+ k + ": " + str(column[k]) if k != str(column[k]) else k
+ for k in printkeys
+ if column[k]
+ ]
)
if extra_message:
extra_message = " " + extra_message
- fieldprint(
- column, '', '', "DEL" + extra_message, reprs)
+ fieldprint(column, "", "", "DEL" + extra_message, reprs)
- printkeys.extend([
- 'hasdefault',
- ])
+ printkeys.extend(
+ [
+ "hasdefault",
+ ]
+ )
for column in new_records:
# we do not care about newly added non stored function fields
- if not column['stored'] and (
- column['isfunction'] or column['isrelated']):
+ if not column["stored"] and (column["isfunction"] or column["isrelated"]):
continue
- if column['mode'] == 'create':
- column['mode'] = ''
+ if column["mode"] == "create":
+ column["mode"] = ""
printkeys_plus = printkeys.copy()
- if column['isfunction'] or column['isrelated']:
- printkeys_plus.extend(['isfunction', 'isrelated', 'stored'])
+ if column["isfunction"] or column["isrelated"]:
+ printkeys_plus.extend(["isfunction", "isrelated", "stored"])
extra_message = ", ".join(
- [k + ': ' + str(column[k]) if k != str(column[k]) else k
- for k in printkeys_plus if column[k]]
+ [
+ k + ": " + str(column[k]) if k != str(column[k]) else k
+ for k in printkeys_plus
+ if column[k]
+ ]
)
if extra_message:
extra_message = " " + extra_message
- fieldprint(
- column, '', '', "NEW" + extra_message, reprs)
+ fieldprint(column, "", "", "NEW" + extra_message, reprs)
for line in [
- "# %d fields matched," % (origlen - len(old_records)),
- "# Direct match: %d" % matched_direct,
- "# Found in other module: %d" % matched_other_module,
- "# Found with different type: %d" % matched_other_type,
- "# In obsolete models: %d" % in_obsolete_models,
- "# Not matched: %d" % len(old_records),
- "# New columns: %d" % len(new_records)
- ]:
- reprs['general'].append(line)
+ "# %d fields matched," % (origlen - len(old_records)),
+ "# Direct match: %d" % matched_direct,
+ "# Found in other module: %d" % matched_other_module,
+ "# Found with different type: %d" % matched_other_type,
+ "# In obsolete models: %d" % in_obsolete_models,
+ "# Not matched: %d" % len(old_records),
+ "# New columns: %d" % len(new_records),
+ ]:
+ reprs["general"].append(line)
return reprs
def compare_xml_sets(old_records, new_records):
reprs = collections.defaultdict(list)
- def match(match_fields, match_type='direct'):
+ def match(match_fields, match_type="direct"):
matched_records = []
for column in copy.copy(old_records):
found = search(column, new_records, match_fields)
if found:
old_records.remove(column)
new_records.remove(found)
- if match_type != 'direct':
- column['old'] = True
- found['new'] = True
- column[match_type] = found['module']
- found[match_type] = column['module']
- found['domain'] = column['domain'] != found['domain'] and \
- column['domain'] != '[]' and found['domain'] is False
- column['domain'] = False
- column['noupdate_switched'] = False
- found['noupdate_switched'] = \
- column['noupdate'] != found['noupdate']
- if match_type != 'direct':
+ if match_type != "direct":
+ column["old"] = True
+ found["new"] = True
+ column[match_type] = found["module"]
+ found[match_type] = column["module"]
+ found["domain"] = (
+ column["domain"] != found["domain"]
+ and column["domain"] != "[]"
+ and found["domain"] is False
+ )
+ column["domain"] = False
+ column["noupdate_switched"] = False
+ found["noupdate_switched"] = column["noupdate"] != found["noupdate"]
+ if match_type != "direct":
matched_records.append(column)
matched_records.append(found)
- elif (match_type == 'direct' and found['domain']) or \
- found['noupdate_switched']:
+ elif (match_type == "direct" and found["domain"]) or found[
+ "noupdate_switched"
+ ]:
matched_records.append(found)
return matched_records
# direct match
- modified_records = match(['module', 'model', 'name'])
+ modified_records = match(["module", "model", "name"])
# other module, same full xmlid
- moved_records = match(['model', 'name'], 'moved')
+ moved_records = match(["model", "name"], "moved")
# other module, same suffix, other prefix
- renamed_records = match(['model', 'suffix', 'other_prefix'], 'renamed')
+ renamed_records = match(["model", "suffix", "other_prefix"], "renamed")
for record in old_records:
- record['old'] = True
- record['domain'] = False
- record['noupdate_switched'] = False
+ record["old"] = True
+ record["domain"] = False
+ record["noupdate_switched"] = False
for record in new_records:
- record['new'] = True
- record['domain'] = False
- record['noupdate_switched'] = False
+ record["new"] = True
+ record["domain"] = False
+ record["noupdate_switched"] = False
sorted_records = sorted(
- old_records + new_records + moved_records + renamed_records +
- modified_records,
- key=lambda k: (k['model'], 'old' in k, k['name'])
+ old_records + new_records + moved_records + renamed_records + modified_records,
+ key=lambda k: (k["model"], "old" in k, k["name"]),
)
for entry in sorted_records:
- content = ''
- if 'old' in entry:
- content = 'DEL %(model)s: %(name)s' % entry
- if 'moved' in entry:
- content += ' [potentially moved to %(moved)s module]' % entry
- elif 'renamed' in entry:
- content += ' [renamed to %(renamed)s module]' % entry
- elif 'new' in entry:
- content = 'NEW %(model)s: %(name)s' % entry
- if 'moved' in entry:
- content += ' [potentially moved from %(moved)s module]' % entry
- elif 'renamed' in entry:
- content += ' [renamed from %(renamed)s module]' % entry
- if 'old' not in entry and 'new' not in entry:
- content = '%(model)s: %(name)s' % entry
- if entry['domain']:
- content += ' (deleted domain)'
- if entry['noupdate']:
- content += ' (noupdate)'
- if entry['noupdate_switched']:
- content += ' (noupdate switched)'
- reprs[module_map(entry['module'])].append(content)
+ content = ""
+ if "old" in entry:
+ content = "DEL %(model)s: %(name)s" % entry
+ if "moved" in entry:
+ content += " [potentially moved to %(moved)s module]" % entry
+ elif "renamed" in entry:
+ content += " [renamed to %(renamed)s module]" % entry
+ elif "new" in entry:
+ content = "NEW %(model)s: %(name)s" % entry
+ if "moved" in entry:
+ content += " [potentially moved from %(moved)s module]" % entry
+ elif "renamed" in entry:
+ content += " [renamed from %(renamed)s module]" % entry
+ if "old" not in entry and "new" not in entry:
+ content = "%(model)s: %(name)s" % entry
+ if entry["domain"]:
+ content += " (deleted domain)"
+ if entry["noupdate"]:
+ content += " (noupdate)"
+ if entry["noupdate_switched"]:
+ content += " (noupdate switched)"
+ reprs[module_map(entry["module"])].append(content)
return reprs
@@ -360,79 +401,84 @@ def compare_model_sets(old_records, new_records):
"""
reprs = collections.defaultdict(list)
- new_models = {column['model']: column['module'] for column in new_records}
- old_models = {column['model']: column['module'] for column in old_records}
+ new_models = {column["model"]: column["module"] for column in new_records}
+ old_models = {column["model"]: column["module"] for column in old_records}
obsolete_models = []
for column in copy.copy(old_records):
- model = column['model']
+ model = column["model"]
if model in old_models:
if model not in new_models:
if model_map(model) not in new_models:
obsolete_models.append(model)
- text = 'obsolete model %s' % model
- if column['model_type']:
- text += " [%s]" % column['model_type']
- reprs[module_map(column['module'])].append(text)
- reprs['general'].append('obsolete model %s [module %s]' % (
- model, module_map(column['module'])))
+ text = "obsolete model %s" % model
+ if column["model_type"]:
+ text += " [%s]" % column["model_type"]
+ reprs[module_map(column["module"])].append(text)
+ reprs["general"].append(
+ "obsolete model %s [module %s]"
+ % (model, module_map(column["module"]))
+ )
else:
- moved_module = ''
- if module_map(column['module']) != new_models[model_map(
- model)]:
- moved_module = ' in module %s' % new_models[model_map(
- model)]
- text = 'obsolete model %s (renamed to %s%s)' % (
- model, model_map(model), moved_module)
- if column['model_type']:
- text += " [%s]" % column['model_type']
- reprs[module_map(column['module'])].append(text)
- reprs['general'].append(
- 'obsolete model %s (renamed to %s) [module %s]' % (
- model, model_map(model),
- module_map(column['module'])))
+ moved_module = ""
+ if module_map(column["module"]) != new_models[model_map(model)]:
+ moved_module = " in module %s" % new_models[model_map(model)]
+ text = "obsolete model {} (renamed to {}{})".format(
+ model,
+ model_map(model),
+ moved_module,
+ )
+ if column["model_type"]:
+ text += " [%s]" % column["model_type"]
+ reprs[module_map(column["module"])].append(text)
+ reprs["general"].append(
+ "obsolete model %s (renamed to %s) [module %s]"
+ % (model, model_map(model), module_map(column["module"]))
+ )
else:
- if module_map(column['module']) != new_models[model]:
- text = 'model %s (moved to %s)' % (
- model, new_models[model])
- if column['model_type']:
- text += " [%s]" % column['model_type']
- reprs[module_map(column['module'])].append(text)
- text = 'model %s (moved from %s)' % (
- model, old_models[model])
- if column['model_type']:
- text += " [%s]" % column['model_type']
+ if module_map(column["module"]) != new_models[model]:
+ text = "model {} (moved to {})".format(model, new_models[model])
+ if column["model_type"]:
+ text += " [%s]" % column["model_type"]
+ reprs[module_map(column["module"])].append(text)
+ text = "model {} (moved from {})".format(model, old_models[model])
+ if column["model_type"]:
+ text += " [%s]" % column["model_type"]
for column in copy.copy(new_records):
- model = column['model']
+ model = column["model"]
if model in new_models:
if model not in old_models:
if inv_model_map(model) not in old_models:
- text = 'new model %s' % model
- if column['model_type']:
- text += " [%s]" % column['model_type']
- reprs[column['module']].append(text)
- reprs['general'].append('new model %s [module %s]' % (
- model, column['module']))
+ text = "new model %s" % model
+ if column["model_type"]:
+ text += " [%s]" % column["model_type"]
+ reprs[column["module"]].append(text)
+ reprs["general"].append(
+ "new model {} [module {}]".format(model, column["module"])
+ )
else:
- moved_module = ''
- if column['module'] != module_map(old_models[inv_model_map(
- model)]):
- moved_module = ' in module %s' % old_models[
- inv_model_map(model)]
- text = 'new model %s (renamed from %s%s)' % (
- model, inv_model_map(model), moved_module)
- if column['model_type']:
- text += " [%s]" % column['model_type']
- reprs[column['module']].append(text)
- reprs['general'].append(
- 'new model %s (renamed from %s) [module %s]' % (
- model, inv_model_map(model), column['module']))
+ moved_module = ""
+ if column["module"] != module_map(old_models[inv_model_map(model)]):
+ moved_module = (
+ " in module %s" % old_models[inv_model_map(model)]
+ )
+ text = "new model {} (renamed from {}{})".format(
+ model,
+ inv_model_map(model),
+ moved_module,
+ )
+ if column["model_type"]:
+ text += " [%s]" % column["model_type"]
+ reprs[column["module"]].append(text)
+ reprs["general"].append(
+ "new model %s (renamed from %s) [module %s]"
+ % (model, inv_model_map(model), column["module"])
+ )
else:
- if column['module'] != module_map(old_models[model]):
- text = 'model %s (moved from %s)' % (
- model, old_models[model])
- if column['model_type']:
- text += " [%s]" % column['model_type']
- reprs[column['module']].append(text)
+ if column["module"] != module_map(old_models[model]):
+ text = "model {} (moved from {})".format(model, old_models[model])
+ if column["model_type"]:
+ text += " [%s]" % column["model_type"]
+ reprs[column["module"]].append(text)
return reprs
diff --git a/upgrade_analysis/models/__init__.py b/upgrade_analysis/models/__init__.py
index 6e4458424..748d5aee0 100644
--- a/upgrade_analysis/models/__init__.py
+++ b/upgrade_analysis/models/__init__.py
@@ -1,5 +1,3 @@
-from . import openupgrade_record
-from . import comparison_config
-from . import analysis_wizard
-from . import generate_records_wizard
-from . import install_all_wizard
+from . import upgrade_comparison_config
+from . import upgrade_attribute
+from . import upgrade_record
diff --git a/upgrade_analysis/models/upgrade_attribute.py b/upgrade_analysis/models/upgrade_attribute.py
new file mode 100644
index 000000000..ce6ef46e3
--- /dev/null
+++ b/upgrade_analysis/models/upgrade_attribute.py
@@ -0,0 +1,20 @@
+# Copyright 2011-2015 Therp BV
+# Copyright 2016 Opener B.V.
+# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
+
+from odoo import fields, models
+
+
+class UpgradeAttribute(models.Model):
+ _name = "upgrade.attribute"
+ _description = "Upgrade Attribute"
+
+ name = fields.Char(readonly=True)
+
+ value = fields.Char(readonly=True)
+
+ record_id = fields.Many2one(
+ comodel_name="upgrade.record",
+ ondelete="CASCADE",
+ readonly=True,
+ )
diff --git a/upgrade_analysis/models/comparison_config.py b/upgrade_analysis/models/upgrade_comparison_config.py
similarity index 80%
rename from upgrade_analysis/models/comparison_config.py
rename to upgrade_analysis/models/upgrade_comparison_config.py
index 0e5274bdf..17d60e61f 100644
--- a/upgrade_analysis/models/comparison_config.py
+++ b/upgrade_analysis/models/upgrade_comparison_config.py
@@ -8,25 +8,25 @@ from odoo import fields, models
from odoo.exceptions import UserError
from odoo.tools.translate import _
-from ..lib import apriori
+from .. import apriori
-class OpenupgradeComparisonConfig(models.Model):
- _name = "openupgrade.comparison.config"
- _description = "OpenUpgrade Comparison Configuration"
+class UpgradeComparisonConfig(models.Model):
+ _name = "upgrade.comparison.config"
+ _description = "Upgrade Comparison Configuration"
name = fields.Char()
- server = fields.Char(required=True)
+
+ server = fields.Char(required=True, default="localhost")
+
port = fields.Integer(required=True, default=8069)
- protocol = fields.Selection(
- [("http://", "XML-RPC")],
- # ('https://', 'XML-RPC Secure')], not supported by libopenerp
- required=True,
- default="http://",
- )
+
database = fields.Char(required=True)
- username = fields.Char(required=True)
- password = fields.Char(required=True)
+
+ username = fields.Char(required=True, default="admin")
+
+ password = fields.Char(required=True, default="admin")
+
last_log = fields.Text()
def get_connection(self):
@@ -51,8 +51,8 @@ class OpenupgradeComparisonConfig(models.Model):
def analyze(self):
""" Run the analysis wizard """
self.ensure_one()
- wizard = self.env["openupgrade.analysis.wizard"].create(
- {"server_config": self.id}
+ wizard = self.env["upgrade.analysis.wizard"].create(
+ {"server_config_id": self.id}
)
return {
"name": wizard._description,
diff --git a/upgrade_analysis/models/openupgrade_record.py b/upgrade_analysis/models/upgrade_record.py
similarity index 85%
rename from upgrade_analysis/models/openupgrade_record.py
rename to upgrade_analysis/models/upgrade_record.py
index 80b5a8a3a..89426c308 100644
--- a/upgrade_analysis/models/openupgrade_record.py
+++ b/upgrade_analysis/models/upgrade_record.py
@@ -5,27 +5,18 @@
from odoo import api, fields, models
-class Attribute(models.Model):
- _name = "openupgrade.attribute"
- _description = "OpenUpgrade Attribute"
+class UpgradeRecord(models.Model):
+ _name = "upgrade.record"
+ _description = "Upgrade Record"
name = fields.Char(readonly=True)
- value = fields.Char(readonly=True)
- record_id = fields.Many2one(
- "openupgrade.record",
- ondelete="CASCADE",
- readonly=True,
- )
-
-class Record(models.Model):
- _name = "openupgrade.record"
- _description = "OpenUpgrade Record"
-
- name = fields.Char(readonly=True)
module = fields.Char(readonly=True)
+
model = fields.Char(readonly=True)
+
field = fields.Char(readonly=True)
+
mode = fields.Selection(
[("create", "Create"), ("modify", "Modify")],
help="Set to Create if a field is newly created "
@@ -33,16 +24,26 @@ class Record(models.Model):
"existing field, set to Modify.",
readonly=True,
)
- type = fields.Selection( # Uh oh, reserved keyword
+
+ type = fields.Selection(
[("field", "Field"), ("xmlid", "XML ID"), ("model", "Model")],
readonly=True,
)
- attribute_ids = fields.One2many("openupgrade.attribute", "record_id", readonly=True)
+
+ attribute_ids = fields.One2many(
+ comodel_name="upgrade.attribute", inverse_name="record_id", readonly=True
+ )
+
noupdate = fields.Boolean(readonly=True)
+
domain = fields.Char(readonly=True)
+
prefix = fields.Char(compute="_compute_prefix_and_suffix")
+
suffix = fields.Char(compute="_compute_prefix_and_suffix")
+
model_original_module = fields.Char(compute="_compute_model_original_module")
+
model_type = fields.Char(compute="_compute_model_type")
@api.depends("name")
diff --git a/upgrade_analysis/readme/CONTRIBUTORS.rst b/upgrade_analysis/readme/CONTRIBUTORS.rst
new file mode 100644
index 000000000..5de0e93e5
--- /dev/null
+++ b/upgrade_analysis/readme/CONTRIBUTORS.rst
@@ -0,0 +1,7 @@
+* Stefan Rijnhart
+* Holger Brunn
+* Pedro M. Baeza
+* Ferdinand Gassauer
+* Florent Xicluna
+* Miquel Raïch
+* Sylvain LE GAL
diff --git a/upgrade_analysis/readme/DESCRIPTION.rst b/upgrade_analysis/readme/DESCRIPTION.rst
new file mode 100644
index 000000000..ff1a57292
--- /dev/null
+++ b/upgrade_analysis/readme/DESCRIPTION.rst
@@ -0,0 +1 @@
+This module provides the tool to generate the database analysis files that indicate how the Odoo data model and module data have changed between two versions of Odoo. Database analysis files for the core modules are included in the OpenUpgrade distribution so as a migration script developer you will not usually need to use this tool yourself. If you do need to run your analysis of a custom set of modules, please refer to the documentation here: https://doc.therp.nl/openupgrade/analysis.html
diff --git a/upgrade_analysis/readme/ROADMAP.rst b/upgrade_analysis/readme/ROADMAP.rst
new file mode 100644
index 000000000..734c22444
--- /dev/null
+++ b/upgrade_analysis/readme/ROADMAP.rst
@@ -0,0 +1,3 @@
+* scripts/compare_noupdate_xml_records.py should be integrated in the analysis process (#590)
+* Log removed modules in the module that owned them (#468)
+* Detect renamed many2many tables (#213)
diff --git a/upgrade_analysis/readme/USAGE.rst b/upgrade_analysis/readme/USAGE.rst
new file mode 100644
index 000000000..e69de29bb
diff --git a/upgrade_analysis/security/ir.model.access.csv b/upgrade_analysis/security/ir.model.access.csv
index 2ab5e67c1..5d835a8a9 100644
--- a/upgrade_analysis/security/ir.model.access.csv
+++ b/upgrade_analysis/security/ir.model.access.csv
@@ -1,4 +1,7 @@
-"id","name","model_id:id","group_id:id","perm_read","perm_write","perm_create","perm_unlink"
-"access_openupgrade_record","openupgrade.record all","model_openupgrade_record",,1,0,0,0
-"access_openupgrade_attribute","openupgrade.attribute all","model_openupgrade_attribute",,1,0,0,0
-"access_openupgrade_comparison_config","openupgrade.comparison.config","model_openupgrade_comparison_config",base.group_system,1,1,1,1
+id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
+access_upgrade_record,upgrade.record all,model_upgrade_record,,1,0,0,0
+access_upgrade_attribute,upgrade.attribute all,model_upgrade_attribute,,1,0,0,0
+access_upgrade_comparison_config,upgrade.comparison.config,model_upgrade_comparison_config,base.group_system,1,1,1,1
+access_upgrade_analysis_wizard,access_upgrade_analysis_wizard,model_upgrade_analysis_wizard,base.group_system,1,1,1,1
+access_upgrade_generate_record_wizard,access_upgrade_generate_record_wizard,model_upgrade_generate_record_wizard,base.group_system,1,1,1,1
+access_upgrade_install_wizard,access_upgrade_install_wizard,model_upgrade_install_wizard,base.group_system,1,1,1,1
diff --git a/upgrade_analysis/views/menu.xml b/upgrade_analysis/views/menu.xml
new file mode 100644
index 000000000..12d44779d
--- /dev/null
+++ b/upgrade_analysis/views/menu.xml
@@ -0,0 +1,12 @@
+
+
+
+
+
+
+
diff --git a/upgrade_analysis/views/comparison_config.xml b/upgrade_analysis/views/view_upgrade_comparison_config.xml
similarity index 63%
rename from upgrade_analysis/views/comparison_config.xml
rename to upgrade_analysis/views/view_upgrade_comparison_config.xml
index db0ae7770..9d98c47a2 100644
--- a/upgrade_analysis/views/comparison_config.xml
+++ b/upgrade_analysis/views/view_upgrade_comparison_config.xml
@@ -1,13 +1,11 @@
-
- view.openupgrade.comparison_config.tree
- openupgrade.comparison.config
+
+ upgrade.comparison.config
-
+
-
@@ -15,14 +13,12 @@
-
- view.openupgrade.comparison_config.form
- openupgrade.comparison.config
+
+ upgrade.comparison.config
-
+
-
@@ -57,21 +53,18 @@
-)
-
- OpenUpgrade Comparison Configs
+
+
+ upgrade Comparison Configs
ir.actions.act_window
- openupgrade.comparison.config
+ upgrade.comparison.config
diff --git a/upgrade_analysis/views/openupgrade_record.xml b/upgrade_analysis/views/view_upgrade_record.xml
similarity index 65%
rename from upgrade_analysis/views/openupgrade_record.xml
rename to upgrade_analysis/views/view_upgrade_record.xml
index a8d683d95..8fbd3c5c4 100644
--- a/upgrade_analysis/views/openupgrade_record.xml
+++ b/upgrade_analysis/views/view_upgrade_record.xml
@@ -1,17 +1,8 @@
-
-
-
-
- Search view for openupgrade records
- openupgrade.record
+
+ upgrade.record
@@ -39,11 +30,10 @@
-
- view.openupgrade.record.tree
- openupgrade.record
+
+ upgrade.record
-
+
@@ -54,11 +44,10 @@
-
- view.openupgrade.record.form
- openupgrade.record
+
+ upgrade.record
-
+
@@ -80,17 +69,17 @@
-
- OpenUpgrade Records
+
+ upgrade Records
ir.actions.act_window
- openupgrade.record
+ upgrade.record
diff --git a/upgrade_analysis/wizards/__init__.py b/upgrade_analysis/wizards/__init__.py
new file mode 100644
index 000000000..dffe83f41
--- /dev/null
+++ b/upgrade_analysis/wizards/__init__.py
@@ -0,0 +1,3 @@
+from . import upgrade_analysis_wizard
+from . import upgrade_generate_record_wizard
+from . import upgrade_install_wizard
diff --git a/upgrade_analysis/models/analysis_wizard.py b/upgrade_analysis/wizards/upgrade_analysis_wizard.py
similarity index 90%
rename from upgrade_analysis/models/analysis_wizard.py
rename to upgrade_analysis/wizards/upgrade_analysis_wizard.py
index 61a5e2082..82cbaab77 100644
--- a/upgrade_analysis/models/analysis_wizard.py
+++ b/upgrade_analysis/wizards/upgrade_analysis_wizard.py
@@ -8,15 +8,15 @@ import os
from odoo import fields, models
from odoo.modules import get_module_path
-from ..lib import compare
+from .. import compare
-class AnalysisWizard(models.TransientModel):
- _name = "openupgrade.analysis.wizard"
- _description = "OpenUpgrade Analysis Wizard"
+class UpgradeAnalysisWizard(models.TransientModel):
+ _name = "upgrade.analysis.wizard"
+ _description = "upgrade Analysis Wizard"
- server_config = fields.Many2one(
- "openupgrade.comparison.config", "Configuration", required=True
+ server_config_id = fields.Many2one(
+ "upgrade.comparison.config", "Configuration", required=True
)
state = fields.Selection(
[("init", "Init"), ("ready", "Ready")], readonly=True, default="init"
@@ -33,7 +33,7 @@ class AnalysisWizard(models.TransientModel):
change set
"""
- def write_file(module, version, content, filename="openupgrade_analysis.txt"):
+ def write_file(module, version, content, filename="upgrade_analysis.txt"):
module_path = get_module_path(module)
if not module_path:
return "ERROR: could not find module path:\n"
@@ -53,9 +53,9 @@ class AnalysisWizard(models.TransientModel):
return None
self.ensure_one()
- connection = self.server_config.get_connection()
- remote_record_obj = connection.env["openupgrade.record"]
- local_record_obj = self.env["openupgrade.record"]
+ connection = self.server_config_id.get_connection()
+ remote_record_obj = connection.env["upgrade.record"]
+ local_record_obj = self.env["upgrade.record"]
# Retrieve field representations and compare
remote_records = remote_record_obj.field_dump()
@@ -168,9 +168,9 @@ class AnalysisWizard(models.TransientModel):
"base",
modules["base"].installed_version,
general,
- "openupgrade_general_log.txt",
+ "upgrade_general_log.txt",
)
- self.server_config.write({"last_log": general})
+ self.server_config_id.write({"last_log": general})
self.write({"state": "ready", "log": general})
return {
diff --git a/upgrade_analysis/models/generate_records_wizard.py b/upgrade_analysis/wizards/upgrade_generate_record_wizard.py
similarity index 88%
rename from upgrade_analysis/models/generate_records_wizard.py
rename to upgrade_analysis/wizards/upgrade_generate_record_wizard.py
index b09f6839e..fc7f6c02f 100644
--- a/upgrade_analysis/models/generate_records_wizard.py
+++ b/upgrade_analysis/wizards/upgrade_generate_record_wizard.py
@@ -10,8 +10,8 @@ from odoo.modules.registry import Registry
class GenerateWizard(models.TransientModel):
- _name = "openupgrade.generate.records.wizard"
- _description = "OpenUpgrade Generate Records Wizard"
+ _name = "upgrade.generate.record.wizard"
+ _description = "Upgrade Generate Record Wizard"
_rec_name = "state"
state = fields.Selection([("init", "init"), ("ready", "ready")], default="init")
@@ -35,9 +35,9 @@ class GenerateWizard(models.TransientModel):
TODO: update module list and versions, then update all modules?"""
# Truncate the records table
if openupgrade_tools.table_exists(
- self.env.cr, "openupgrade_attribute"
- ) and openupgrade_tools.table_exists(self.env.cr, "openupgrade_record"):
- self.env.cr.execute("TRUNCATE openupgrade_attribute, openupgrade_record;")
+ self.env.cr, "upgrade_attribute"
+ ) and openupgrade_tools.table_exists(self.env.cr, "upgrade_record"):
+ self.env.cr.execute("TRUNCATE upgrade_attribute, upgrade_record;")
# Run any quirks
self.quirk_standard_calendar_attendances()
@@ -67,7 +67,7 @@ class GenerateWizard(models.TransientModel):
# Set domain property
self.env.cr.execute(
- """ UPDATE openupgrade_record our
+ """ UPDATE upgrade_record our
SET domain = iaw.domain
FROM ir_model_data imd
JOIN ir_act_window iaw ON imd.res_id = iaw.id
@@ -79,13 +79,13 @@ class GenerateWizard(models.TransientModel):
)
self.env.cache.invalidate(
[
- (self.env["openupgrade.record"]._fields["domain"], None),
+ (self.env["upgrade.record"]._fields["domain"], None),
]
)
# Set noupdate property from ir_model_data
self.env.cr.execute(
- """ UPDATE openupgrade_record our
+ """ UPDATE upgrade_record our
SET noupdate = imd.noupdate
FROM ir_model_data imd
WHERE our.type = 'xmlid'
@@ -101,7 +101,7 @@ class GenerateWizard(models.TransientModel):
# Log model records
self.env.cr.execute(
- """INSERT INTO openupgrade_record
+ """INSERT INTO upgrade_record
(module, name, model, type)
SELECT imd2.module, imd2.module || '.' || imd.name AS name,
im.model, 'model' AS type
diff --git a/upgrade_analysis/models/install_all_wizard.py b/upgrade_analysis/wizards/upgrade_install_wizard.py
similarity index 89%
rename from upgrade_analysis/models/install_all_wizard.py
rename to upgrade_analysis/wizards/upgrade_install_wizard.py
index c1085418e..4ea1d36b9 100644
--- a/upgrade_analysis/models/install_all_wizard.py
+++ b/upgrade_analysis/wizards/upgrade_install_wizard.py
@@ -9,9 +9,9 @@ from odoo.osv.expression import AND
from ..blacklist import BLACKLIST_MODULES
-class InstallAll(models.TransientModel):
- _name = "openupgrade.install.all.wizard"
- _description = "OpenUpgrade Install All Wizard"
+class UpgradeInstallWizard(models.TransientModel):
+ _name = "upgrade.install.wizard"
+ _description = "Upgrade Install Wizard"
state = fields.Selection(
[("init", "init"), ("ready", "ready")], readonly=True, default="init"
@@ -22,7 +22,7 @@ class InstallAll(models.TransientModel):
def default_get(self, fields):
"""Update module list and retrieve the number
of installable modules"""
- res = super(InstallAll, self).default_get(fields)
+ res = super().default_get(fields)
update, add = self.env["ir.module.module"].update_list()
modules = self.env["ir.module.module"].search(
[("state", "not in", ["uninstallable", "unknown"])]
diff --git a/upgrade_analysis/views/analysis_wizard.xml b/upgrade_analysis/wizards/view_upgrade_analysis_wizard.xml
similarity index 74%
rename from upgrade_analysis/views/analysis_wizard.xml
rename to upgrade_analysis/wizards/view_upgrade_analysis_wizard.xml
index efaa5294f..d988c503d 100644
--- a/upgrade_analysis/views/analysis_wizard.xml
+++ b/upgrade_analysis/wizards/view_upgrade_analysis_wizard.xml
@@ -1,13 +1,12 @@
-
- view.openupgrade.analysis_wizard.form
- openupgrade.analysis.wizard
+
+ upgrade.analysis.wizard
-
+
-
+
-
- view.openupgrade.generate_records_wizard.form
- openupgrade.generate.records.wizard
+
+ upgrade.generate.record.wizard
-
+
This will reinitialize all the modules installed on this database. Do not continue if you use this database in production.
- Modules initialized and records created
+ Modules initialized and record created
-
+
Generate Records
ir.actions.act_window
- openupgrade.generate.records.wizard
+ upgrade.generate.record.wizard
form,tree
new
diff --git a/upgrade_analysis/views/install_all_wizard.xml b/upgrade_analysis/wizards/view_upgrade_install_wizard.xml
similarity index 65%
rename from upgrade_analysis/views/install_all_wizard.xml
rename to upgrade_analysis/wizards/view_upgrade_install_wizard.xml
index 73188afb2..a6d21e537 100644
--- a/upgrade_analysis/views/install_all_wizard.xml
+++ b/upgrade_analysis/wizards/view_upgrade_install_wizard.xml
@@ -1,11 +1,10 @@
-
- view.openupgrade.install_all_wizard.form
- openupgrade.install.all.wizard
+
+ upgrade.install.wizard
-
+
-
- Install All Modules
+
+ Install Modules
ir.actions.act_window
- openupgrade.install.all.wizard
+ upgrade.install.wizard
form,tree
new
From f76ed740e518959b5fd4d51d9e8c6a7a40b5e72e Mon Sep 17 00:00:00 2001
From: Sylvain LE GAL
Date: Sat, 7 Nov 2020 00:35:37 +0100
Subject: [PATCH 04/67] [IMP] upgrade_analysis: improve install wizard to have
the possibility to select some modules, and improve filters, regarding test
module with startswith and endswith pattern
---
upgrade_analysis/__init__.py | 1 +
upgrade_analysis/blacklist.py | 17 +--
upgrade_analysis/models/__init__.py | 1 +
upgrade_analysis/models/ir_module_module.py | 35 ++++++
upgrade_analysis/tests/__init__.py | 1 +
upgrade_analysis/tests/test_module.py | 46 ++++++++
upgrade_analysis/views/menu.xml | 3 +-
.../wizards/upgrade_generate_record_wizard.py | 2 +-
.../wizards/upgrade_install_wizard.py | 103 +++++++++++++-----
.../view_upgrade_generate_record_wizard.xml | 4 +-
.../wizards/view_upgrade_install_wizard.xml | 63 +++++++++--
11 files changed, 227 insertions(+), 49 deletions(-)
create mode 100644 upgrade_analysis/models/ir_module_module.py
create mode 100644 upgrade_analysis/tests/__init__.py
create mode 100644 upgrade_analysis/tests/test_module.py
diff --git a/upgrade_analysis/__init__.py b/upgrade_analysis/__init__.py
index abe0f8c3c..338ffe995 100644
--- a/upgrade_analysis/__init__.py
+++ b/upgrade_analysis/__init__.py
@@ -1,3 +1,4 @@
+from . import odoo_patch
from . import models
from . import wizards
from . import blacklist
diff --git a/upgrade_analysis/blacklist.py b/upgrade_analysis/blacklist.py
index 814396ad6..41943d6fb 100644
--- a/upgrade_analysis/blacklist.py
+++ b/upgrade_analysis/blacklist.py
@@ -1,7 +1,10 @@
-BLACKLIST_MODULES = [
- # the hw_* modules are not affected by a migration as they don't
- # contain any ORM functionality, but they do start up threads that
- # delay the process and spit out annoying log messages continously.
- "hw_escpos",
- "hw_proxy",
-]
+BLACKLIST_MODULES = []
+
+# the hw_* modules are not affected by a migration as they don't
+# contain any ORM functionality, but they do start up threads that
+# delay the process and spit out annoying log messages continously.
+
+# We also don't want to analyze tests modules
+BLACKLIST_MODULES_STARTS_WITH = ["hw_", "test_"]
+
+BLACKLIST_MODULES_ENDS_WITH = ["_test"]
diff --git a/upgrade_analysis/models/__init__.py b/upgrade_analysis/models/__init__.py
index 748d5aee0..e0245a184 100644
--- a/upgrade_analysis/models/__init__.py
+++ b/upgrade_analysis/models/__init__.py
@@ -1,3 +1,4 @@
+from . import ir_module_module
from . import upgrade_comparison_config
from . import upgrade_attribute
from . import upgrade_record
diff --git a/upgrade_analysis/models/ir_module_module.py b/upgrade_analysis/models/ir_module_module.py
new file mode 100644
index 000000000..9456af708
--- /dev/null
+++ b/upgrade_analysis/models/ir_module_module.py
@@ -0,0 +1,35 @@
+# Copyright 2011-2015 Therp BV
+# Copyright 2016 Opener B.V.
+# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
+
+import os
+
+from odoo import fields, models
+from odoo.modules import get_module_path
+
+
+class UpgradeAttribute(models.Model):
+ _inherit = "ir.module.module"
+
+ is_odoo_module = fields.Boolean(
+ compute="_compute_is_odoo_module",
+ )
+
+ is_oca_module = fields.Boolean(compute="_compute_is_oca_module")
+
+ def _compute_is_oca_module(self):
+ for module in self:
+ if "/OCA/" in module.website:
+ module.is_oca_module = True
+ else:
+ module.is_oca_module = False
+
+ def _compute_is_odoo_module(self):
+ for module in self:
+ module_path = get_module_path(module.name)
+ absolute_repo_path = os.path.split(module_path)[0]
+ x, relative_repo_path = os.path.split(absolute_repo_path)
+ if relative_repo_path == "addons":
+ module.is_odoo_module = True
+ else:
+ module.is_odoo_module = False
diff --git a/upgrade_analysis/tests/__init__.py b/upgrade_analysis/tests/__init__.py
new file mode 100644
index 000000000..d9b96c4fa
--- /dev/null
+++ b/upgrade_analysis/tests/__init__.py
@@ -0,0 +1 @@
+from . import test_module
diff --git a/upgrade_analysis/tests/test_module.py b/upgrade_analysis/tests/test_module.py
new file mode 100644
index 000000000..85a66d9b7
--- /dev/null
+++ b/upgrade_analysis/tests/test_module.py
@@ -0,0 +1,46 @@
+from odoo.tests import common, tagged
+
+
+@tagged("post_install", "-at_install")
+class TestUpgradeAnalysis(common.TransactionCase):
+ def setUp(self):
+ super().setUp()
+ self.IrModuleModule = self.env["ir.module.module"]
+ self.product_module = self.IrModuleModule.search([("name", "=", "product")])
+ self.sale_module = self.IrModuleModule.search([("name", "=", "sale")])
+ self.upgrade_analysis = self.IrModuleModule.search(
+ [("name", "=", "upgrade_analysis")]
+ )
+
+ def test_upgrade_install_wizard(self):
+ InstallWizard = self.env["upgrade.install.wizard"]
+ wizard = InstallWizard.create({})
+
+ wizard.select_odoo_modules()
+ self.assertTrue(
+ self.product_module.id in wizard.module_ids.ids,
+ "Select Odoo module should select 'product' module",
+ )
+
+ wizard.select_oca_modules()
+ self.assertTrue(
+ self.upgrade_analysis.id in wizard.module_ids.ids,
+ "Select OCA module should select 'upgrade_analysis' module",
+ )
+
+ wizard.select_other_modules()
+ self.assertTrue(
+ self.product_module.id not in wizard.module_ids.ids,
+ "Select Other module should not select 'product' module",
+ )
+
+ wizard.unselect_modules()
+ self.assertEqual(
+ wizard.module_ids.ids, [], "Unselect module should clear the selection"
+ )
+ # For the time being, tests doens't call install_modules() function
+ # because installing module in a test context will execute the test
+ # of the installed modules, raising finally an error:
+
+ # TypeError: Many2many fields ir.actions.server.partner_ids and
+ # ir.actions.server.partner_ids use the same table and columns
diff --git a/upgrade_analysis/views/menu.xml b/upgrade_analysis/views/menu.xml
index 12d44779d..e12c75236 100644
--- a/upgrade_analysis/views/menu.xml
+++ b/upgrade_analysis/views/menu.xml
@@ -1,10 +1,9 @@
-
diff --git a/upgrade_analysis/wizards/upgrade_generate_record_wizard.py b/upgrade_analysis/wizards/upgrade_generate_record_wizard.py
index fc7f6c02f..439f6b2c2 100644
--- a/upgrade_analysis/wizards/upgrade_generate_record_wizard.py
+++ b/upgrade_analysis/wizards/upgrade_generate_record_wizard.py
@@ -95,7 +95,7 @@ class GenerateWizard(models.TransientModel):
)
self.env.cache.invalidate(
[
- (self.env["openupgrade.record"]._fields["noupdate"], None),
+ (self.env["upgrade.record"]._fields["noupdate"], None),
]
)
diff --git a/upgrade_analysis/wizards/upgrade_install_wizard.py b/upgrade_analysis/wizards/upgrade_install_wizard.py
index 4ea1d36b9..d91232867 100644
--- a/upgrade_analysis/wizards/upgrade_install_wizard.py
+++ b/upgrade_analysis/wizards/upgrade_install_wizard.py
@@ -6,7 +6,11 @@ from odoo import api, fields, models
from odoo.modules.registry import Registry
from odoo.osv.expression import AND
-from ..blacklist import BLACKLIST_MODULES
+from ..blacklist import (
+ BLACKLIST_MODULES,
+ BLACKLIST_MODULES_ENDS_WITH,
+ BLACKLIST_MODULES_STARTS_WITH,
+)
class UpgradeInstallWizard(models.TransientModel):
@@ -14,38 +18,87 @@ class UpgradeInstallWizard(models.TransientModel):
_description = "Upgrade Install Wizard"
state = fields.Selection(
- [("init", "init"), ("ready", "ready")], readonly=True, default="init"
+ [("draft", "Draft"), ("done", "Done")], readonly=True, default="draft"
+ )
+
+ module_ids = fields.Many2many(
+ comodel_name="ir.module.module",
+ domain=lambda x: x._module_ids_domain(),
+ )
+
+ module_qty = fields.Integer(
+ string="Modules Quantity", compute="_compute_module_qty"
)
- to_install = fields.Integer("Number of modules to install", readonly=True)
@api.model
- def default_get(self, fields):
- """Update module list and retrieve the number
- of installable modules"""
- res = super().default_get(fields)
- update, add = self.env["ir.module.module"].update_list()
- modules = self.env["ir.module.module"].search(
- [("state", "not in", ["uninstallable", "unknown"])]
- )
- res["to_install"] = len(modules)
- return res
-
- def install_all(self, extra_domain=None):
- """Main wizard step. Set all installable modules to install
- and actually install them. Exclude testing modules."""
+ def _module_ids_domain(self, extra_domain=None):
domain = [
- "&",
"&",
("state", "not in", ["uninstallable", "unknown"]),
- ("category_id.name", "!=", "Tests"),
("name", "not in", BLACKLIST_MODULES),
]
if extra_domain:
domain = AND([domain, extra_domain])
modules = self.env["ir.module.module"].search(domain)
- if modules:
- modules.write({"state": "to install"})
- self.env.cr.commit() # pylint: disable=invalid-commit
- Registry.new(self.env.cr.dbname, update_module=True)
- self.write({"state": "ready"})
- return True
+
+ for start_pattern in BLACKLIST_MODULES_STARTS_WITH:
+ modules = modules.filtered(lambda x: not x.name.startswith(start_pattern))
+ for end_pattern in BLACKLIST_MODULES_ENDS_WITH:
+ modules = modules.filtered(lambda x: not x.name.endswith(end_pattern))
+ return [("id", "in", modules.ids)]
+
+ @api.depends("module_ids")
+ def _compute_module_qty(self):
+ for wizard in self:
+ wizard.module_qty = len(wizard.module_ids)
+
+ def select_odoo_modules(self):
+ self.ensure_one()
+ modules = self.env["ir.module.module"].search(self._module_ids_domain())
+ modules = modules.filtered(lambda x: x.is_odoo_module)
+ self.module_ids = modules
+ return self.return_same_form_view()
+
+ def select_oca_modules(self):
+ self.ensure_one()
+ modules = self.env["ir.module.module"].search(self._module_ids_domain())
+ modules = modules.filtered(lambda x: x.is_oca_module)
+ self.module_ids = modules
+ return self.return_same_form_view()
+
+ def select_other_modules(self):
+ self.ensure_one()
+ modules = self.env["ir.module.module"].search(self._module_ids_domain())
+ modules = modules.filtered(lambda x: not (x.is_oca_module or x.is_odoo_module))
+ self.module_ids = modules
+ return self.return_same_form_view()
+
+ def select_installable_modules(self):
+ self.ensure_one()
+ self.module_ids = self.env["ir.module.module"].search(self._module_ids_domain())
+ return self.return_same_form_view()
+
+ def unselect_modules(self):
+ self.ensure_one()
+ self.module_ids = False
+ return self.return_same_form_view()
+
+ def install_modules(self):
+ """Set all selected modules and actually install them."""
+ self.ensure_one()
+ self.module_ids.write({"state": "to install"})
+ self.env.cr.commit() # pylint: disable=invalid-commit
+ Registry.new(self.env.cr.dbname, update_module=True)
+ self.write({"state": "done"})
+ return self.return_same_form_view()
+
+ def return_same_form_view(self):
+ return {
+ "type": "ir.actions.act_window",
+ "res_model": "upgrade.install.wizard",
+ "view_mode": "form",
+ "view_type": "form",
+ "res_id": self.id,
+ "views": [(False, "form")],
+ "target": "new",
+ }
diff --git a/upgrade_analysis/wizards/view_upgrade_generate_record_wizard.xml b/upgrade_analysis/wizards/view_upgrade_generate_record_wizard.xml
index 86c620179..a0a310e74 100644
--- a/upgrade_analysis/wizards/view_upgrade_generate_record_wizard.xml
+++ b/upgrade_analysis/wizards/view_upgrade_generate_record_wizard.xml
@@ -28,7 +28,7 @@
- Generate Records
+ Generate Records Wizard
ir.actions.act_window
upgrade.generate.record.wizard
form,tree
@@ -36,7 +36,7 @@
-
-
+
+
This will install all modules on the database. Do not continue if you use this database in production.
-
+ class="alert alert-warning"
+ role="alert"
+ >This will install the selected modules on the database. Do not continue if you use this database in production.
-
- Modules installed
+
+ The modules have been installed successfuly
+
+
+
+
+
+
+
+
+
+
+
@@ -29,7 +68,7 @@
- Install Modules
+ Install Modules Wizard
ir.actions.act_window
upgrade.install.wizard
form,tree
@@ -37,7 +76,7 @@
+
+
+
+
+
+
+
+
+
diff --git a/upgrade_analysis/wizards/__init__.py b/upgrade_analysis/wizards/__init__.py
index dffe83f41..95d289332 100644
--- a/upgrade_analysis/wizards/__init__.py
+++ b/upgrade_analysis/wizards/__init__.py
@@ -1,3 +1,2 @@
-from . import upgrade_analysis_wizard
from . import upgrade_generate_record_wizard
from . import upgrade_install_wizard
diff --git a/upgrade_analysis/wizards/upgrade_generate_record_wizard.py b/upgrade_analysis/wizards/upgrade_generate_record_wizard.py
index 439f6b2c2..7a5747719 100644
--- a/upgrade_analysis/wizards/upgrade_generate_record_wizard.py
+++ b/upgrade_analysis/wizards/upgrade_generate_record_wizard.py
@@ -2,7 +2,6 @@
# Copyright 2016 Opener B.V.
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
-from openupgradelib import openupgrade_tools
from odoo import _, fields, models
from odoo.exceptions import UserError
@@ -12,44 +11,38 @@ from odoo.modules.registry import Registry
class GenerateWizard(models.TransientModel):
_name = "upgrade.generate.record.wizard"
_description = "Upgrade Generate Record Wizard"
- _rec_name = "state"
- state = fields.Selection([("init", "init"), ("ready", "ready")], default="init")
+ state = fields.Selection([("draft", "Draft"), ("done", "Done")], default="draft")
- def quirk_standard_calendar_attendances(self):
- """Introduced in Odoo 13. The reinstallation causes a one2many value
- in [(0, 0, {})] format to be loaded on top of the first load, causing a
- violation of database constraint."""
- for cal in ("resource_calendar_std_35h", "resource_calendar_std_38h"):
- record = self.env.ref("resource.%s" % cal, False)
- if record:
- record.attendance_ids.unlink()
+ # from openupgradelib import openupgrade_tools
+ # TODO, SLG, make better a patch in odoo_patch
+ # def quirk_standard_calendar_attendances(self):
+ # """Introduced in Odoo 13. The reinstallation causes a one2many value
+ # in [(0, 0, {})] format to be loaded on top of the first load, causing a
+ # violation of database constraint."""
+ # for cal in ("resource_calendar_std_35h", "resource_calendar_std_38h"):
+ # record = self.env.ref("resource.%s" % cal, False)
+ # if record:
+ # record.attendance_ids.unlink()
+
+ # # Truncate the records table
+ # if openupgrade_tools.table_exists(
+ # self.env.cr, "upgrade_attribute"
+ # ) and openupgrade_tools.table_exists(self.env.cr, "upgrade_record"):
+ # self.env.cr.execute("TRUNCATE upgrade_attribute, upgrade_record;")
+
+ # # Run any quirks
+ # self.quirk_standard_calendar_attendances()
def generate(self):
- """Main wizard step. Make sure that all modules are up-to-date,
- then reinitialize all installed modules.
+ """Reinitialize all installed modules.
Equivalent of running the server with '-d --init all'
The goal of this is to fill the records table.
TODO: update module list and versions, then update all modules?"""
- # Truncate the records table
- if openupgrade_tools.table_exists(
- self.env.cr, "upgrade_attribute"
- ) and openupgrade_tools.table_exists(self.env.cr, "upgrade_record"):
- self.env.cr.execute("TRUNCATE upgrade_attribute, upgrade_record;")
- # Run any quirks
- self.quirk_standard_calendar_attendances()
-
- # Need to get all modules in state 'installed'
- modules = self.env["ir.module.module"].search(
- [("state", "in", ["to install", "to upgrade"])]
- )
- if modules:
- self.env.cr.commit() # pylint: disable=invalid-commit
- Registry.new(self.env.cr.dbname, update_module=True)
- # Did we succeed above?
+ # Check of all the modules are correctly installed
modules = self.env["ir.module.module"].search(
[("state", "in", ["to install", "to upgrade"])]
)
@@ -116,4 +109,4 @@ class GenerateWizard(models.TransientModel):
ORDER BY imd.name, imd.id""",
)
- return self.write({"state": "ready"})
+ return self.write({"state": "done"})
diff --git a/upgrade_analysis/wizards/view_upgrade_analysis_wizard.xml b/upgrade_analysis/wizards/view_upgrade_analysis_wizard.xml
deleted file mode 100644
index d988c503d..000000000
--- a/upgrade_analysis/wizards/view_upgrade_analysis_wizard.xml
+++ /dev/null
@@ -1,35 +0,0 @@
-
-
-
-
- upgrade.analysis.wizard
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/upgrade_analysis/wizards/view_upgrade_generate_record_wizard.xml b/upgrade_analysis/wizards/view_upgrade_generate_record_wizard.xml
index a0a310e74..4a4cd0193 100644
--- a/upgrade_analysis/wizards/view_upgrade_generate_record_wizard.xml
+++ b/upgrade_analysis/wizards/view_upgrade_generate_record_wizard.xml
@@ -4,13 +4,15 @@
upgrade.generate.record.wizard
-
-
-
+
+
+
This will reinitialize all the modules installed on this database. Do not continue if you use this database in production.
-
+
Modules initialized and record created
@@ -18,7 +20,7 @@
string="Continue"
name="generate"
type="object"
- states="init"
+ states="draft"
class="btn-primary"
/>
diff --git a/upgrade_analysis/wizards/view_upgrade_install_wizard.xml b/upgrade_analysis/wizards/view_upgrade_install_wizard.xml
index 0c079b94f..7c9ac1ceb 100644
--- a/upgrade_analysis/wizards/view_upgrade_install_wizard.xml
+++ b/upgrade_analysis/wizards/view_upgrade_install_wizard.xml
@@ -5,7 +5,9 @@
upgrade.install.wizard
-
+
The modules have been installed successfuly
-
+
-
@@ -52,6 +50,11 @@
widget="many2many_tags"
options="{'no_create': True}"
/>
+
Date: Tue, 1 Dec 2020 10:35:52 +0100
Subject: [PATCH 07/67] [RFR] Improve patchwork
---
upgrade_analysis/__init__.py | 1 -
upgrade_analysis/models/upgrade_analysis.py | 17 +-
upgrade_analysis/odoo_patch/__init__.py | 3 +-
.../odoo_patch/addons/__init__.py | 2 +-
.../odoo_patch/addons/mrp/__init__.py | 21 +-
.../addons/point_of_sale/__init__.py | 1 -
.../addons/point_of_sale/models/__init__.py | 1 -
.../addons/point_of_sale/models/pos_config.py | 21 -
.../odoo_patch/addons/stock/__init__.py | 19 +-
upgrade_analysis/odoo_patch/odoo/__init__.py | 6 +-
upgrade_analysis/odoo_patch/odoo/http.py | 32 -
upgrade_analysis/odoo_patch/odoo/models.py | 184 +-----
.../odoo_patch/odoo/modules/__init__.py | 11 -
.../odoo_patch/odoo/modules/graph.py | 108 ----
.../odoo_patch/odoo/modules/loading.py | 556 ------------------
.../odoo_patch/odoo/modules/migration.py | 118 ----
.../odoo_patch/odoo/modules/registry.py | 77 +--
.../odoo_patch/odoo/service/__init__.py | 4 -
.../odoo_patch/odoo/service/server.py | 71 ---
.../odoo_patch/odoo/tools/__init__.py | 1 -
.../odoo_patch/odoo/tools/convert.py | 24 +-
.../odoo_patch/odoo/tools/view_validation.py | 29 -
upgrade_analysis/odoo_patch/odoo_patch.py | 59 ++
upgrade_analysis/upgrade_loading.py | 316 ----------
upgrade_analysis/upgrade_log.py | 154 ++++-
.../views/view_upgrade_analysis.xml | 4 +
.../wizards/upgrade_generate_record_wizard.py | 35 +-
.../wizards/upgrade_install_wizard.py | 28 +-
28 files changed, 324 insertions(+), 1579 deletions(-)
delete mode 100644 upgrade_analysis/odoo_patch/addons/point_of_sale/__init__.py
delete mode 100644 upgrade_analysis/odoo_patch/addons/point_of_sale/models/__init__.py
delete mode 100644 upgrade_analysis/odoo_patch/addons/point_of_sale/models/pos_config.py
delete mode 100644 upgrade_analysis/odoo_patch/odoo/http.py
delete mode 100644 upgrade_analysis/odoo_patch/odoo/modules/graph.py
delete mode 100644 upgrade_analysis/odoo_patch/odoo/modules/loading.py
delete mode 100644 upgrade_analysis/odoo_patch/odoo/modules/migration.py
delete mode 100644 upgrade_analysis/odoo_patch/odoo/service/__init__.py
delete mode 100644 upgrade_analysis/odoo_patch/odoo/service/server.py
delete mode 100644 upgrade_analysis/odoo_patch/odoo/tools/view_validation.py
create mode 100644 upgrade_analysis/odoo_patch/odoo_patch.py
delete mode 100644 upgrade_analysis/upgrade_loading.py
diff --git a/upgrade_analysis/__init__.py b/upgrade_analysis/__init__.py
index 7fc3dd81d..ca02278df 100644
--- a/upgrade_analysis/__init__.py
+++ b/upgrade_analysis/__init__.py
@@ -4,5 +4,4 @@ from . import wizards
from . import blacklist
from . import apriori
from . import compare
-from . import upgrade_loading
from . import upgrade_log
diff --git a/upgrade_analysis/models/upgrade_analysis.py b/upgrade_analysis/models/upgrade_analysis.py
index a579696fa..52eff5d85 100644
--- a/upgrade_analysis/models/upgrade_analysis.py
+++ b/upgrade_analysis/models/upgrade_analysis.py
@@ -3,6 +3,7 @@
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
# flake8: noqa: C901
+import logging
import os
from odoo import fields, models
@@ -11,6 +12,7 @@ from odoo.tools import config
from .. import compare
+_logger = logging.getLogger(__name__)
_IGNORE_MODULES = ["openupgrade_records", "upgrade_analysis"]
@@ -31,6 +33,10 @@ class UpgradeAnalysis(models.Model):
)
log = fields.Text(readonly=True)
+ upgrade_path = fields.Char(
+ default=config.get("upgrade_path", False),
+ help="The base file path to save the analyse files of Odoo modules",
+ )
write_files = fields.Boolean(
help="Write analysis files to the module directories", default=True
@@ -50,10 +56,12 @@ class UpgradeAnalysis(models.Model):
):
module = self.env["ir.module.module"].search([("name", "=", module_name)])[0]
if module.is_odoo_module:
- upgrade_path = config.get("upgrade_path", False)
- if not upgrade_path:
- return "ERROR: could not find 'upgrade_path' config:\n"
- module_path = os.path.join(upgrade_path, module_name)
+ if not self.upgrade_path:
+ return (
+ "ERROR: no upgrade_path set when writing analysis of %s\n"
+ % module_name
+ )
+ module_path = os.path.join(self.upgrade_path, module_name)
else:
module_path = get_module_path(module_name)
if not module_path:
@@ -71,6 +79,7 @@ class UpgradeAnalysis(models.Model):
f = open(logfile, "w")
except Exception:
return "ERROR: could not open file %s for writing:\n" % logfile
+ _logger.debug("Writing analysis to %s", logfile)
f.write(content)
f.close()
return None
diff --git a/upgrade_analysis/odoo_patch/__init__.py b/upgrade_analysis/odoo_patch/__init__.py
index 56a70dbc1..4a1837956 100644
--- a/upgrade_analysis/odoo_patch/__init__.py
+++ b/upgrade_analysis/odoo_patch/__init__.py
@@ -1,2 +1,3 @@
-from . import odoo
from . import addons
+from . import odoo
+from . import odoo_patch
diff --git a/upgrade_analysis/odoo_patch/addons/__init__.py b/upgrade_analysis/odoo_patch/addons/__init__.py
index e5aa886ba..3247dc7b6 100644
--- a/upgrade_analysis/odoo_patch/addons/__init__.py
+++ b/upgrade_analysis/odoo_patch/addons/__init__.py
@@ -1,3 +1,3 @@
from . import mrp
-from . import stock
from . import point_of_sale
+from . import stock
diff --git a/upgrade_analysis/odoo_patch/addons/mrp/__init__.py b/upgrade_analysis/odoo_patch/addons/mrp/__init__.py
index 925f56ed2..94f30010f 100644
--- a/upgrade_analysis/odoo_patch/addons/mrp/__init__.py
+++ b/upgrade_analysis/odoo_patch/addons/mrp/__init__.py
@@ -1,19 +1,10 @@
from odoo.addons import mrp
+from ...odoo_patch import OdooPatch
-def _pre_init_mrp(cr):
- """ Allow installing MRP in databases with large stock.move table (>1M records)
- - Creating the computed+stored field stock_move.is_done is terribly slow with the ORM and
- leads to "Out of Memory" crashes
- """
- #
- # don't try to add 'is_done' column, because it will fail
- # when executing the generation of records, in the openupgrade_records
- # module.
- # cr.execute("""ALTER TABLE "stock_move" ADD COLUMN "is_done" bool;""")
- # cr.execute("""UPDATE stock_move
- # SET is_done=COALESCE(state in ('done', 'cancel'), FALSE);""")
- #
+class PreInitHookPatch(OdooPatch):
+ target = mrp
+ method_names = ['_pre_init_mrp']
-
-mrp._pre_init_mrp = _pre_init_mrp
+ def _pre_init_mrp(cr):
+ """ Don't try to create an existing column on reinstall """
diff --git a/upgrade_analysis/odoo_patch/addons/point_of_sale/__init__.py b/upgrade_analysis/odoo_patch/addons/point_of_sale/__init__.py
deleted file mode 100644
index 0650744f6..000000000
--- a/upgrade_analysis/odoo_patch/addons/point_of_sale/__init__.py
+++ /dev/null
@@ -1 +0,0 @@
-from . import models
diff --git a/upgrade_analysis/odoo_patch/addons/point_of_sale/models/__init__.py b/upgrade_analysis/odoo_patch/addons/point_of_sale/models/__init__.py
deleted file mode 100644
index db8634ade..000000000
--- a/upgrade_analysis/odoo_patch/addons/point_of_sale/models/__init__.py
+++ /dev/null
@@ -1 +0,0 @@
-from . import pos_config
diff --git a/upgrade_analysis/odoo_patch/addons/point_of_sale/models/pos_config.py b/upgrade_analysis/odoo_patch/addons/point_of_sale/models/pos_config.py
deleted file mode 100644
index ac0f5dc5a..000000000
--- a/upgrade_analysis/odoo_patch/addons/point_of_sale/models/pos_config.py
+++ /dev/null
@@ -1,21 +0,0 @@
-from odoo import api
-from odoo.addons.point_of_sale.models.pos_config import PosConfig
-
-if True:
-
- @api.model
- def post_install_pos_localisation(self, companies=False):
- #
- # don't try to setup_defaults, because it will fail
- # when executing the generation of records, in the openupgrade_records
- # module.
- # self = self.sudo()
- # if not companies:
- # companies = self.env['res.company'].search([])
- # for company in companies.filtered('chart_template_id'):
- # pos_configs = self.search([('company_id', '=', company.id)])
- # pos_configs.setup_defaults(company)
- pass
- #
-
-PosConfig.post_install_pos_localisation = post_install_pos_localisation
diff --git a/upgrade_analysis/odoo_patch/addons/stock/__init__.py b/upgrade_analysis/odoo_patch/addons/stock/__init__.py
index b66d7f484..a28a083ce 100644
--- a/upgrade_analysis/odoo_patch/addons/stock/__init__.py
+++ b/upgrade_analysis/odoo_patch/addons/stock/__init__.py
@@ -1,17 +1,10 @@
from odoo.addons import stock
+from ...odoo_patch import OdooPatch
-def pre_init_hook(cr):
- #
- # don't uninstall data as this breaks the analysis
- # Origin of this code is https://github.com/odoo/odoo/issues/22243
- # env = api.Environment(cr, SUPERUSER_ID, {})
- # env['ir.model.data'].search([
- # ('model', 'like', '%stock%'),
- # ('module', '=', 'stock')
- # ]).unlink()
- pass
- #
+class PreInitHookPatch(OdooPatch):
+ target = stock
+ method_names = ['pre_init_hook']
-
-stock.pre_init_hook = pre_init_hook
+ def pre_init_hook(cr):
+ """ Don't unlink stock data on reinstall """
diff --git a/upgrade_analysis/odoo_patch/odoo/__init__.py b/upgrade_analysis/odoo_patch/odoo/__init__.py
index 5629ec98c..4541924d9 100644
--- a/upgrade_analysis/odoo_patch/odoo/__init__.py
+++ b/upgrade_analysis/odoo_patch/odoo/__init__.py
@@ -1,5 +1,3 @@
-from . import modules
-from . import service
-from . import tools
-from . import http
from . import models
+from . import modules
+from . import tools
diff --git a/upgrade_analysis/odoo_patch/odoo/http.py b/upgrade_analysis/odoo_patch/odoo/http.py
deleted file mode 100644
index e11c558fb..000000000
--- a/upgrade_analysis/odoo_patch/odoo/http.py
+++ /dev/null
@@ -1,32 +0,0 @@
-# flake8: noqa
-# pylint: skip-file
-
-import odoo
-from odoo.service import security
-from odoo.http import SessionExpiredException, request, OpenERPSession
-
-if True:
- def _check_security(self):
- """
- Check the current authentication parameters to know if those are still
- valid. This method should be called at each request. If the
- authentication fails, a :exc:`SessionExpiredException` is raised.
- """
- if not self.db or not self.uid:
- raise SessionExpiredException("Session expired")
- # We create our own environment instead of the request's one.
- # to avoid creating it without the uid since request.uid isn't set yet
- env = odoo.api.Environment(request.cr, self.uid, self.context)
- # here we check if the session is still valid
- if not security.check_session(self, env):
- #
- # When asking openupgrade_records to generate records
- # over jsonrpc, a query on res_users in the call above locks this
- # table for the sql operations that are triggered by the
- # reinstallation of the base module
- env.cr.rollback()
- #
- raise SessionExpiredException("Session expired")
-
-
-OpenERPSession.check_security = _check_security
diff --git a/upgrade_analysis/odoo_patch/odoo/models.py b/upgrade_analysis/odoo_patch/odoo/models.py
index 201f3f4fe..09c10c418 100644
--- a/upgrade_analysis/odoo_patch/odoo/models.py
+++ b/upgrade_analysis/odoo_patch/odoo/models.py
@@ -1,179 +1,21 @@
-# flake8: noqa
-# pylint: skip-file
-
-import odoo
-import psycopg2
-from odoo import _
-from odoo.models import fix_import_export_id_paths, BaseModel, _logger
+from odoo import api, models
+from ..odoo_patch import OdooPatch
from ... import upgrade_log
-if True:
- def _load(self, fields, data):
- """
- Attempts to load the data matrix, and returns a list of ids (or
- ``False`` if there was an error and no id could be generated) and a
- list of messages.
+class BaseModelPatch(OdooPatch):
+ target = models.BaseModel
+ method_names = ['_convert_records']
- The ids are those of the records created and saved (in database), in
- the same order they were extracted from the file. They can be passed
- directly to :meth:`~read`
-
- :param fields: list of fields to import, at the same index as the corresponding data
- :type fields: list(str)
- :param data: row-major matrix of data to import
- :type data: list(list(str))
- :returns: {ids: list(int)|False, messages: [Message][, lastrow: int]}
- """
- self.flush()
-
- # determine values of mode, current_module and noupdate
- mode = self._context.get('mode', 'init')
- current_module = self._context.get('module', '__import__')
- noupdate = self._context.get('noupdate', False)
- # add current module in context for the conversion of xml ids
- self = self.with_context(_import_current_module=current_module)
-
- cr = self._cr
- cr.execute('SAVEPOINT model_load')
-
- fields = [fix_import_export_id_paths(f) for f in fields]
- fg = self.fields_get()
-
- ids = []
- messages = []
- ModelData = self.env['ir.model.data']
-
- # list of (xid, vals, info) for records to be created in batch
- batch = []
- batch_xml_ids = set()
- # models in which we may have created / modified data, therefore might
- # require flushing in order to name_search: the root model and any
- # o2m
- creatable_models = {self._name}
- for field_path in fields:
- if field_path[0] in (None, 'id', '.id'):
- continue
- model_fields = self._fields
- if isinstance(model_fields[field_path[0]], odoo.fields.Many2one):
- # this only applies for toplevel m2o (?) fields
- if field_path[0] in (self.env.context.get('name_create_enabled_fieds') or {}):
- creatable_models.add(model_fields[field_path[0]].comodel_name)
- for field_name in field_path:
- if field_name in (None, 'id', '.id'):
- break
-
- if isinstance(model_fields[field_name], odoo.fields.One2many):
- comodel = model_fields[field_name].comodel_name
- creatable_models.add(comodel)
- model_fields = self.env[comodel]._fields
-
- def flush(*, xml_id=None, model=None):
- if not batch:
- return
-
- assert not (xml_id and model), \
- "flush can specify *either* an external id or a model, not both"
-
- if xml_id and xml_id not in batch_xml_ids:
- if xml_id not in self.env:
- return
- if model and model not in creatable_models:
- return
-
- data_list = [
- dict(xml_id=xid, values=vals, info=info, noupdate=noupdate)
- for xid, vals, info in batch
- ]
- batch.clear()
- batch_xml_ids.clear()
-
- # try to create in batch
- try:
- with cr.savepoint():
- recs = self._load_records(data_list, mode == 'update')
- ids.extend(recs.ids)
- return
- except psycopg2.InternalError as e:
- # broken transaction, exit and hope the source error was already logged
- if not any(message['type'] == 'error' for message in messages):
- info = data_list[0]['info']
- messages.append(dict(info, type='error', message=_(u"Unknown database error: '%s'", e)))
- return
- except Exception:
- pass
-
- errors = 0
- # try again, this time record by record
- for i, rec_data in enumerate(data_list, 1):
- try:
- with cr.savepoint():
- rec = self._load_records([rec_data], mode == 'update')
- ids.append(rec.id)
- except psycopg2.Warning as e:
- info = rec_data['info']
- messages.append(dict(info, type='warning', message=str(e)))
- except psycopg2.Error as e:
- info = rec_data['info']
- messages.append(dict(info, type='error', **PGERROR_TO_OE[e.pgcode](self, fg, info, e)))
- # Failed to write, log to messages, rollback savepoint (to
- # avoid broken transaction) and keep going
- errors += 1
- except Exception as e:
- _logger.debug("Error while loading record", exc_info=True)
- info = rec_data['info']
- message = (_(u'Unknown error during import:') + u' %s: %s' % (type(e), e))
- moreinfo = _('Resolve other errors first')
- messages.append(dict(info, type='error', message=message, moreinfo=moreinfo))
- # Failed for some reason, perhaps due to invalid data supplied,
- # rollback savepoint and keep going
- errors += 1
- if errors >= 10 and (errors >= i / 10):
- messages.append({
- 'type': 'warning',
- 'message': _(u"Found more than 10 errors and more than one error per 10 records, interrupted to avoid showing too many errors.")
- })
- break
-
- # make 'flush' available to the methods below, in the case where XMLID
- # resolution fails, for instance
- flush_self = self.with_context(import_flush=flush)
-
- # TODO: break load's API instead of smuggling via context?
- limit = self._context.get('_import_limit')
- if limit is None:
- limit = float('inf')
- extracted = flush_self._extract_records(fields, data, log=messages.append, limit=limit)
-
- converted = flush_self._convert_records(extracted, log=messages.append)
-
- info = {'rows': {'to': -1}}
- for id, xid, record, info in converted:
+ @api.model
+ def _convert_records(self, records, log=lambda a: None):
+ """ Log data ids that are imported with `load` """
+ current_module = self.env.context['module']
+ for res in BaseModelPatch._convert_records._original_method(
+ self, records, log=log):
+ _id, xid, _record, _info = res
if xid:
xid = xid if '.' in xid else "%s.%s" % (current_module, xid)
- batch_xml_ids.add(xid)
- #
- # log csv records
upgrade_log.log_xml_id(self.env.cr, current_module, xid)
- #
- elif id:
- record['id'] = id
- batch.append((xid, record, info))
- flush()
- if any(message['type'] == 'error' for message in messages):
- cr.execute('ROLLBACK TO SAVEPOINT model_load')
- ids = False
- # cancel all changes done to the registry/ormcache
- self.pool.reset_changes()
-
- nextrow = info['rows']['to'] + 1
- if nextrow < limit:
- nextrow = 0
- return {
- 'ids': ids,
- 'messages': messages,
- 'nextrow': nextrow,
- }
-
-BaseModel.load = _load
+ yield res
diff --git a/upgrade_analysis/odoo_patch/odoo/modules/__init__.py b/upgrade_analysis/odoo_patch/odoo/modules/__init__.py
index 90de5b4ff..7246323f9 100644
--- a/upgrade_analysis/odoo_patch/odoo/modules/__init__.py
+++ b/upgrade_analysis/odoo_patch/odoo/modules/__init__.py
@@ -1,12 +1 @@
-# Minor changes. (call to safe_eval changed)
-# otherwise : adapted to V14
-from . import graph
-
-# A lot of changes in the core functions.
-from . import loading
-
-# Adapted to V14
-from . import migration
-
-# Adapted to V14
from . import registry
diff --git a/upgrade_analysis/odoo_patch/odoo/modules/graph.py b/upgrade_analysis/odoo_patch/odoo/modules/graph.py
deleted file mode 100644
index b0bedef3e..000000000
--- a/upgrade_analysis/odoo_patch/odoo/modules/graph.py
+++ /dev/null
@@ -1,108 +0,0 @@
-# flake8: noqa
-# pylint: skip-file
-
-import logging
-import odoo
-import odoo.tools as tools
-from odoo.tools.safe_eval import safe_eval
-
-from odoo.modules.graph import Graph
-
-_logger = logging.getLogger(__name__)
-
-
-if True:
-
- def _update_from_db(self, cr):
- if not len(self):
- return
- # update the graph with values from the database (if exist)
- ## First, we set the default values for each package in graph
- additional_data = {key: {'id': 0, 'state': 'uninstalled', 'dbdemo': False, 'installed_version': None} for key in self.keys()}
- ## Then we get the values from the database
- cr.execute('SELECT name, id, state, demo AS dbdemo, latest_version AS installed_version'
- ' FROM ir_module_module'
- ' WHERE name IN %s',(tuple(additional_data),)
- )
-
- ## and we update the default values with values from the database
- additional_data.update((x['name'], x) for x in cr.dictfetchall())
-
- #
- # Prevent reloading of demo data from the new version on major upgrade
- if ('base' in self and additional_data['base']['dbdemo'] and
- additional_data['base']['installed_version'] <
- odoo.release.major_version):
- cr.execute("UPDATE ir_module_module SET demo = false")
- for data in additional_data.values():
- data['dbdemo'] = False
- #
-
- for package in self.values():
- for k, v in additional_data[package.name].items():
- setattr(package, k, v)
-
-
- def _add_modules(self, cr, module_list, force=None):
- if force is None:
- force = []
- packages = []
- len_graph = len(self)
-
- #
- # force additional dependencies for the upgrade process if given
- # in config file
- forced_deps = tools.config.get_misc('openupgrade', 'force_deps', '{}')
- forced_deps = tools.config.get_misc('openupgrade',
- 'force_deps_' + odoo.release.version,
- forced_deps)
- forced_deps = safe_eval(forced_deps)
- #
-
- for module in module_list:
- # This will raise an exception if no/unreadable descriptor file.
- # NOTE The call to load_information_from_description_file is already
- # done by db.initialize, so it is possible to not do it again here.
- info = odoo.modules.module.load_information_from_description_file(module)
- if info and info['installable']:
- #
- info['depends'].extend(forced_deps.get(module, []))
- #
- packages.append((module, info)) # TODO directly a dict, like in get_modules_with_version
- elif module != 'studio_customization':
- _logger.warning('module %s: not installable, skipped', module)
-
- dependencies = dict([(p, info['depends']) for p, info in packages])
- current, later = set([p for p, info in packages]), set()
-
- while packages and current > later:
- package, info = packages[0]
- deps = info['depends']
-
- # if all dependencies of 'package' are already in the graph, add 'package' in the graph
- if all(dep in self for dep in deps):
- if not package in current:
- packages.pop(0)
- continue
- later.clear()
- current.remove(package)
- node = self.add_node(package, info)
- for kind in ('init', 'demo', 'update'):
- if package in tools.config[kind] or 'all' in tools.config[kind] or kind in force:
- setattr(node, kind, True)
- else:
- later.add(package)
- packages.append((package, info))
- packages.pop(0)
-
- self.update_from_db(cr)
-
- for package in later:
- unmet_deps = [p for p in dependencies[package] if p not in self]
- _logger.info('module %s: Unmet dependencies: %s', package, ', '.join(unmet_deps))
-
- return len(self) - len_graph
-
-
-Graph.update_from_db = _update_from_db
-Graph.add_modules = _add_modules
diff --git a/upgrade_analysis/odoo_patch/odoo/modules/loading.py b/upgrade_analysis/odoo_patch/odoo/modules/loading.py
deleted file mode 100644
index 4194fdc62..000000000
--- a/upgrade_analysis/odoo_patch/odoo/modules/loading.py
+++ /dev/null
@@ -1,556 +0,0 @@
-# flake8: noqa
-# pylint: skip-file
-
-import itertools
-import logging
-import sys
-import time
-
-import odoo
-import odoo.tools as tools
-from odoo import api, SUPERUSER_ID
-from odoo.modules import loading
-from odoo.modules.module import adapt_version, load_openerp_module, initialize_sys_path
-
-from odoo.modules.loading import load_data, load_demo, _check_module_names
-from .... import upgrade_loading
-
-import os
-
-_logger = logging.getLogger(__name__)
-_test_logger = logging.getLogger('odoo.tests')
-
-
-def _load_module_graph(cr, graph, status=None, perform_checks=True,
- skip_modules=None, report=None, models_to_check=None, upg_registry=None):
- #
- """Migrates+Updates or Installs all module nodes from ``graph``
- :param graph: graph of module nodes to load
- :param status: deprecated parameter, unused, left to avoid changing signature in 8.0
- :param perform_checks: whether module descriptors should be checked for validity (prints warnings
- for same cases)
- :param skip_modules: optional list of module names (packages) which have previously been loaded and can be skipped
- :return: list of modules that were installed or updated
- """
- if skip_modules is None:
- skip_modules = []
-
- if models_to_check is None:
- models_to_check = set()
-
- processed_modules = []
- loaded_modules = []
- registry = odoo.registry(cr.dbname)
- migrations = odoo.modules.migration.MigrationManager(cr, graph)
- module_count = len(graph)
- _logger.info('loading %d modules...', module_count)
-
- #
- # suppress commits to have the upgrade of one module in just one transaction
- cr.commit_org = cr.commit
- cr.commit = lambda *args: None
- cr.rollback_org = cr.rollback
- cr.rollback = lambda *args: None
- #
-
- # register, instantiate and initialize models for each modules
- t0 = time.time()
- loading_extra_query_count = odoo.sql_db.sql_counter
- loading_cursor_query_count = cr.sql_log_count
-
- models_updated = set()
-
- for index, package in enumerate(graph, 1):
- module_name = package.name
- module_id = package.id
-
- #
- if module_name in skip_modules or module_name in loaded_modules:
- #
- continue
-
- module_t0 = time.time()
- module_cursor_query_count = cr.sql_log_count
- module_extra_query_count = odoo.sql_db.sql_counter
-
- needs_update = (
- hasattr(package, "init")
- or hasattr(package, "update")
- or package.state in ("to install", "to upgrade")
- )
- module_log_level = logging.DEBUG
- if needs_update:
- module_log_level = logging.INFO
- _logger.log(module_log_level, 'Loading module %s (%d/%d)', module_name, index, module_count)
-
- if needs_update:
- if package.name != 'base':
- registry.setup_models(cr)
- migrations.migrate_module(package, 'pre')
- if package.name != 'base':
- env = api.Environment(cr, SUPERUSER_ID, {})
- env['base'].flush()
-
- load_openerp_module(package.name)
-
- new_install = package.state == 'to install'
- if new_install:
- py_module = sys.modules['odoo.addons.%s' % (module_name,)]
- pre_init = package.info.get('pre_init_hook')
- if pre_init:
- getattr(py_module, pre_init)(cr)
-
- model_names = registry.load(cr, package)
-
- mode = 'update'
- if hasattr(package, 'init') or package.state == 'to install':
- mode = 'init'
-
- loaded_modules.append(package.name)
- if needs_update:
- models_updated |= set(model_names)
- models_to_check -= set(model_names)
- registry.setup_models(cr)
- #
- # rebuild the local registry based on the loaded models
- local_registry = {}
- env = api.Environment(cr, SUPERUSER_ID, {})
- for model in env.values():
- if not model._auto:
- continue
- upgrade_loading.log_model(model, local_registry)
- upgrade_loading.compare_registries(
- cr, package.name, upg_registry, local_registry)
- #
-
- registry.init_models(cr, model_names, {'module': package.name}, new_install)
- elif package.state != 'to remove':
- # The current module has simply been loaded. The models extended by this module
- # and for which we updated the schema, must have their schema checked again.
- # This is because the extension may have changed the model,
- # e.g. adding required=True to an existing field, but the schema has not been
- # updated by this module because it's not marked as 'to upgrade/to install'.
- models_to_check |= set(model_names) & models_updated
-
- idref = {}
-
- if needs_update:
- env = api.Environment(cr, SUPERUSER_ID, {})
- # Can't put this line out of the loop: ir.module.module will be
- # registered by init_models() above.
- module = env['ir.module.module'].browse(module_id)
-
- if perform_checks:
- module._check()
-
- if package.state == 'to upgrade':
- # upgrading the module information
- module.write(module.get_values_from_terp(package.data))
- load_data(cr, idref, mode, kind='data', package=package)
- demo_loaded = package.dbdemo = load_demo(cr, package, idref, mode)
- cr.execute('update ir_module_module set demo=%s where id=%s', (demo_loaded, module_id))
- module.invalidate_cache(['demo'])
-
- #
- # add 'try' block for logging exceptions
- # as errors in post scripts seem to be dropped
- try:
- migrations.migrate_module(package, 'post')
- except Exception as exc:
- _logger.error('Error executing post migration script for module %s: %s',
- package, exc)
- raise
- #
-
- # Update translations for all installed languages
- overwrite = odoo.tools.config["overwrite_existing_translations"]
- module.with_context(overwrite=overwrite)._update_translations()
-
- if package.name is not None:
- registry._init_modules.add(package.name)
-
- if needs_update:
- if new_install:
- post_init = package.info.get('post_init_hook')
- if post_init:
- getattr(py_module, post_init)(cr, registry)
-
- if mode == 'update':
- # validate the views that have not been checked yet
- env['ir.ui.view']._validate_module_views(module_name)
-
- # need to commit any modification the module's installation or
- # update made to the schema or data so the tests can run
- # (separately in their own transaction)
- #
- # commit after processing every module as well, for
- # easier debugging and continuing an interrupted migration
- cr.commit_org()
- #
- # run tests
- if os.environ.get('OPENUPGRADE_TESTS') and package.name is not None:
- prefix = '.migrations'
- registry.openupgrade_test_prefixes[package.name] = prefix
- report.record_result(odoo.modules.module.run_unit_tests(module_name, openupgrade_prefix=prefix))
- #
- # commit module_n state and version immediatly
- # to avoid invalid database state if module_n+1 raises an
- # exception
- cr.commit_org()
- #
-
- package.load_state = package.state
- package.load_version = package.installed_version
- package.state = 'installed'
- for kind in ('init', 'demo', 'update'):
- if hasattr(package, kind):
- delattr(package, kind)
- module.flush()
-
- extra_queries = odoo.sql_db.sql_counter - module_extra_query_count - test_queries
- extras = []
- if test_queries:
- extras.append(f'+{test_queries} test')
- if extra_queries:
- extras.append(f'+{extra_queries} other')
- _logger.log(
- module_log_level, "Module %s loaded in %.2fs%s, %s queries%s",
- module_name, time.time() - module_t0,
- f' (incl. {test_time:.2f}s test)' if test_time else '',
- cr.sql_log_count - module_cursor_query_count,
- f' ({", ".join(extras)})' if extras else ''
- )
- if test_results and not test_results.wasSuccessful():
- _logger.error(
- "Module %s: %d failures, %d errors of %d tests",
- module_name, len(test_results.failures), len(test_results.errors),
- test_results.testsRun
- )
-
- _logger.runbot("%s modules loaded in %.2fs, %s queries (+%s extra)",
- len(graph),
- time.time() - t0,
- cr.sql_log_count - loading_cursor_query_count,
- odoo.sql_db.sql_counter - loading_extra_query_count) # extra queries: testes, notify, any other closed cursor
-
- #
- # restore commit method
- cr.commit = cr.commit_org
- cr.commit()
- #
-
- return loaded_modules, processed_modules
-
-
-def _load_marked_modules(cr, graph, states, force, progressdict, report,
- loaded_modules, perform_checks, models_to_check=None, upg_registry=None):
- #
- """Loads modules marked with ``states``, adding them to ``graph`` and
- ``loaded_modules`` and returns a list of installed/upgraded modules."""
-
- if models_to_check is None:
- models_to_check = set()
-
- processed_modules = []
- while True:
- cr.execute("SELECT name from ir_module_module WHERE state IN %s" ,(tuple(states),))
- module_list = [name for (name,) in cr.fetchall() if name not in graph]
- #
- module_list = upgrade_loading.add_module_dependencies(cr, module_list)
- #
- if not module_list:
- break
- graph.add_modules(cr, module_list, force)
- _logger.debug('Updating graph with %d more modules', len(module_list))
- #
- # add upg_registry
- loaded, processed = _load_module_graph(
- cr, graph, progressdict, report=report, skip_modules=loaded_modules,
- perform_checks=perform_checks, models_to_check=models_to_check,
- upg_registry=upg_registry,
- )
- #
- processed_modules.extend(processed)
- loaded_modules.extend(loaded)
- if not processed:
- break
- return processed_modules
-
-
-def _load_modules(db, force_demo=False, status=None, update_module=False):
- initialize_sys_path()
-
- force = []
- if force_demo:
- force.append('demo')
-
- #
- upg_registry = {}
- #
-
- models_to_check = set()
-
- with db.cursor() as cr:
- if not odoo.modules.db.is_initialized(cr):
- if not update_module:
- _logger.error("Database %s not initialized, you can force it with `-i base`", cr.dbname)
- return
- _logger.info("init db")
- odoo.modules.db.initialize(cr)
- update_module = True # process auto-installed modules
- tools.config["init"]["all"] = 1
- if not tools.config['without_demo']:
- tools.config["demo"]['all'] = 1
-
- # This is a brand new registry, just created in
- # odoo.modules.registry.Registry.new().
- registry = odoo.registry(cr.dbname)
-
- if 'base' in tools.config['update'] or 'all' in tools.config['update']:
- cr.execute("update ir_module_module set state=%s where name=%s and state=%s", ('to upgrade', 'base', 'installed'))
-
- # STEP 1: LOAD BASE (must be done before module dependencies can be computed for later steps)
- graph = odoo.modules.graph.Graph()
- graph.add_module(cr, 'base', force)
- if not graph:
- _logger.critical('module base cannot be loaded! (hint: verify addons-path)')
- raise ImportError('Module `base` cannot be loaded! (hint: verify addons-path)')
-
- # processed_modules: for cleanup step after install
- # loaded_modules: to avoid double loading
- report = registry._assertion_report
- #
- # add upg_registry
- loaded_modules, processed_modules = _load_module_graph(
- cr, graph, status, perform_checks=update_module,
- report=report, models_to_check=models_to_check, upg_registry=upg_registry)
-
- #
- load_lang = tools.config.pop('load_language')
- if load_lang or update_module:
- # some base models are used below, so make sure they are set up
- registry.setup_models(cr)
-
- if load_lang:
- for lang in load_lang.split(','):
- tools.load_language(cr, lang)
-
- # STEP 2: Mark other modules to be loaded/updated
- if update_module:
- env = api.Environment(cr, SUPERUSER_ID, {})
- Module = env['ir.module.module']
- _logger.info('updating modules list')
- Module.update_list()
-
- _check_module_names(cr, itertools.chain(tools.config['init'], tools.config['update']))
-
- module_names = [k for k, v in tools.config['init'].items() if v]
- if module_names:
- modules = Module.search([('state', '=', 'uninstalled'), ('name', 'in', module_names)])
- if modules:
- modules.button_install()
-
- module_names = [k for k, v in tools.config['update'].items() if v]
- if module_names:
- #
- # in standard Odoo, '--update all' just means:
- # '--update base + upward (installed) dependencies. This breaks
- # the chain when new glue modules are encountered.
- # E.g. purchase in 8.0 depends on stock_account and report,
- # both of which are new. They may be installed, but purchase as
- # an upward dependency is not selected for upgrade.
- # Therefore, explicitely select all installed modules for
- # upgrading in OpenUpgrade in that case.
- domain = [('state', '=', 'installed')]
- if 'all' not in module_names:
- domain.append(('name', 'in', module_names))
- modules = Module.search(domain)
- #
- if modules:
- modules.button_upgrade()
-
- cr.execute("update ir_module_module set state=%s where name=%s", ('installed', 'base'))
- Module.invalidate_cache(['state'])
- Module.flush()
-
- # STEP 3: Load marked modules (skipping base which was done in STEP 1)
- # IMPORTANT: this is done in two parts, first loading all installed or
- # partially installed modules (i.e. installed/to upgrade), to
- # offer a consistent system to the second part: installing
- # newly selected modules.
- # We include the modules 'to remove' in the first step, because
- # they are part of the "currently installed" modules. They will
- # be dropped in STEP 6 later, before restarting the loading
- # process.
- # IMPORTANT 2: We have to loop here until all relevant modules have been
- # processed, because in some rare cases the dependencies have
- # changed, and modules that depend on an uninstalled module
- # will not be processed on the first pass.
- # It's especially useful for migrations.
- previously_processed = -1
- while previously_processed < len(processed_modules):
- previously_processed = len(processed_modules)
- #
- # add upg_registry
- processed_modules += _load_marked_modules(cr, graph,
- ['installed', 'to upgrade', 'to remove'],
- force, status, report, loaded_modules, update_module, models_to_check, upg_registry)
- #
- if update_module:
- #
- # add upg_registry
- processed_modules += _load_marked_modules(cr, graph,
- ['to install'], force, status, report,
- loaded_modules, update_module, models_to_check, upg_registry)
- #
- # check that new module dependencies have been properly installed after a migration/upgrade
- cr.execute("SELECT name from ir_module_module WHERE state IN ('to install', 'to upgrade')")
- module_list = [name for (name,) in cr.fetchall()]
- if module_list:
- _logger.error("Some modules have inconsistent states, some dependencies may be missing: %s", sorted(module_list))
-
- # check that all installed modules have been loaded by the registry after a migration/upgrade
- cr.execute("SELECT name from ir_module_module WHERE state = 'installed' and name != 'studio_customization'")
- module_list = [name for (name,) in cr.fetchall() if name not in graph]
- if module_list:
- _logger.error("Some modules are not loaded, some dependencies or manifest may be missing: %s", sorted(module_list))
-
- registry.loaded = True
- registry.setup_models(cr)
-
- # STEP 3.5: execute migration end-scripts
- migrations = odoo.modules.migration.MigrationManager(cr, graph)
- for package in graph:
- migrations.migrate_module(package, 'end')
-
- # STEP 3.6: apply remaining constraints in case of an upgrade
- registry.finalize_constraints()
-
- # STEP 4: Finish and cleanup installations
- if processed_modules:
- env = api.Environment(cr, SUPERUSER_ID, {})
- cr.execute("""select model,name from ir_model where id NOT IN (select distinct model_id from ir_model_access)""")
- for (model, name) in cr.fetchall():
- if model in registry and not registry[model]._abstract:
- _logger.warning('The model %s has no access rules, consider adding one. E.g. access_%s,access_%s,model_%s,base.group_user,1,0,0,0',
- model, model.replace('.', '_'), model.replace('.', '_'), model.replace('.', '_'))
-
- cr.execute("SELECT model from ir_model")
- for (model,) in cr.fetchall():
- if model in registry:
- env[model]._check_removed_columns(log=True)
- elif _logger.isEnabledFor(logging.INFO): # more an info that a warning...
- _logger.runbot("Model %s is declared but cannot be loaded! (Perhaps a module was partially removed or renamed)", model)
-
- # Cleanup orphan records
- env['ir.model.data']._process_end(processed_modules)
- env['base'].flush()
-
- for kind in ('init', 'demo', 'update'):
- tools.config[kind] = {}
-
- # STEP 5: Uninstall modules to remove
- if update_module:
- # Remove records referenced from ir_model_data for modules to be
- # removed (and removed the references from ir_model_data).
- cr.execute("SELECT name, id FROM ir_module_module WHERE state=%s", ('to remove',))
- modules_to_remove = dict(cr.fetchall())
- if modules_to_remove:
- env = api.Environment(cr, SUPERUSER_ID, {})
- pkgs = reversed([p for p in graph if p.name in modules_to_remove])
- for pkg in pkgs:
- uninstall_hook = pkg.info.get('uninstall_hook')
- if uninstall_hook:
- py_module = sys.modules['odoo.addons.%s' % (pkg.name,)]
- getattr(py_module, uninstall_hook)(cr, registry)
-
- Module = env['ir.module.module']
- Module.browse(modules_to_remove.values()).module_uninstall()
- # Recursive reload, should only happen once, because there should be no
- # modules to remove next time
- cr.commit()
- _logger.info('Reloading registry once more after uninstalling modules')
- api.Environment.reset()
- registry = odoo.modules.registry.Registry.new(
- cr.dbname, force_demo, status, update_module
- )
- registry.check_tables_exist(cr)
- cr.commit()
- return registry
-
- # STEP 5.5: Verify extended fields on every model
- # This will fix the schema of all models in a situation such as:
- # - module A is loaded and defines model M;
- # - module B is installed/upgraded and extends model M;
- # - module C is loaded and extends model M;
- # - module B and C depend on A but not on each other;
- # The changes introduced by module C are not taken into account by the upgrade of B.
- if models_to_check:
- registry.init_models(cr, list(models_to_check), {'models_to_check': True})
-
- # STEP 6: verify custom views on every model
- if update_module:
- env = api.Environment(cr, SUPERUSER_ID, {})
- env['res.groups']._update_user_groups_view()
- View = env['ir.ui.view']
- for model in registry:
- try:
- View._validate_custom_views(model)
- except Exception as e:
- _logger.warning('invalid custom view(s) for model %s: %s', model, tools.ustr(e))
-
- if report.wasSuccessful():
- _logger.info('Modules loaded.')
- else:
- _logger.error('At least one test failed when loading the modules.')
-
- # STEP 8: call _register_hook on every model
- # This is done *exactly once* when the registry is being loaded. See the
- # management of those hooks in `Registry.setup_models`: all the calls to
- # setup_models() done here do not mess up with hooks, as registry.ready
- # is False.
- env = api.Environment(cr, SUPERUSER_ID, {})
- for model in env.values():
- model._register_hook()
- env['base'].flush()
-
- # STEP 9: save installed/updated modules for post-install tests
- registry.updated_modules += processed_modules
-
-loading.load_module_graph = _load_module_graph
-loading.load_marked_modules = _load_marked_modules
-loading.load_modules = _load_modules
-odoo.modules.load_modules = _load_modules
diff --git a/upgrade_analysis/odoo_patch/odoo/modules/migration.py b/upgrade_analysis/odoo_patch/odoo/modules/migration.py
deleted file mode 100644
index 0346c2b8c..000000000
--- a/upgrade_analysis/odoo_patch/odoo/modules/migration.py
+++ /dev/null
@@ -1,118 +0,0 @@
-# flake8: noqa
-# pylint: skip-file
-
-import logging
-import os
-from os.path import join as opj
-import odoo.release as release
-from odoo.tools.parse_version import parse_version
-
-import odoo
-from odoo.modules.migration import load_script
-from odoo.modules import migration
-
-_logger = logging.getLogger(__name__)
-
-
-if True:
- def _migrate_module(self, pkg, stage):
- assert stage in ('pre', 'post', 'end')
- stageformat = {
- 'pre': '[>%s]',
- 'post': '[%s>]',
- 'end': '[$%s]',
- }
- state = pkg.state if stage in ('pre', 'post') else getattr(pkg, 'load_state', None)
-
- #
- # In openupgrade, also run migration scripts upon installation.
- # We want to always pass in pre and post migration files and use a new
- # argument in the migrate decorator (explained in the docstring)
- # to decide if we want to do something if a new module is installed
- # during the migration.
- if not (hasattr(pkg, 'update') or state in ('to upgrade', 'to install')):
- #
- return
-
- def convert_version(version):
- if version.count('.') >= 2:
- return version # the version number already containt the server version
- return "%s.%s" % (release.major_version, version)
-
- def _get_migration_versions(pkg, stage):
- versions = sorted({
- ver
- for lv in self.migrations[pkg.name].values()
- for ver, lf in lv.items()
- if lf
- }, key=lambda k: parse_version(convert_version(k)))
- if "0.0.0" in versions:
- # reorder versions
- versions.remove("0.0.0")
- if stage == "pre":
- versions.insert(0, "0.0.0")
- else:
- versions.append("0.0.0")
- return versions
-
- def _get_migration_files(pkg, version, stage):
- """ return a list of migration script files
- """
- m = self.migrations[pkg.name]
- lst = []
-
- mapping = {
- 'module': opj(pkg.name, 'migrations'),
- 'module_upgrades': opj(pkg.name, 'upgrades'),
- }
-
- for path in odoo.upgrade.__path__:
- if os.path.exists(opj(path, pkg.name)):
- mapping['upgrade'] = opj(path, pkg.name)
- break
-
- for x in mapping:
- if version in m.get(x):
- for f in m[x][version]:
- if not f.startswith(stage + '-'):
- continue
- lst.append(opj(mapping[x], version, f))
- lst.sort()
- return lst
-
- installed_version = getattr(pkg, 'load_version', pkg.installed_version) or ''
- parsed_installed_version = parse_version(installed_version)
- current_version = parse_version(convert_version(pkg.data['version']))
-
- versions = _get_migration_versions(pkg, stage)
-
- for version in versions:
- if ((version == "0.0.0" and parsed_installed_version < current_version)
- or parsed_installed_version < parse_version(convert_version(version)) <= current_version):
-
- strfmt = {'addon': pkg.name,
- 'stage': stage,
- 'version': stageformat[stage] % version,
- }
-
- for pyfile in _get_migration_files(pkg, version, stage):
- name, ext = os.path.splitext(os.path.basename(pyfile))
- if ext.lower() != '.py':
- continue
- mod = None
- try:
- mod = load_script(pyfile, name)
- _logger.info('module %(addon)s: Running migration %(version)s %(name)s' % dict(strfmt, name=mod.__name__))
- migrate = mod.migrate
- except ImportError:
- _logger.exception('module %(addon)s: Unable to load %(stage)s-migration file %(file)s' % dict(strfmt, file=pyfile))
- raise
- except AttributeError:
- _logger.error('module %(addon)s: Each %(stage)s-migration file must have a "migrate(cr, installed_version)" function' % strfmt)
- else:
- migrate(self.cr, installed_version)
- finally:
- if mod:
- del mod
-
-migration.migrate_module = _migrate_module
diff --git a/upgrade_analysis/odoo_patch/odoo/modules/registry.py b/upgrade_analysis/odoo_patch/odoo/modules/registry.py
index 4c5f50d4e..3d0981a00 100644
--- a/upgrade_analysis/odoo_patch/odoo/modules/registry.py
+++ b/upgrade_analysis/odoo_patch/odoo/modules/registry.py
@@ -1,58 +1,29 @@
-# flake8: noqa
-# pylint: skip-file
+import logging
+from threading import current_thread
+from odoo import api, SUPERUSER_ID
+from ...odoo_patch import OdooPatch
+from .... import upgrade_log
+from odoo.modules.registry import Registry
-from collections import deque
-from contextlib import closing
-import odoo
-from odoo.tools.lru import LRU
-
-from odoo.modules import registry
+_logger = logging.getLogger(__name__)
-if True:
+class RegistryPatch(OdooPatch):
+ target = Registry
+ method_names = ['init_models']
- def _init(self, db_name):
- self.models = {} # model name/model instance mapping
- self._sql_constraints = set()
- self._init = True
- self._assertion_report = odoo.tests.runner.OdooTestResult()
- self._fields_by_model = None
- self._ordinary_tables = None
- self._constraint_queue = deque()
- self.__cache = LRU(8192)
+ def init_models(self, cr, model_names, context, install=True):
+ module_name = context['module']
+ _logger.debug('Logging models of module %s', module_name)
+ upg_registry = current_thread()._upgrade_registry
+ local_registry = {}
+ env = api.Environment(cr, SUPERUSER_ID, {})
+ for model in env.values():
+ if not model._auto:
+ continue
+ upgrade_log.log_model(model, local_registry)
+ upgrade_log.compare_registries(
+ cr, context['module'], upg_registry, local_registry)
- # modules fully loaded (maintained during init phase by `loading` module)
- self._init_modules = set()
- self.updated_modules = [] # installed/updated modules
- #
- self.openupgrade_test_prefixes = {}
- #
- self.loaded_xmlids = set()
-
- self.db_name = db_name
- self._db = odoo.sql_db.db_connect(db_name)
-
- # cursor for test mode; None means "normal" mode
- self.test_cr = None
- self.test_lock = None
-
- # Indicates that the registry is
- self.loaded = False # whether all modules are loaded
- self.ready = False # whether everything is set up
-
- # Inter-process signaling:
- # The `base_registry_signaling` sequence indicates the whole registry
- # must be reloaded.
- # The `base_cache_signaling sequence` indicates all caches must be
- # invalidated (i.e. cleared).
- self.registry_sequence = None
- self.cache_sequence = None
-
- # Flags indicating invalidation of the registry or the cache.
- self.registry_invalidated = False
- self.cache_invalidated = False
-
- with closing(self.cursor()) as cr:
- self.has_unaccent = odoo.modules.db.has_unaccent(cr)
-
-registry.init = _init
+ return RegistryPatch.init_models._original_method(
+ self, cr, model_names, context, install=install)
diff --git a/upgrade_analysis/odoo_patch/odoo/service/__init__.py b/upgrade_analysis/odoo_patch/odoo/service/__init__.py
deleted file mode 100644
index a96314d0f..000000000
--- a/upgrade_analysis/odoo_patch/odoo/service/__init__.py
+++ /dev/null
@@ -1,4 +0,0 @@
-# Import disabled, because the function run_unit_tests()
-# disappeared in V14.
-# TODO: OpenUpgrade Core maintainers : FIXME.
-# from . import server
diff --git a/upgrade_analysis/odoo_patch/odoo/service/server.py b/upgrade_analysis/odoo_patch/odoo/service/server.py
deleted file mode 100644
index a2a998e69..000000000
--- a/upgrade_analysis/odoo_patch/odoo/service/server.py
+++ /dev/null
@@ -1,71 +0,0 @@
-# flake8: noqa
-# pylint: skip-file
-
-import logging
-import os
-import time
-
-import odoo
-from odoo.tools import config
-from odoo.modules.registry import Registry
-
-from odoo.service import server
-from odoo.service.server import load_test_file_py
-
-_logger = logging.getLogger(__name__)
-
-
-def preload_registries(dbnames):
- """ Preload a registries, possibly run a test file."""
- # TODO: move all config checks to args dont check tools.config here
- dbnames = dbnames or []
- rc = 0
- for dbname in dbnames:
- try:
- update_module = config['init'] or config['update']
- registry = Registry.new(dbname, update_module=update_module)
-
- # run test_file if provided
- if config['test_file']:
- test_file = config['test_file']
- if not os.path.isfile(test_file):
- _logger.warning('test file %s cannot be found', test_file)
- elif not test_file.endswith('py'):
- _logger.warning('test file %s is not a python file', test_file)
- else:
- _logger.info('loading test file %s', test_file)
- with odoo.api.Environment.manage():
- load_test_file_py(registry, test_file)
-
- # run post-install tests
- if config['test_enable']:
- t0 = time.time()
- t0_sql = odoo.sql_db.sql_counter
- module_names = (registry.updated_modules if update_module else
- sorted(registry._init_modules))
- _logger.info("Starting post tests")
- tests_before = registry._assertion_report.testsRun
- with odoo.api.Environment.manage():
- for module_name in module_names:
- result = loader.run_suite(loader.make_suite(module_name, 'post_install'), module_name)
- registry._assertion_report.update(result)
- #
- # run deferred unit tests
- for module_name, prefix in registry.openupgrade_test_prefixes:
- result = run_unit_tests(module_name, position='post_install', openupgrade_prefix=prefix)
- registry._assertion_report.record_result(result)
- #
- _logger.info("%d post-tests in %.2fs, %s queries",
- registry._assertion_report.testsRun - tests_before,
- time.time() - t0,
- odoo.sql_db.sql_counter - t0_sql)
-
- if not registry._assertion_report.wasSuccessful():
- rc += 1
- except Exception:
- _logger.critical('Failed to initialize database `%s`.', dbname, exc_info=True)
- return -1
- return rc
-
-
-server.preload_registries = preload_registries
diff --git a/upgrade_analysis/odoo_patch/odoo/tools/__init__.py b/upgrade_analysis/odoo_patch/odoo/tools/__init__.py
index 6ad156515..99a9527ec 100644
--- a/upgrade_analysis/odoo_patch/odoo/tools/__init__.py
+++ b/upgrade_analysis/odoo_patch/odoo/tools/__init__.py
@@ -1,2 +1 @@
from . import convert
-from . import view_validation
diff --git a/upgrade_analysis/odoo_patch/odoo/tools/convert.py b/upgrade_analysis/odoo_patch/odoo/tools/convert.py
index 8c1f710a5..7130859d6 100644
--- a/upgrade_analysis/odoo_patch/odoo/tools/convert.py
+++ b/upgrade_analysis/odoo_patch/odoo/tools/convert.py
@@ -1,23 +1,13 @@
-# flake8: noqa
-# pylint: skip-file
-
+from ...odoo_patch import OdooPatch
from .... import upgrade_log
-
from odoo.tools.convert import xml_import
-if True:
- def __test_xml_id(self, xml_id):
- if '.' in xml_id:
- module, id = xml_id.split('.', 1)
- assert '.' not in id, """The ID reference "%s" must contain
-maximum one dot. They are used to refer to other modules ID, in the
-form: module.record_id""" % (xml_id,)
- if module != self.module:
- modcnt = self.env['ir.module.module'].search_count([('name', '=', module), ('state', '=', 'installed')])
- assert modcnt == 1, """The ID "%s" refers to an uninstalled module""" % (xml_id,)
+class XMLImportPatch(OdooPatch):
+ target = xml_import
+ method_names = ['_test_xml_id']
- # OpenUpgrade: log entry of XML imports
+ def _test_xml_id(self, xml_id):
+ res = XMLImportPatch._test_xml_id._original_method(self, xml_id)
upgrade_log.log_xml_id(self.env.cr, self.module, xml_id)
-
-xml_import._test_xml_id = __test_xml_id
+ return res
diff --git a/upgrade_analysis/odoo_patch/odoo/tools/view_validation.py b/upgrade_analysis/odoo_patch/odoo/tools/view_validation.py
deleted file mode 100644
index e6c824324..000000000
--- a/upgrade_analysis/odoo_patch/odoo/tools/view_validation.py
+++ /dev/null
@@ -1,29 +0,0 @@
-# flake8: noqa
-# pylint: skip-file
-
-# from odoo.addons.openupgrade_framework.openupgrade import openupgrade_log
-
-from odoo.tools import view_validation
-from odoo.tools.view_validation import _validators, _logger
-
-
-def _valid_view(arch, **kwargs):
- for pred in _validators[arch.tag]:
- #
- # Do not raise blocking error, because it's normal to
- # have inconsistent views in an openupgrade process
- check = pred(arch, **kwargs) or 'Warning'
- #
- if not check:
- _logger.error("Invalid XML: %s", pred.__doc__)
- return False
- if check == "Warning":
- #
- # Don't show this warning as useless and too much verbose
- # _logger.warning("Invalid XML: %s", pred.__doc__)
- #
- return "Warning"
- return True
-
-
-view_validation.valid_view = _valid_view
diff --git a/upgrade_analysis/odoo_patch/odoo_patch.py b/upgrade_analysis/odoo_patch/odoo_patch.py
new file mode 100644
index 000000000..ac9f02fee
--- /dev/null
+++ b/upgrade_analysis/odoo_patch/odoo_patch.py
@@ -0,0 +1,59 @@
+import logging
+
+_logger = logging.getLogger(__name__)
+
+
+class OdooPatch(object):
+ """ Simple mechanism to apply a collection of monkeypatches using a
+ context manager.
+
+ Classes can register their monkeypatches by inheriting from this class.
+ They need to define a `target` member, referring to the object or module
+ that needs to be patched, and a list `method_names`. They also need to
+ redefine those methods under the same name.
+
+ The original method is made available on the new method as
+ `_original_method`.
+
+ Example:
+
+ ```
+ from odoo import api
+ from odoo.addons.some_module.models.my_model import MyModel
+
+ class MyModelPatch(OdooPatch):
+ target = MyModel
+ method_names = ['do_something']
+
+ @api.model
+ def do_something(self):
+ res = MyModelPatch.do_something._original_method()
+ ...
+ return res
+ ```
+
+ Usage:
+
+ ```
+ with OdooPatch():
+ do_something()
+ ```
+ """
+ def __enter__(self):
+ for cls in OdooPatch.__subclasses__():
+ for method_name in cls.method_names:
+ method = getattr(cls, method_name)
+ setattr(method, '_original_method',
+ getattr(cls.target, method_name))
+ setattr(cls.target, method_name, method)
+
+ def __exit__(self, exc_type, exc_value, tb):
+ for cls in OdooPatch.__subclasses__():
+ for method_name in cls.method_names:
+ method = getattr(cls.target, method_name)
+ if hasattr(method, '_original_method'):
+ setattr(cls.target, method_name, method._original_method)
+ else:
+ _logger.warn(
+ '_original_method not found on method %s of class %s',
+ method_name, cls.target)
diff --git a/upgrade_analysis/upgrade_loading.py b/upgrade_analysis/upgrade_loading.py
deleted file mode 100644
index 1187a5900..000000000
--- a/upgrade_analysis/upgrade_loading.py
+++ /dev/null
@@ -1,316 +0,0 @@
-# Copyright 2011-2015 Therp BV
-# Copyright 2016-2019 Opener B.V.
-# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
-
-# flake8: noqa: C901
-
-import logging
-
-from openupgradelib.openupgrade_tools import table_exists
-
-from odoo import release
-from odoo.modules.module import get_module_path
-from odoo.tools.config import config
-from odoo.tools.safe_eval import safe_eval
-
-# A collection of functions used in
-# odoo/modules/loading.py
-
-_logger = logging.getLogger(__name__)
-
-
-def add_module_dependencies(cr, module_list):
- """
- Select (new) dependencies from the modules in the list
- so that we can inject them into the graph at upgrade
- time. Used in the modified OpenUpgrade Server,
- not to be called from migration scripts
-
- Also take the OpenUpgrade configuration directives 'forced_deps'
- and 'autoinstall' into account. From any additional modules
- that these directives can add, the dependencies are added as
- well (but these directives are not checked for the occurrence
- of any of the dependencies).
- """
- if not module_list:
- return module_list
-
- modules_in = list(module_list)
- forced_deps = safe_eval(
- config.get_misc(
- "openupgrade",
- "forced_deps_" + release.version,
- config.get_misc("openupgrade", "forced_deps", "{}"),
- )
- )
-
- autoinstall = safe_eval(
- config.get_misc(
- "openupgrade",
- "autoinstall_" + release.version,
- config.get_misc("openupgrade", "autoinstall", "{}"),
- )
- )
-
- for module in list(module_list):
- module_list += forced_deps.get(module, [])
- module_list += autoinstall.get(module, [])
-
- module_list = list(set(module_list))
-
- dependencies = module_list
- while dependencies:
- cr.execute(
- """
- SELECT DISTINCT dep.name
- FROM
- ir_module_module,
- ir_module_module_dependency dep
- WHERE
- module_id = ir_module_module.id
- AND ir_module_module.name in %s
- AND dep.name not in %s
- """,
- (
- tuple(dependencies),
- tuple(module_list),
- ),
- )
-
- dependencies = [x[0] for x in cr.fetchall()]
- module_list += dependencies
-
- # Select auto_install modules of which all dependencies
- # are fulfilled based on the modules we know are to be
- # installed
- cr.execute(
- """
- SELECT name from ir_module_module WHERE state IN %s
- """,
- (("installed", "to install", "to upgrade"),),
- )
- modules = list(set(module_list + [row[0] for row in cr.fetchall()]))
- cr.execute(
- """
- SELECT name from ir_module_module m
- WHERE auto_install IS TRUE
- AND state = 'uninstalled'
- AND NOT EXISTS(
- SELECT id FROM ir_module_module_dependency d
- WHERE d.module_id = m.id
- AND name NOT IN %s)
- """,
- (tuple(modules),),
- )
- auto_modules = [row[0] for row in cr.fetchall() if get_module_path(row[0])]
- if auto_modules:
- _logger.info("Selecting autoinstallable modules %s", ",".join(auto_modules))
- module_list += auto_modules
-
- # Set proper state for new dependencies so that any init scripts are run
- cr.execute(
- """
- UPDATE ir_module_module SET state = 'to install'
- WHERE name IN %s AND name NOT IN %s AND state = 'uninstalled'
- """,
- (tuple(module_list), tuple(modules_in)),
- )
- return module_list
-
-
-def log_model(model, local_registry):
- """
- OpenUpgrade: Store the characteristics of the BaseModel and its fields
- in the local registry, so that we can compare changes with the
- main registry
- """
-
- if not model._name:
- return
-
- typemap = {"monetary": "float"}
-
- # Deferred import to prevent import loop
- from odoo import models
-
- # persistent models only
- if isinstance(model, models.TransientModel):
- return
-
- def isfunction(model, k):
- if (
- model._fields[k].compute
- and not model._fields[k].related
- and not model._fields[k].company_dependent
- ):
- return "function"
- return ""
-
- def isproperty(model, k):
- if model._fields[k].company_dependent:
- return "property"
- return ""
-
- def isrelated(model, k):
- if model._fields[k].related:
- return "related"
- return ""
-
- def _get_relation(v):
- if v.type in ("many2many", "many2one", "one2many"):
- return v.comodel_name
- elif v.type == "many2one_reference":
- return v.model_field
- else:
- return ""
-
- model_registry = local_registry.setdefault(model._name, {})
- if model._inherits:
- model_registry["_inherits"] = {"_inherits": str(model._inherits)}
- for k, v in model._fields.items():
- properties = {
- "type": typemap.get(v.type, v.type),
- "isfunction": isfunction(model, k),
- "isproperty": isproperty(model, k),
- "isrelated": isrelated(model, k),
- "relation": _get_relation(v),
- "table": v.relation if v.type == "many2many" else "",
- "required": v.required and "required" or "",
- "stored": v.store and "stored" or "",
- "selection_keys": "",
- "req_default": "",
- "hasdefault": model._fields[k].default and "hasdefault" or "",
- "inherits": "",
- }
- if v.type == "selection":
- if isinstance(v.selection, (tuple, list)):
- properties["selection_keys"] = str(sorted([x[0] for x in v.selection]))
- else:
- properties["selection_keys"] = "function"
- elif v.type == "binary":
- properties["attachment"] = str(getattr(v, "attachment", False))
- default = model._fields[k].default
- if v.required and default:
- if (
- callable(default)
- or isinstance(default, str)
- and getattr(model._fields[k], default, False)
- and callable(getattr(model._fields[k], default))
- ):
- # todo: in OpenERP 5 (and in 6 as well),
- # literals are wrapped in a lambda function
- properties["req_default"] = "function"
- else:
- properties["req_default"] = str(default)
- for key, value in properties.items():
- if value:
- model_registry.setdefault(k, {})[key] = value
-
-
-def get_record_id(cr, module, model, field, mode):
- """
- OpenUpgrade: get or create the id from the record table matching
- the key parameter values
- """
- cr.execute(
- "SELECT id FROM upgrade_record "
- "WHERE module = %s AND model = %s AND "
- "field = %s AND mode = %s AND type = %s",
- (module, model, field, mode, "field"),
- )
- record = cr.fetchone()
- if record:
- return record[0]
- cr.execute(
- "INSERT INTO upgrade_record "
- "(module, model, field, mode, type) "
- "VALUES (%s, %s, %s, %s, %s)",
- (module, model, field, mode, "field"),
- )
- cr.execute(
- "SELECT id FROM upgrade_record "
- "WHERE module = %s AND model = %s AND "
- "field = %s AND mode = %s AND type = %s",
- (module, model, field, mode, "field"),
- )
- return cr.fetchone()[0]
-
-
-def compare_registries(cr, module, registry, local_registry):
- """
- OpenUpgrade: Compare the local registry with the global registry,
- log any differences and merge the local registry with
- the global one.
- """
- if not table_exists(cr, "upgrade_record"):
- return
- for model, flds in local_registry.items():
- registry.setdefault(model, {})
- for field, attributes in flds.items():
- old_field = registry[model].setdefault(field, {})
- mode = old_field and "modify" or "create"
- record_id = False
- for key, value in attributes.items():
- if key not in old_field or old_field[key] != value:
- if not record_id:
- record_id = get_record_id(cr, module, model, field, mode)
- cr.execute(
- "SELECT id FROM upgrade_attribute "
- "WHERE name = %s AND value = %s AND "
- "record_id = %s",
- (key, value, record_id),
- )
- if not cr.fetchone():
- cr.execute(
- "INSERT INTO upgrade_attribute "
- "(name, value, record_id) VALUES (%s, %s, %s)",
- (key, value, record_id),
- )
- old_field[key] = value
-
-
-def update_field_xmlid(model, field):
- """OpenUpgrade edit start: In rare cases, an old module defined a field
- on a model that is not defined in another module earlier in the
- chain of inheritance. Then we need to assign the ir.model.fields'
- xmlid to this other module, otherwise the column would be dropped
- when uninstalling the first module.
- An example is res.partner#display_name defined in 7.0 by
- account_report_company, but now the field belongs to the base
- module
- Given that we arrive here in order of inheritance, we simply check
- if the field's xmlid belongs to a module already loaded, and if not,
- update the record with the correct module name."""
- model.env.cr.execute(
- "SELECT f.*, d.module, d.id as xmlid_id, d.name as xmlid "
- "FROM ir_model_fields f LEFT JOIN ir_model_data d "
- "ON f.id=d.res_id and d.model='ir.model.fields' WHERE f.model=%s",
- (model._name,),
- )
- for rec in model.env.cr.dictfetchall():
- if (
- "module" in model.env.context
- and rec["module"]
- and rec["name"] in model._fields.keys()
- and rec["module"] != model.env.context["module"]
- and rec["module"] not in model.env.registry._init_modules
- ):
- _logger.info(
- "Moving XMLID for ir.model.fields record of %s#%s " "from %s to %s",
- model._name,
- rec["name"],
- rec["module"],
- model.env.context["module"],
- )
- model.env.cr.execute(
- "SELECT id FROM ir_model_data WHERE module=%(module)s "
- "AND name=%(xmlid)s",
- dict(rec, module=model.env.context["module"]),
- )
- if model.env.cr.fetchone():
- _logger.info("Aborting, an XMLID for this module already exists.")
- continue
- model.env.cr.execute(
- "UPDATE ir_model_data SET module=%(module)s " "WHERE id=%(xmlid_id)s",
- dict(rec, module=model.env.context["module"]),
- )
diff --git a/upgrade_analysis/upgrade_log.py b/upgrade_analysis/upgrade_log.py
index 2563ecbc6..10c28596b 100644
--- a/upgrade_analysis/upgrade_log.py
+++ b/upgrade_analysis/upgrade_log.py
@@ -6,9 +6,161 @@ import logging
from openupgradelib.openupgrade_tools import table_exists
+from odoo import models
+
_logger = logging.getLogger(__name__)
+def get_record_id(cr, module, model, field, mode):
+ """
+ OpenUpgrade: get or create the id from the record table matching
+ the key parameter values
+ """
+ cr.execute(
+ "SELECT id FROM upgrade_record "
+ "WHERE module = %s AND model = %s AND "
+ "field = %s AND mode = %s AND type = %s",
+ (module, model, field, mode, "field"),
+ )
+ record = cr.fetchone()
+ if record:
+ return record[0]
+ cr.execute(
+ "INSERT INTO upgrade_record "
+ "(module, model, field, mode, type) "
+ "VALUES (%s, %s, %s, %s, %s)",
+ (module, model, field, mode, "field"),
+ )
+ cr.execute(
+ "SELECT id FROM upgrade_record "
+ "WHERE module = %s AND model = %s AND "
+ "field = %s AND mode = %s AND type = %s",
+ (module, model, field, mode, "field"),
+ )
+ return cr.fetchone()[0]
+
+
+def compare_registries(cr, module, registry, local_registry):
+ """
+ OpenUpgrade: Compare the local registry with the global registry,
+ log any differences and merge the local registry with
+ the global one.
+ """
+ if not table_exists(cr, "upgrade_record"):
+ return
+ for model, flds in local_registry.items():
+ registry.setdefault(model, {})
+ for field, attributes in flds.items():
+ old_field = registry[model].setdefault(field, {})
+ mode = old_field and "modify" or "create"
+ record_id = False
+ for key, value in attributes.items():
+ if key not in old_field or old_field[key] != value:
+ if not record_id:
+ record_id = get_record_id(cr, module, model, field, mode)
+ cr.execute(
+ "SELECT id FROM upgrade_attribute "
+ "WHERE name = %s AND value = %s AND "
+ "record_id = %s",
+ (key, value, record_id),
+ )
+ if not cr.fetchone():
+ cr.execute(
+ "INSERT INTO upgrade_attribute "
+ "(name, value, record_id) VALUES (%s, %s, %s)",
+ (key, value, record_id),
+ )
+ old_field[key] = value
+
+
+def isfunction(model, k):
+ if (
+ model._fields[k].compute
+ and not model._fields[k].related
+ and not model._fields[k].company_dependent
+ ):
+ return "function"
+ return ""
+
+
+def isproperty(model, k):
+ if model._fields[k].company_dependent:
+ return "property"
+ return ""
+
+
+def isrelated(model, k):
+ if model._fields[k].related:
+ return "related"
+ return ""
+
+
+def _get_relation(v):
+ if v.type in ("many2many", "many2one", "one2many"):
+ return v.comodel_name
+ elif v.type == "many2one_reference":
+ return v.model_field
+ else:
+ return ""
+
+
+def log_model(model, local_registry):
+ """
+ OpenUpgrade: Store the characteristics of the BaseModel and its fields
+ in the local registry, so that we can compare changes with the
+ main registry
+ """
+
+ if not model._name:
+ return
+
+ typemap = {"monetary": "float"}
+
+ # persistent models only
+ if isinstance(model, models.TransientModel):
+ return
+
+ model_registry = local_registry.setdefault(model._name, {})
+ if model._inherits:
+ model_registry["_inherits"] = {"_inherits": str(model._inherits)}
+ for k, v in model._fields.items():
+ properties = {
+ "type": typemap.get(v.type, v.type),
+ "isfunction": isfunction(model, k),
+ "isproperty": isproperty(model, k),
+ "isrelated": isrelated(model, k),
+ "relation": _get_relation(v),
+ "table": v.relation if v.type == "many2many" else "",
+ "required": v.required and "required" or "",
+ "stored": v.store and "stored" or "",
+ "selection_keys": "",
+ "req_default": "",
+ "hasdefault": model._fields[k].default and "hasdefault" or "",
+ "inherits": "",
+ }
+ if v.type == "selection":
+ if isinstance(v.selection, (tuple, list)):
+ properties["selection_keys"] = str(sorted([x[0] for x in v.selection]))
+ else:
+ properties["selection_keys"] = "function"
+ elif v.type == "binary":
+ properties["attachment"] = str(getattr(v, "attachment", False))
+ default = model._fields[k].default
+ if v.required and default:
+ if (
+ callable(default)
+ or isinstance(default, str)
+ and getattr(model._fields[k], default, False)
+ and callable(getattr(model._fields[k], default))
+ ):
+ properties["req_default"] = "function"
+ else:
+ properties["req_default"] = str(default)
+ for key, value in properties.items():
+ if value:
+ model_registry.setdefault(k, {})[key] = value
+
+
def log_xml_id(cr, module, xml_id):
"""
Log xml_ids at load time in the records table.
@@ -49,7 +201,7 @@ def log_xml_id(cr, module, xml_id):
)
record = cr.fetchone()
if not record:
- _logger.warning("Cannot find xml_id %s" % xml_id)
+ _logger.warning("Cannot find xml_id %s", xml_id)
return
else:
cr.execute(
diff --git a/upgrade_analysis/views/view_upgrade_analysis.xml b/upgrade_analysis/views/view_upgrade_analysis.xml
index 375253ce9..c2ce39170 100644
--- a/upgrade_analysis/views/view_upgrade_analysis.xml
+++ b/upgrade_analysis/views/view_upgrade_analysis.xml
@@ -36,6 +36,10 @@
name="write_files"
attrs="{'readonly': [('state', '=', 'done')]}"
/>
+
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
+from threading import current_thread
from odoo import _, fields, models
from odoo.exceptions import UserError
from odoo.modules.registry import Registry
+from ..odoo_patch.odoo_patch import OdooPatch
+
class GenerateWizard(models.TransientModel):
_name = "upgrade.generate.record.wizard"
@@ -14,26 +17,6 @@ class GenerateWizard(models.TransientModel):
state = fields.Selection([("draft", "Draft"), ("done", "Done")], default="draft")
- # from openupgradelib import openupgrade_tools
- # TODO, SLG, make better a patch in odoo_patch
- # def quirk_standard_calendar_attendances(self):
- # """Introduced in Odoo 13. The reinstallation causes a one2many value
- # in [(0, 0, {})] format to be loaded on top of the first load, causing a
- # violation of database constraint."""
- # for cal in ("resource_calendar_std_35h", "resource_calendar_std_38h"):
- # record = self.env.ref("resource.%s" % cal, False)
- # if record:
- # record.attendance_ids.unlink()
-
- # # Truncate the records table
- # if openupgrade_tools.table_exists(
- # self.env.cr, "upgrade_attribute"
- # ) and openupgrade_tools.table_exists(self.env.cr, "upgrade_record"):
- # self.env.cr.execute("TRUNCATE upgrade_attribute, upgrade_record;")
-
- # # Run any quirks
- # self.quirk_standard_calendar_attendances()
-
def generate(self):
"""Reinitialize all installed modules.
Equivalent of running the server with '-d --init all'
@@ -56,7 +39,17 @@ class GenerateWizard(models.TransientModel):
{"state": "to install"}
)
self.env.cr.commit() # pylint: disable=invalid-commit
- Registry.new(self.env.cr.dbname, update_module=True)
+
+ # Patch the registry on the thread
+ thread = current_thread()
+ thread._upgrade_registry = {}
+
+ # Regenerate the registry with monkeypatches that log the records
+ with OdooPatch():
+ Registry.new(self.env.cr.dbname, update_module=True)
+
+ # Free the registry
+ delattr(thread, "_upgrade_registry")
# Set domain property
self.env.cr.execute(
diff --git a/upgrade_analysis/wizards/upgrade_install_wizard.py b/upgrade_analysis/wizards/upgrade_install_wizard.py
index d91232867..94cc3a7fe 100644
--- a/upgrade_analysis/wizards/upgrade_install_wizard.py
+++ b/upgrade_analysis/wizards/upgrade_install_wizard.py
@@ -17,6 +17,10 @@ class UpgradeInstallWizard(models.TransientModel):
_name = "upgrade.install.wizard"
_description = "Upgrade Install Wizard"
+ name = fields.Char(
+ default=_description,
+ help="Workaround for https://github.com/OCA/odoorpc/issues/57",
+ )
state = fields.Selection(
[("draft", "Draft"), ("done", "Done")], readonly=True, default="draft"
)
@@ -52,30 +56,38 @@ class UpgradeInstallWizard(models.TransientModel):
for wizard in self:
wizard.module_qty = len(wizard.module_ids)
- def select_odoo_modules(self):
+ def select_odoo_modules(self, extra_domain=None):
self.ensure_one()
- modules = self.env["ir.module.module"].search(self._module_ids_domain())
+ modules = self.env["ir.module.module"].search(
+ self._module_ids_domain(extra_domain=extra_domain)
+ )
modules = modules.filtered(lambda x: x.is_odoo_module)
self.module_ids = modules
return self.return_same_form_view()
- def select_oca_modules(self):
+ def select_oca_modules(self, extra_domain=None):
self.ensure_one()
- modules = self.env["ir.module.module"].search(self._module_ids_domain())
+ modules = self.env["ir.module.module"].search(
+ self._module_ids_domain(extra_domain=extra_domain)
+ )
modules = modules.filtered(lambda x: x.is_oca_module)
self.module_ids = modules
return self.return_same_form_view()
- def select_other_modules(self):
+ def select_other_modules(self, extra_domain=None):
self.ensure_one()
- modules = self.env["ir.module.module"].search(self._module_ids_domain())
+ modules = self.env["ir.module.module"].search(
+ self._module_ids_domain(extra_domain=extra_domain)
+ )
modules = modules.filtered(lambda x: not (x.is_oca_module or x.is_odoo_module))
self.module_ids = modules
return self.return_same_form_view()
- def select_installable_modules(self):
+ def select_installable_modules(self, extra_domain=None):
self.ensure_one()
- self.module_ids = self.env["ir.module.module"].search(self._module_ids_domain())
+ self.module_ids = self.env["ir.module.module"].search(
+ self._module_ids_domain(extra_domain=extra_domain)
+ )
return self.return_same_form_view()
def unselect_modules(self):
From b16c6f36e34d388917aaebb98f351b568ca09936 Mon Sep 17 00:00:00 2001
From: Stefan Rijnhart
Date: Sun, 6 Dec 2020 12:23:12 +0100
Subject: [PATCH 08/67] [IMP] Create records with timestamp; [RFR] No
/migration/ level when using upgrade-path
---
upgrade_analysis/models/upgrade_analysis.py | 3 ++-
upgrade_analysis/upgrade_log.py | 10 ++++++----
.../wizards/upgrade_generate_record_wizard.py | 5 +++--
3 files changed, 11 insertions(+), 7 deletions(-)
diff --git a/upgrade_analysis/models/upgrade_analysis.py b/upgrade_analysis/models/upgrade_analysis.py
index 52eff5d85..39320ba0f 100644
--- a/upgrade_analysis/models/upgrade_analysis.py
+++ b/upgrade_analysis/models/upgrade_analysis.py
@@ -62,11 +62,12 @@ class UpgradeAnalysis(models.Model):
% module_name
)
module_path = os.path.join(self.upgrade_path, module_name)
+ full_path = os.path.join(module_path, version)
else:
module_path = get_module_path(module_name)
+ full_path = os.path.join(module_path, "migrations", version)
if not module_path:
return "ERROR: could not find module path of '%s':\n" % (module_name)
- full_path = os.path.join(module_path, "migrations", version)
if not os.path.exists(full_path):
try:
os.makedirs(full_path)
diff --git a/upgrade_analysis/upgrade_log.py b/upgrade_analysis/upgrade_log.py
index 10c28596b..345b1d772 100644
--- a/upgrade_analysis/upgrade_log.py
+++ b/upgrade_analysis/upgrade_log.py
@@ -27,8 +27,8 @@ def get_record_id(cr, module, model, field, mode):
return record[0]
cr.execute(
"INSERT INTO upgrade_record "
- "(module, model, field, mode, type) "
- "VALUES (%s, %s, %s, %s, %s)",
+ "(create_date, module, model, field, mode, type) "
+ "VALUES (NOW() AT TIME ZONE 'UTC', %s, %s, %s, %s, %s)",
(module, model, field, mode, "field"),
)
cr.execute(
@@ -67,7 +67,8 @@ def compare_registries(cr, module, registry, local_registry):
if not cr.fetchone():
cr.execute(
"INSERT INTO upgrade_attribute "
- "(name, value, record_id) VALUES (%s, %s, %s)",
+ "(create_date, name, value, record_id) "
+ "VALUES (NOW() AT TIME ZONE 'UTC', %s, %s, %s)",
(key, value, record_id),
)
old_field[key] = value
@@ -212,6 +213,7 @@ def log_xml_id(cr, module, xml_id):
if not cr.fetchone():
cr.execute(
"INSERT INTO upgrade_record "
- "(module, model, name, type) values(%s, %s, %s, %s)",
+ "(create_date, module, model, name, type) "
+ "values(NOW() AT TIME ZONE 'UTC', %s, %s, %s, %s)",
(module, record[0], xml_id, "xmlid"),
)
diff --git a/upgrade_analysis/wizards/upgrade_generate_record_wizard.py b/upgrade_analysis/wizards/upgrade_generate_record_wizard.py
index 84dd36622..ace540646 100644
--- a/upgrade_analysis/wizards/upgrade_generate_record_wizard.py
+++ b/upgrade_analysis/wizards/upgrade_generate_record_wizard.py
@@ -88,8 +88,9 @@ class GenerateWizard(models.TransientModel):
# Log model records
self.env.cr.execute(
"""INSERT INTO upgrade_record
- (module, name, model, type)
- SELECT imd2.module, imd2.module || '.' || imd.name AS name,
+ (create_date, module, name, model, type)
+ SELECT NOW() AT TIME ZONE 'UTC',
+ imd2.module, imd2.module || '.' || imd.name AS name,
im.model, 'model' AS type
FROM (
SELECT min(id) as id, name, res_id
From 3b172ff276f094a2e598f304f754ca2c01014159 Mon Sep 17 00:00:00 2001
From: Stefan Rijnhart
Date: Mon, 7 Dec 2020 10:59:40 +0100
Subject: [PATCH 09/67] [FIX] ImportError;
---
upgrade_analysis/models/upgrade_analysis.py | 18 ++++++++++++------
.../models/upgrade_comparison_config.py | 10 +++++++++-
upgrade_analysis/odoo_patch/addons/__init__.py | 1 -
3 files changed, 21 insertions(+), 8 deletions(-)
diff --git a/upgrade_analysis/models/upgrade_analysis.py b/upgrade_analysis/models/upgrade_analysis.py
index 39320ba0f..8f490e727 100644
--- a/upgrade_analysis/models/upgrade_analysis.py
+++ b/upgrade_analysis/models/upgrade_analysis.py
@@ -7,8 +7,10 @@ import logging
import os
from odoo import fields, models
+from odoo.exceptions import UserError
from odoo.modules import get_module_path
from odoo.tools import config
+from odoo.tools.translate import _
from .. import compare
@@ -35,7 +37,11 @@ class UpgradeAnalysis(models.Model):
log = fields.Text(readonly=True)
upgrade_path = fields.Char(
default=config.get("upgrade_path", False),
- help="The base file path to save the analyse files of Odoo modules",
+ help=(
+ "The base file path to save the analyse files of Odoo modules. "
+ "Default is taken from Odoo's --upgrade-path command line option. "
+ ),
+ required=True,
)
write_files = fields.Boolean(
@@ -56,11 +62,6 @@ class UpgradeAnalysis(models.Model):
):
module = self.env["ir.module.module"].search([("name", "=", module_name)])[0]
if module.is_odoo_module:
- if not self.upgrade_path:
- return (
- "ERROR: no upgrade_path set when writing analysis of %s\n"
- % module_name
- )
module_path = os.path.join(self.upgrade_path, module_name)
full_path = os.path.join(module_path, version)
else:
@@ -98,6 +99,11 @@ class UpgradeAnalysis(models.Model):
}
)
+ if not self.upgrade_path:
+ return (
+ "ERROR: no upgrade_path set when writing analysis of %s\n" % module_name
+ )
+
connection = self.config_id.get_connection()
RemoteRecord = self._get_remote_model(connection, "record")
LocalRecord = self.env["upgrade.record"]
diff --git a/upgrade_analysis/models/upgrade_comparison_config.py b/upgrade_analysis/models/upgrade_comparison_config.py
index 6bce297ce..90553ccf7 100644
--- a/upgrade_analysis/models/upgrade_comparison_config.py
+++ b/upgrade_analysis/models/upgrade_comparison_config.py
@@ -2,6 +2,8 @@
# Copyright 2016 Opener B.V.
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
+from urllib.error import URLError
+
import odoorpc
from odoo import api, fields, models
@@ -39,7 +41,13 @@ class UpgradeComparisonConfig(models.Model):
def get_connection(self):
self.ensure_one()
- remote = odoorpc.ODOO(self.server, port=self.port)
+ try:
+ remote = odoorpc.ODOO(self.server, port=self.port)
+ except URLError:
+ raise UserError(
+ _("Could not connect the Odoo server at %s:%s")
+ % (self.server, self.port)
+ )
remote.login(self.database, self.username, self.password)
self.version = remote.version
return remote
diff --git a/upgrade_analysis/odoo_patch/addons/__init__.py b/upgrade_analysis/odoo_patch/addons/__init__.py
index 3247dc7b6..5710e7497 100644
--- a/upgrade_analysis/odoo_patch/addons/__init__.py
+++ b/upgrade_analysis/odoo_patch/addons/__init__.py
@@ -1,3 +1,2 @@
from . import mrp
-from . import point_of_sale
from . import stock
From 74159600bc055e44d27e2a5bcfe0932bc6cd5151 Mon Sep 17 00:00:00 2001
From: Sylvain LE GAL
Date: Mon, 7 Dec 2020 12:15:01 +0100
Subject: [PATCH 10/67] [IMP] various improvment from Yajo.
---
upgrade_analysis/models/ir_module_module.py | 10 ++--------
upgrade_analysis/models/upgrade_attribute.py | 1 +
upgrade_analysis/models/upgrade_comparison_config.py | 6 +++---
upgrade_analysis/tests/test_module.py | 4 ++--
4 files changed, 8 insertions(+), 13 deletions(-)
diff --git a/upgrade_analysis/models/ir_module_module.py b/upgrade_analysis/models/ir_module_module.py
index 9456af708..a9a569517 100644
--- a/upgrade_analysis/models/ir_module_module.py
+++ b/upgrade_analysis/models/ir_module_module.py
@@ -19,17 +19,11 @@ class UpgradeAttribute(models.Model):
def _compute_is_oca_module(self):
for module in self:
- if "/OCA/" in module.website:
- module.is_oca_module = True
- else:
- module.is_oca_module = False
+ module.is_oca_module = "/OCA/" in module.website
def _compute_is_odoo_module(self):
for module in self:
module_path = get_module_path(module.name)
absolute_repo_path = os.path.split(module_path)[0]
x, relative_repo_path = os.path.split(absolute_repo_path)
- if relative_repo_path == "addons":
- module.is_odoo_module = True
- else:
- module.is_odoo_module = False
+ module.is_odoo_module = relative_repo_path == "addons"
diff --git a/upgrade_analysis/models/upgrade_attribute.py b/upgrade_analysis/models/upgrade_attribute.py
index ce6ef46e3..15c934466 100644
--- a/upgrade_analysis/models/upgrade_attribute.py
+++ b/upgrade_analysis/models/upgrade_attribute.py
@@ -15,6 +15,7 @@ class UpgradeAttribute(models.Model):
record_id = fields.Many2one(
comodel_name="upgrade.record",
+ index=True,
ondelete="CASCADE",
readonly=True,
)
diff --git a/upgrade_analysis/models/upgrade_comparison_config.py b/upgrade_analysis/models/upgrade_comparison_config.py
index 90553ccf7..95317bf7e 100644
--- a/upgrade_analysis/models/upgrade_comparison_config.py
+++ b/upgrade_analysis/models/upgrade_comparison_config.py
@@ -67,9 +67,9 @@ class UpgradeComparisonConfig(models.Model):
"params": {
"type": "info",
"message": _(
- "You are correctly connected to the server {server}"
- " (version {version}) with the user {user_name}"
- ).format(
+ "You are correctly connected to the server %(server)s"
+ " (version %(version)s) with the user %(user_name)s"
+ ) % dict(
server=self.server,
version=self.version,
user_name=user_info["name"],
diff --git a/upgrade_analysis/tests/test_module.py b/upgrade_analysis/tests/test_module.py
index 85a66d9b7..fbb54e505 100644
--- a/upgrade_analysis/tests/test_module.py
+++ b/upgrade_analysis/tests/test_module.py
@@ -29,8 +29,8 @@ class TestUpgradeAnalysis(common.TransactionCase):
)
wizard.select_other_modules()
- self.assertTrue(
- self.product_module.id not in wizard.module_ids.ids,
+ self.assertFalse(
+ self.product_module.id in wizard.module_ids.ids,
"Select Other module should not select 'product' module",
)
From 389a348a94181294d47753d4db92b40c2aaeaf23 Mon Sep 17 00:00:00 2001
From: Sylvain LE GAL
Date: Mon, 7 Dec 2020 12:42:45 +0100
Subject: [PATCH 11/67] [IMP] import apriori file of openupgrade_scripts, if
available [IMP] guess upgrade_path, if config is not set, and
openupgrade_scripts is available
---
upgrade_analysis/apriori.py | 22 +++++++++++++++++--
upgrade_analysis/models/upgrade_analysis.py | 20 ++++++++++++++++-
.../models/upgrade_comparison_config.py | 3 ++-
.../odoo_patch/addons/__init__.py | 1 +
.../addons/point_of_sale/__init__.py | 12 ++++++++++
upgrade_analysis/readme/USAGE.rst | 0
6 files changed, 54 insertions(+), 4 deletions(-)
create mode 100644 upgrade_analysis/odoo_patch/addons/point_of_sale/__init__.py
delete mode 100644 upgrade_analysis/readme/USAGE.rst
diff --git a/upgrade_analysis/apriori.py b/upgrade_analysis/apriori.py
index 2e5883191..4c06538e2 100644
--- a/upgrade_analysis/apriori.py
+++ b/upgrade_analysis/apriori.py
@@ -2,9 +2,27 @@
to help the matching process
"""
-renamed_modules = {}
+import logging
-merged_modules = {}
+_logger = logging.getLogger(__name__)
+
+
+try:
+ from odoo.addons.openupgrade_scripts.apriori import merged_modules, renamed_modules
+except ImportError:
+ renamed_modules = {}
+ merged_modules = {}
+ _logger.warning(
+ "You are using upgrade_analysis without having"
+ " openupgrade_scripts module available."
+ " The analysis process will not work properly,"
+ " if you are generating analysis for the odoo modules"
+ " in an openupgrade context."
+ )
+
+renamed_modules.update({})
+
+merged_modules.update({})
# only used here for upgrade_analysis
renamed_models = {}
diff --git a/upgrade_analysis/models/upgrade_analysis.py b/upgrade_analysis/models/upgrade_analysis.py
index 8f490e727..b0463e9f2 100644
--- a/upgrade_analysis/models/upgrade_analysis.py
+++ b/upgrade_analysis/models/upgrade_analysis.py
@@ -5,6 +5,7 @@
import logging
import os
+from pathlib import Path
from odoo import fields, models
from odoo.exceptions import UserError
@@ -17,6 +18,11 @@ from .. import compare
_logger = logging.getLogger(__name__)
_IGNORE_MODULES = ["openupgrade_records", "upgrade_analysis"]
+try:
+ from odoo.addons.openupgrade_scripts import apriori
+except ImportError:
+ apriori = False
+
class UpgradeAnalysis(models.Model):
_name = "upgrade.analysis"
@@ -36,7 +42,7 @@ class UpgradeAnalysis(models.Model):
log = fields.Text(readonly=True)
upgrade_path = fields.Char(
- default=config.get("upgrade_path", False),
+ default=lambda x: x._default_upgrade_path(),
help=(
"The base file path to save the analyse files of Odoo modules. "
"Default is taken from Odoo's --upgrade-path command line option. "
@@ -48,6 +54,17 @@ class UpgradeAnalysis(models.Model):
help="Write analysis files to the module directories", default=True
)
+ def _default_upgrade_path(self):
+ # Return upgrade_path value, if exists
+ config_value = config.get("upgrade_path", False)
+ if config_value:
+ return config_value
+ # Otherwise, try to guess, with the openupgrade_scripts path
+ elif apriori:
+ apriori_path = Path(os.path.abspath(apriori.__file__))
+ return os.path.join(apriori_path.parent, "scripts")
+ return False
+
def _get_remote_model(self, connection, model):
self.ensure_one()
if model == "record":
@@ -232,3 +249,4 @@ class UpgradeAnalysis(models.Model):
"log": general_log,
}
)
+ return True
diff --git a/upgrade_analysis/models/upgrade_comparison_config.py b/upgrade_analysis/models/upgrade_comparison_config.py
index 95317bf7e..35fcd5005 100644
--- a/upgrade_analysis/models/upgrade_comparison_config.py
+++ b/upgrade_analysis/models/upgrade_comparison_config.py
@@ -69,7 +69,8 @@ class UpgradeComparisonConfig(models.Model):
"message": _(
"You are correctly connected to the server %(server)s"
" (version %(version)s) with the user %(user_name)s"
- ) % dict(
+ )
+ % dict(
server=self.server,
version=self.version,
user_name=user_info["name"],
diff --git a/upgrade_analysis/odoo_patch/addons/__init__.py b/upgrade_analysis/odoo_patch/addons/__init__.py
index 5710e7497..3247dc7b6 100644
--- a/upgrade_analysis/odoo_patch/addons/__init__.py
+++ b/upgrade_analysis/odoo_patch/addons/__init__.py
@@ -1,2 +1,3 @@
from . import mrp
+from . import point_of_sale
from . import stock
diff --git a/upgrade_analysis/odoo_patch/addons/point_of_sale/__init__.py b/upgrade_analysis/odoo_patch/addons/point_of_sale/__init__.py
new file mode 100644
index 000000000..a67563f42
--- /dev/null
+++ b/upgrade_analysis/odoo_patch/addons/point_of_sale/__init__.py
@@ -0,0 +1,12 @@
+from odoo import api
+from odoo.addons.point_of_sale.models import pos_config
+from ...odoo_patch import OdooPatch
+
+
+class PreInitHookPatch(OdooPatch):
+ target = pos_config.PosConfig
+ method_names = ['post_install_pos_localisation']
+
+ @api.model
+ def post_install_pos_localisation(cr):
+ """ Do not configure twice pos_localisation"""
diff --git a/upgrade_analysis/readme/USAGE.rst b/upgrade_analysis/readme/USAGE.rst
deleted file mode 100644
index e69de29bb..000000000
From a1c6c0bb07235e36599f937919531601a59f7a74 Mon Sep 17 00:00:00 2001
From: Stefan Rijnhart
Date: Tue, 8 Dec 2020 11:26:15 +0100
Subject: [PATCH 12/67] [RFR] upgrade_path not user writable
---
upgrade_analysis/__init__.py | 1 -
upgrade_analysis/apriori.py | 31 ---------
upgrade_analysis/compare.py | 14 +++-
upgrade_analysis/models/ir_module_module.py | 3 +
upgrade_analysis/models/upgrade_analysis.py | 65 ++++++++++---------
.../views/view_upgrade_analysis.xml | 2 +-
6 files changed, 51 insertions(+), 65 deletions(-)
delete mode 100644 upgrade_analysis/apriori.py
diff --git a/upgrade_analysis/__init__.py b/upgrade_analysis/__init__.py
index ca02278df..172ae9a25 100644
--- a/upgrade_analysis/__init__.py
+++ b/upgrade_analysis/__init__.py
@@ -2,6 +2,5 @@ from . import odoo_patch
from . import models
from . import wizards
from . import blacklist
-from . import apriori
from . import compare
from . import upgrade_log
diff --git a/upgrade_analysis/apriori.py b/upgrade_analysis/apriori.py
deleted file mode 100644
index 4c06538e2..000000000
--- a/upgrade_analysis/apriori.py
+++ /dev/null
@@ -1,31 +0,0 @@
-""" Encode any known changes to the database here
-to help the matching process
-"""
-
-import logging
-
-_logger = logging.getLogger(__name__)
-
-
-try:
- from odoo.addons.openupgrade_scripts.apriori import merged_modules, renamed_modules
-except ImportError:
- renamed_modules = {}
- merged_modules = {}
- _logger.warning(
- "You are using upgrade_analysis without having"
- " openupgrade_scripts module available."
- " The analysis process will not work properly,"
- " if you are generating analysis for the odoo modules"
- " in an openupgrade context."
- )
-
-renamed_modules.update({})
-
-merged_modules.update({})
-
-# only used here for upgrade_analysis
-renamed_models = {}
-
-# only used here for upgrade_analysis
-merged_models = {}
diff --git a/upgrade_analysis/compare.py b/upgrade_analysis/compare.py
index 6af14263d..bc817d9e0 100644
--- a/upgrade_analysis/compare.py
+++ b/upgrade_analysis/compare.py
@@ -11,7 +11,19 @@
import collections
import copy
-from . import apriori
+try:
+ from odoo.addons.openupgrade_scripts import apriori
+except ImportError:
+ from dataclasses import dataclass, field
+
+ @dataclass
+ class NullApriori:
+ renamed_modules: dict = field(default_factory=dict)
+ merged_modules: dict = field(default_factory=dict)
+ renamed_models: dict = field(default_factory=dict)
+ merged_models: dict = field(default_factory=dict)
+
+ apriori = NullApriori()
def module_map(module):
diff --git a/upgrade_analysis/models/ir_module_module.py b/upgrade_analysis/models/ir_module_module.py
index a9a569517..bff4265b3 100644
--- a/upgrade_analysis/models/ir_module_module.py
+++ b/upgrade_analysis/models/ir_module_module.py
@@ -24,6 +24,9 @@ class UpgradeAttribute(models.Model):
def _compute_is_odoo_module(self):
for module in self:
module_path = get_module_path(module.name)
+ if not module_path:
+ module.is_odoo_module = False
+ continue
absolute_repo_path = os.path.split(module_path)[0]
x, relative_repo_path = os.path.split(absolute_repo_path)
module.is_odoo_module = relative_repo_path == "addons"
diff --git a/upgrade_analysis/models/upgrade_analysis.py b/upgrade_analysis/models/upgrade_analysis.py
index b0463e9f2..f42ffdff1 100644
--- a/upgrade_analysis/models/upgrade_analysis.py
+++ b/upgrade_analysis/models/upgrade_analysis.py
@@ -5,7 +5,6 @@
import logging
import os
-from pathlib import Path
from odoo import fields, models
from odoo.exceptions import UserError
@@ -18,11 +17,6 @@ from .. import compare
_logger = logging.getLogger(__name__)
_IGNORE_MODULES = ["openupgrade_records", "upgrade_analysis"]
-try:
- from odoo.addons.openupgrade_scripts import apriori
-except ImportError:
- apriori = False
-
class UpgradeAnalysis(models.Model):
_name = "upgrade.analysis"
@@ -42,28 +36,28 @@ class UpgradeAnalysis(models.Model):
log = fields.Text(readonly=True)
upgrade_path = fields.Char(
- default=lambda x: x._default_upgrade_path(),
+ compute="_compute_upgrade_path",
+ readonly=True,
help=(
"The base file path to save the analyse files of Odoo modules. "
- "Default is taken from Odoo's --upgrade-path command line option. "
+ "Taken from Odoo's --upgrade-path command line option or the "
+ "'scripts' subdirectory in the openupgrade_scripts addon."
),
- required=True,
)
-
write_files = fields.Boolean(
help="Write analysis files to the module directories", default=True
)
- def _default_upgrade_path(self):
- # Return upgrade_path value, if exists
- config_value = config.get("upgrade_path", False)
- if config_value:
- return config_value
- # Otherwise, try to guess, with the openupgrade_scripts path
- elif apriori:
- apriori_path = Path(os.path.abspath(apriori.__file__))
- return os.path.join(apriori_path.parent, "scripts")
- return False
+ def _compute_upgrade_path(self):
+ """Return the --upgrade-path configuration option or the `scripts`
+ directory in `openupgrade_scripts` if available
+ """
+ res = config.get("upgrade_path", False)
+ if not res:
+ module_path = get_module_path("openupgrade_scripts", display_warning=False)
+ if module_path:
+ res = os.path.join(module_path, "scripts")
+ self.upgrade_path = res
def _get_remote_model(self, connection, model):
self.ensure_one()
@@ -79,13 +73,16 @@ class UpgradeAnalysis(models.Model):
):
module = self.env["ir.module.module"].search([("name", "=", module_name)])[0]
if module.is_odoo_module:
- module_path = os.path.join(self.upgrade_path, module_name)
- full_path = os.path.join(module_path, version)
+ if not self.upgrade_path:
+ return (
+ "ERROR: no upgrade_path set when writing analysis of %s\n"
+ % module_name
+ )
+ full_path = os.path.join(self.upgrade_path, module_name, version)
else:
- module_path = get_module_path(module_name)
- full_path = os.path.join(module_path, "migrations", version)
- if not module_path:
- return "ERROR: could not find module path of '%s':\n" % (module_name)
+ full_path = os.path.join(
+ get_module_path(module_name, "migrations", version)
+ )
if not os.path.exists(full_path):
try:
os.makedirs(full_path)
@@ -116,11 +113,6 @@ class UpgradeAnalysis(models.Model):
}
)
- if not self.upgrade_path:
- return (
- "ERROR: no upgrade_path set when writing analysis of %s\n" % module_name
- )
-
connection = self.config_id.get_connection()
RemoteRecord = self._get_remote_model(connection, "record")
LocalRecord = self.env["upgrade.record"]
@@ -183,6 +175,17 @@ class UpgradeAnalysis(models.Model):
+ local_model_records
}
)
+ if "base" in affected_modules:
+ try:
+ from odoo.addons.openupgrade_scripts import apriori
+ except ImportError:
+ _logger.error(
+ "You are using upgrade_analysis on core modules without "
+ " having openupgrade_scripts module available."
+ " The analysis process will not work properly,"
+ " if you are generating analysis for the odoo modules"
+ " in an openupgrade context."
+ )
# reorder and output the result
keys = ["general"] + affected_modules
diff --git a/upgrade_analysis/views/view_upgrade_analysis.xml b/upgrade_analysis/views/view_upgrade_analysis.xml
index c2ce39170..c664fa70d 100644
--- a/upgrade_analysis/views/view_upgrade_analysis.xml
+++ b/upgrade_analysis/views/view_upgrade_analysis.xml
@@ -38,7 +38,7 @@
/>
Date: Fri, 11 Dec 2020 21:07:18 +0100
Subject: [PATCH 13/67] [ADD] Generate noupdate_changes
---
upgrade_analysis/models/upgrade_analysis.py | 234 +++++++++++++++++++-
upgrade_analysis/models/upgrade_record.py | 48 +++-
2 files changed, 279 insertions(+), 3 deletions(-)
diff --git a/upgrade_analysis/models/upgrade_analysis.py b/upgrade_analysis/models/upgrade_analysis.py
index f42ffdff1..e9eca7b59 100644
--- a/upgrade_analysis/models/upgrade_analysis.py
+++ b/upgrade_analysis/models/upgrade_analysis.py
@@ -1,17 +1,28 @@
# Copyright 2011-2015 Therp BV
-# Copyright 2016 Opener B.V.
+# Copyright 2016-2020 Opener B.V.
+# Copyright 2019 Eficent
+# Copyright 2020 GRAP
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
# flake8: noqa: C901
import logging
import os
+from copy import deepcopy
+
+from lxml import etree
from odoo import fields, models
-from odoo.exceptions import UserError
+from odoo.exceptions import UserError, ValidationError
from odoo.modules import get_module_path
from odoo.tools import config
+from odoo.tools.convert import nodeattr2bool
from odoo.tools.translate import _
+try:
+ from odoo.addons.openupgrade_scripts.apriori import renamed_modules
+except ImportError:
+ renamed_modules = {}
+
from .. import compare
_logger = logging.getLogger(__name__)
@@ -246,6 +257,13 @@ class UpgradeAnalysis(models.Model):
general_log,
"upgrade_general_log.txt",
)
+
+ try:
+ self.generate_noupdate_changes()
+ except Exception as e:
+ _logger.exception("Error generating noupdate changes: %s" % e)
+ general_log += "ERROR: error when generating noupdate changes: %s\n" % e
+
self.write(
{
"state": "done",
@@ -253,3 +271,215 @@ class UpgradeAnalysis(models.Model):
}
)
return True
+
+ @staticmethod
+ def _get_node_dict(element):
+ res = {}
+ if element is None:
+ return res
+ for child in element:
+ if "name" in child.attrib:
+ key = "./{}[@name='{}']".format(child.tag, child.attrib["name"])
+ res[key] = child
+ return res
+
+ @staticmethod
+ def _get_node_value(element):
+ if "eval" in element.attrib.keys():
+ return element.attrib["eval"]
+ if "ref" in element.attrib.keys():
+ return element.attrib["ref"]
+ if not len(element):
+ return element.text
+ return etree.tostring(element)
+
+ def _get_xml_diff(
+ self, remote_update, remote_noupdate, local_update, local_noupdate
+ ):
+ odoo = etree.Element("odoo")
+ for xml_id in sorted(local_noupdate.keys()):
+ local_record = local_noupdate[xml_id]
+ remote_record = None
+ if xml_id in remote_update and xml_id not in remote_noupdate:
+ remote_record = remote_update[xml_id]
+ elif xml_id in remote_noupdate:
+ remote_record = remote_noupdate[xml_id]
+
+ if "." in xml_id:
+ module_xmlid = xml_id.split(".", 1)[0]
+ else:
+ module_xmlid = ""
+
+ if remote_record is None and not module_xmlid:
+ continue
+
+ element = etree.Element(
+ "record", id=xml_id, model=local_record.attrib["model"]
+ )
+ # Add forcecreate attribute if exists
+ if local_record.attrib.get("forcecreate"):
+ element.attrib["forcecreate"] = local_record.attrib["forcecreate"]
+ record_remote_dict = self._get_node_dict(remote_record)
+ record_local_dict = self._get_node_dict(local_record)
+ for key in sorted(record_remote_dict.keys()):
+ if not local_record.xpath(key):
+ # The element is no longer present.
+ # Does the field still exist?
+ if record_remote_dict[key].tag == "field":
+ field_name = remote_record.xpath(key)[0].attrib.get("name")
+ if (
+ field_name
+ not in self.env[local_record.attrib["model"]]._fields.keys()
+ ):
+ continue
+ # Overwrite an existing value with an empty one.
+ attribs = deepcopy(record_remote_dict[key]).attrib
+ for attr in ["eval", "ref"]:
+ if attr in attribs:
+ del attribs[attr]
+ element.append(etree.Element(record_remote_dict[key].tag, attribs))
+ else:
+ oldrepr = self._get_node_value(record_remote_dict[key])
+ newrepr = self._get_node_value(record_local_dict[key])
+
+ if oldrepr != newrepr:
+ element.append(deepcopy(record_local_dict[key]))
+
+ for key in sorted(record_local_dict.keys()):
+ if remote_record is None or not remote_record.xpath(key):
+ element.append(deepcopy(record_local_dict[key]))
+
+ if len(element):
+ odoo.append(element)
+
+ if not len(odoo):
+ return ""
+ return etree.tostring(
+ etree.ElementTree(odoo),
+ pretty_print=True,
+ xml_declaration=True,
+ encoding="utf-8",
+ ).decode("utf-8")
+
+ @staticmethod
+ def _update_node(target, source):
+ for element in source:
+ if "name" in element.attrib:
+ query = "./{}[@name='{}']".format(element.tag, element.attrib["name"])
+ else:
+ # query = "./%s" % element.tag
+ continue
+ for existing in target.xpath(query):
+ target.remove(existing)
+ target.append(element)
+
+ @classmethod
+ def _process_data_node(
+ self, data_node, records_update, records_noupdate, module_name
+ ):
+ noupdate = nodeattr2bool(data_node, "noupdate", False)
+ for record in data_node.xpath("./record"):
+ self._process_record_node(
+ record, noupdate, records_update, records_noupdate, module_name
+ )
+
+ @classmethod
+ def _process_record_node(
+ self, record, noupdate, records_update, records_noupdate, module_name
+ ):
+ xml_id = record.get("id")
+ if not xml_id:
+ return
+ if "." in xml_id and xml_id.startswith(module_name + "."):
+ xml_id = xml_id[len(module_name) + 1 :]
+ for records in records_noupdate, records_update:
+ # records can occur multiple times in the same module
+ # with different noupdate settings
+ if xml_id in records:
+ # merge records (overwriting an existing element
+ # with the same tag). The order processing the
+ # various directives from the manifest is
+ # important here
+ self._update_node(records[xml_id], record)
+ break
+ else:
+ target_dict = records_noupdate if noupdate else records_update
+ target_dict[xml_id] = record
+
+ @classmethod
+ def _parse_files(self, xml_files, module_name):
+ records_update = {}
+ records_noupdate = {}
+ parser = etree.XMLParser(
+ remove_blank_text=True,
+ strip_cdata=False,
+ )
+ for xml_file in xml_files:
+ try:
+ # This is for a final correct pretty print
+ # Ref.: https://stackoverflow.com/a/7904066
+ # Also don't strip CDATA tags as needed for HTML content
+ root_node = etree.fromstring(xml_file.encode("utf-8"), parser=parser)
+ except etree.XMLSyntaxError:
+ continue
+ # Support xml files with root Element either odoo or openerp
+ # Condition: each xml file should have only one root element
+ # {, or —rarely— };
+ root_node_noupdate = nodeattr2bool(root_node, "noupdate", False)
+ if root_node.tag not in ("openerp", "odoo", "data"):
+ raise ValidationError(
+ _(
+ "Unexpected root Element: %s in file: %s"
+ % (tree.getroot(), xml_file)
+ )
+ )
+ for node in root_node:
+ if node.tag == "data":
+ self._process_data_node(
+ node, records_update, records_noupdate, module_name
+ )
+ elif node.tag == "record":
+ self._process_record_node(
+ node,
+ root_node_noupdate,
+ records_update,
+ records_noupdate,
+ module_name,
+ )
+
+ return records_update, records_noupdate
+
+ def generate_noupdate_changes(self):
+ """Communicate with the remote server to fetch all xml data records
+ per module, and generate a diff in XML format that can be imported
+ from the module's migration script using openupgrade.load_data()
+ """
+ self.ensure_one()
+ connection = self.config_id.get_connection()
+ remote_record_obj = self._get_remote_model(connection, "record")
+ local_record_obj = self.env["upgrade.record"]
+ local_modules = local_record_obj.list_modules()
+ for remote_module in remote_record_obj.list_modules():
+ local_module = renamed_modules.get(remote_module, remote_module)
+ if local_module not in local_modules:
+ continue
+ remote_files = remote_record_obj.get_xml_records(remote_module)
+ local_files = local_record_obj.get_xml_records(local_module)
+ remote_update, remote_noupdate = self._parse_files(
+ remote_files, remote_module
+ )
+ local_update, local_noupdate = self._parse_files(local_files, local_module)
+ diff = self._get_xml_diff(
+ remote_update, remote_noupdate, local_update, local_noupdate
+ )
+ if diff:
+ module = self.env["ir.module.module"].search(
+ [("name", "=", local_module)]
+ )
+ self._write_file(
+ local_module,
+ module.installed_version,
+ diff,
+ filename="noupdate_changes.xml",
+ )
+ return True
diff --git a/upgrade_analysis/models/upgrade_record.py b/upgrade_analysis/models/upgrade_record.py
index 89426c308..6aa07cab6 100644
--- a/upgrade_analysis/models/upgrade_record.py
+++ b/upgrade_analysis/models/upgrade_record.py
@@ -1,8 +1,16 @@
# Copyright 2011-2015 Therp BV
-# Copyright 2016 Opener B.V.
+# Copyright 2016-2020 Opener B.V.
+# Copyright 2019 Eficent
+# Copyright 2020 GRAP
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
+import ast
+import os
+
from odoo import api, fields, models
+from odoo.exceptions import ValidationError
+from odoo.modules.module import MANIFEST_NAMES, get_module_path
+from odoo.tools.translate import _
class UpgradeRecord(models.Model):
@@ -112,3 +120,41 @@ class UpgradeRecord(models.Model):
repre.update({x.name: x.value for x in record.attribute_ids})
data.append(repre)
return data
+
+ @api.model
+ def list_modules(self):
+ """ Return the set of covered modules """
+ self.env.cr.execute(
+ """SELECT DISTINCT(module) FROM upgrade_record
+ ORDER BY module"""
+ )
+ return [module for module, in self.env.cr.fetchall()]
+
+ @staticmethod
+ def _read_manifest(addon_dir):
+ for manifest_name in MANIFEST_NAMES:
+ if os.access(os.path.join(addon_dir, manifest_name), os.R_OK):
+ with open(os.path.join(addon_dir, manifest_name), "r") as f:
+ manifest_string = f.read()
+ return ast.literal_eval(manifest_string)
+ raise ValidationError(_("No manifest found in %s" % addon_dir))
+
+ @api.model
+ def get_xml_records(self, module):
+ """ Return all XML records from the given module """
+ addon_dir = get_module_path(module)
+ manifest = self._read_manifest(addon_dir)
+ # The order of the keys are important.
+ # Load files in the same order as in
+ # module/loading.py:load_module_graph
+ files = []
+ for key in ["init_xml", "update_xml", "data"]:
+ if not manifest.get(key):
+ continue
+ for xml_file in manifest[key]:
+ if not xml_file.lower().endswith(".xml"):
+ continue
+ parts = xml_file.split("/")
+ with open(os.path.join(addon_dir, *parts), "r") as xml_handle:
+ files.append(xml_handle.read())
+ return files
From 2eb1d09b26347a6efac351a0704238f7eb5ce990 Mon Sep 17 00:00:00 2001
From: Stefan Rijnhart
Date: Fri, 11 Dec 2020 21:11:44 +0100
Subject: [PATCH 14/67] [FIX] dataclasses for Python < 3.7
---
upgrade_analysis/__manifest__.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/upgrade_analysis/__manifest__.py b/upgrade_analysis/__manifest__.py
index a7d9de82b..44c755efb 100644
--- a/upgrade_analysis/__manifest__.py
+++ b/upgrade_analysis/__manifest__.py
@@ -20,7 +20,7 @@
],
"installable": True,
"external_dependencies": {
- "python": ["odoorpc", "openupgradelib"],
+ "python": ["dataclasses", "odoorpc", "openupgradelib"],
},
"license": "AGPL-3",
}
From 62c7c11c926b570585be081162f0fe5fcc7685b2 Mon Sep 17 00:00:00 2001
From: Sylvain LE GAL
Date: Wed, 20 Jan 2021 12:22:38 +0100
Subject: [PATCH 15/67] Update upgrade_analysis/models/ir_module_module.py
Co-authored-by: David Beal
---
upgrade_analysis/models/ir_module_module.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/upgrade_analysis/models/ir_module_module.py b/upgrade_analysis/models/ir_module_module.py
index bff4265b3..38edbbac8 100644
--- a/upgrade_analysis/models/ir_module_module.py
+++ b/upgrade_analysis/models/ir_module_module.py
@@ -8,7 +8,7 @@ from odoo import fields, models
from odoo.modules import get_module_path
-class UpgradeAttribute(models.Model):
+class IrModuleModule(models.Model):
_inherit = "ir.module.module"
is_odoo_module = fields.Boolean(
From 8cf7f08649b3977e15bd58e56be4e06a6d38b1a9 Mon Sep 17 00:00:00 2001
From: Sylvain LE GAL
Date: Wed, 24 Feb 2021 09:13:12 +0100
Subject: [PATCH 16/67] [REM] remove obsolete roadmap point
---
upgrade_analysis/readme/ROADMAP.rst | 1 -
1 file changed, 1 deletion(-)
diff --git a/upgrade_analysis/readme/ROADMAP.rst b/upgrade_analysis/readme/ROADMAP.rst
index 734c22444..79e8c5939 100644
--- a/upgrade_analysis/readme/ROADMAP.rst
+++ b/upgrade_analysis/readme/ROADMAP.rst
@@ -1,3 +1,2 @@
-* scripts/compare_noupdate_xml_records.py should be integrated in the analysis process (#590)
* Log removed modules in the module that owned them (#468)
* Detect renamed many2many tables (#213)
From cc83a275a3c69598813c89ed215f80a2add7da76 Mon Sep 17 00:00:00 2001
From: Sylvain LE GAL
Date: Wed, 24 Feb 2021 09:20:42 +0100
Subject: [PATCH 17/67] [IMP] remove pre-commit exception and fix various style
in odoo_patch folder
---
.../odoo_patch/addons/mrp/__init__.py | 3 ++-
.../addons/point_of_sale/__init__.py | 3 ++-
.../odoo_patch/addons/stock/__init__.py | 3 ++-
upgrade_analysis/odoo_patch/odoo/models.py | 12 ++++++-----
.../odoo_patch/odoo/modules/registry.py | 20 +++++++++++--------
.../odoo_patch/odoo/tools/convert.py | 7 ++++---
upgrade_analysis/odoo_patch/odoo_patch.py | 14 +++++++------
7 files changed, 37 insertions(+), 25 deletions(-)
diff --git a/upgrade_analysis/odoo_patch/addons/mrp/__init__.py b/upgrade_analysis/odoo_patch/addons/mrp/__init__.py
index 94f30010f..09caee64c 100644
--- a/upgrade_analysis/odoo_patch/addons/mrp/__init__.py
+++ b/upgrade_analysis/odoo_patch/addons/mrp/__init__.py
@@ -1,10 +1,11 @@
+# flake8: noqa: B902
from odoo.addons import mrp
from ...odoo_patch import OdooPatch
class PreInitHookPatch(OdooPatch):
target = mrp
- method_names = ['_pre_init_mrp']
+ method_names = ["_pre_init_mrp"]
def _pre_init_mrp(cr):
""" Don't try to create an existing column on reinstall """
diff --git a/upgrade_analysis/odoo_patch/addons/point_of_sale/__init__.py b/upgrade_analysis/odoo_patch/addons/point_of_sale/__init__.py
index a67563f42..66f003c17 100644
--- a/upgrade_analysis/odoo_patch/addons/point_of_sale/__init__.py
+++ b/upgrade_analysis/odoo_patch/addons/point_of_sale/__init__.py
@@ -1,3 +1,4 @@
+# flake8: noqa: B902
from odoo import api
from odoo.addons.point_of_sale.models import pos_config
from ...odoo_patch import OdooPatch
@@ -5,7 +6,7 @@ from ...odoo_patch import OdooPatch
class PreInitHookPatch(OdooPatch):
target = pos_config.PosConfig
- method_names = ['post_install_pos_localisation']
+ method_names = ["post_install_pos_localisation"]
@api.model
def post_install_pos_localisation(cr):
diff --git a/upgrade_analysis/odoo_patch/addons/stock/__init__.py b/upgrade_analysis/odoo_patch/addons/stock/__init__.py
index a28a083ce..206795b42 100644
--- a/upgrade_analysis/odoo_patch/addons/stock/__init__.py
+++ b/upgrade_analysis/odoo_patch/addons/stock/__init__.py
@@ -1,10 +1,11 @@
+# flake8: noqa: B902
from odoo.addons import stock
from ...odoo_patch import OdooPatch
class PreInitHookPatch(OdooPatch):
target = stock
- method_names = ['pre_init_hook']
+ method_names = ["pre_init_hook"]
def pre_init_hook(cr):
""" Don't unlink stock data on reinstall """
diff --git a/upgrade_analysis/odoo_patch/odoo/models.py b/upgrade_analysis/odoo_patch/odoo/models.py
index 09c10c418..431fc9635 100644
--- a/upgrade_analysis/odoo_patch/odoo/models.py
+++ b/upgrade_analysis/odoo_patch/odoo/models.py
@@ -1,21 +1,23 @@
from odoo import api, models
-from ..odoo_patch import OdooPatch
+
from ... import upgrade_log
+from ..odoo_patch import OdooPatch
class BaseModelPatch(OdooPatch):
target = models.BaseModel
- method_names = ['_convert_records']
+ method_names = ["_convert_records"]
@api.model
def _convert_records(self, records, log=lambda a: None):
""" Log data ids that are imported with `load` """
- current_module = self.env.context['module']
+ current_module = self.env.context["module"]
for res in BaseModelPatch._convert_records._original_method(
- self, records, log=log):
+ self, records, log=log
+ ):
_id, xid, _record, _info = res
if xid:
- xid = xid if '.' in xid else "%s.%s" % (current_module, xid)
+ xid = xid if "." in xid else "{}.{}".format(current_module, xid)
upgrade_log.log_xml_id(self.env.cr, current_module, xid)
yield res
diff --git a/upgrade_analysis/odoo_patch/odoo/modules/registry.py b/upgrade_analysis/odoo_patch/odoo/modules/registry.py
index 3d0981a00..017da063f 100644
--- a/upgrade_analysis/odoo_patch/odoo/modules/registry.py
+++ b/upgrade_analysis/odoo_patch/odoo/modules/registry.py
@@ -1,20 +1,22 @@
import logging
from threading import current_thread
-from odoo import api, SUPERUSER_ID
-from ...odoo_patch import OdooPatch
-from .... import upgrade_log
+
+from odoo import SUPERUSER_ID, api
from odoo.modules.registry import Registry
+from .... import upgrade_log
+from ...odoo_patch import OdooPatch
+
_logger = logging.getLogger(__name__)
class RegistryPatch(OdooPatch):
target = Registry
- method_names = ['init_models']
+ method_names = ["init_models"]
def init_models(self, cr, model_names, context, install=True):
- module_name = context['module']
- _logger.debug('Logging models of module %s', module_name)
+ module_name = context["module"]
+ _logger.debug("Logging models of module %s", module_name)
upg_registry = current_thread()._upgrade_registry
local_registry = {}
env = api.Environment(cr, SUPERUSER_ID, {})
@@ -23,7 +25,9 @@ class RegistryPatch(OdooPatch):
continue
upgrade_log.log_model(model, local_registry)
upgrade_log.compare_registries(
- cr, context['module'], upg_registry, local_registry)
+ cr, context["module"], upg_registry, local_registry
+ )
return RegistryPatch.init_models._original_method(
- self, cr, model_names, context, install=install)
+ self, cr, model_names, context, install=install
+ )
diff --git a/upgrade_analysis/odoo_patch/odoo/tools/convert.py b/upgrade_analysis/odoo_patch/odoo/tools/convert.py
index 7130859d6..0912c6d26 100644
--- a/upgrade_analysis/odoo_patch/odoo/tools/convert.py
+++ b/upgrade_analysis/odoo_patch/odoo/tools/convert.py
@@ -1,11 +1,12 @@
-from ...odoo_patch import OdooPatch
-from .... import upgrade_log
from odoo.tools.convert import xml_import
+from .... import upgrade_log
+from ...odoo_patch import OdooPatch
+
class XMLImportPatch(OdooPatch):
target = xml_import
- method_names = ['_test_xml_id']
+ method_names = ["_test_xml_id"]
def _test_xml_id(self, xml_id):
res = XMLImportPatch._test_xml_id._original_method(self, xml_id)
diff --git a/upgrade_analysis/odoo_patch/odoo_patch.py b/upgrade_analysis/odoo_patch/odoo_patch.py
index ac9f02fee..c1956f51f 100644
--- a/upgrade_analysis/odoo_patch/odoo_patch.py
+++ b/upgrade_analysis/odoo_patch/odoo_patch.py
@@ -4,7 +4,7 @@ _logger = logging.getLogger(__name__)
class OdooPatch(object):
- """ Simple mechanism to apply a collection of monkeypatches using a
+ """Simple mechanism to apply a collection of monkeypatches using a
context manager.
Classes can register their monkeypatches by inheriting from this class.
@@ -39,21 +39,23 @@ class OdooPatch(object):
do_something()
```
"""
+
def __enter__(self):
for cls in OdooPatch.__subclasses__():
for method_name in cls.method_names:
method = getattr(cls, method_name)
- setattr(method, '_original_method',
- getattr(cls.target, method_name))
+ method._original_method = getattr(cls.target, method_name)
setattr(cls.target, method_name, method)
def __exit__(self, exc_type, exc_value, tb):
for cls in OdooPatch.__subclasses__():
for method_name in cls.method_names:
method = getattr(cls.target, method_name)
- if hasattr(method, '_original_method'):
+ if hasattr(method, "_original_method"):
setattr(cls.target, method_name, method._original_method)
else:
_logger.warn(
- '_original_method not found on method %s of class %s',
- method_name, cls.target)
+ "_original_method not found on method %s of class %s",
+ method_name,
+ cls.target,
+ )
From ee63a77c5fcc94d97031f9650ed925a61124ff3d Mon Sep 17 00:00:00 2001
From: oca-travis
Date: Fri, 26 Feb 2021 19:28:26 +0000
Subject: [PATCH 18/67] [UPD] Update upgrade_analysis.pot
---
upgrade_analysis/i18n/upgrade_analysis.pot | 521 +++++++++++++++++++++
1 file changed, 521 insertions(+)
create mode 100644 upgrade_analysis/i18n/upgrade_analysis.pot
diff --git a/upgrade_analysis/i18n/upgrade_analysis.pot b/upgrade_analysis/i18n/upgrade_analysis.pot
new file mode 100644
index 000000000..63f58e38a
--- /dev/null
+++ b/upgrade_analysis/i18n/upgrade_analysis.pot
@@ -0,0 +1,521 @@
+# Translation of Odoo Server.
+# This file contains the translation of the following modules:
+# * upgrade_analysis
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: Odoo Server 14.0\n"
+"Report-Msgid-Bugs-To: \n"
+"Last-Translator: \n"
+"Language-Team: \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: \n"
+"Plural-Forms: \n"
+
+#. module: upgrade_analysis
+#: model_terms:ir.ui.view,arch_db:upgrade_analysis.view_upgrade_install_wizard_form
+msgid "All Modules"
+msgstr ""
+
+#. module: upgrade_analysis
+#: model_terms:ir.ui.view,arch_db:upgrade_analysis.view_upgrade_install_wizard_form
+msgid "All OCA Modules"
+msgstr ""
+
+#. module: upgrade_analysis
+#: model_terms:ir.ui.view,arch_db:upgrade_analysis.view_upgrade_install_wizard_form
+msgid "All Odoo SA Modules"
+msgstr ""
+
+#. module: upgrade_analysis
+#: model_terms:ir.ui.view,arch_db:upgrade_analysis.view_upgrade_install_wizard_form
+msgid "All Other Modules"
+msgstr ""
+
+#. module: upgrade_analysis
+#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_comparison_config__analysis_ids
+#: model_terms:ir.ui.view,arch_db:upgrade_analysis.view_upgrade_comparison_config_form
+msgid "Analyses"
+msgstr ""
+
+#. module: upgrade_analysis
+#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_analysis__analysis_date
+msgid "Analysis Date"
+msgstr ""
+
+#. module: upgrade_analysis
+#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_comparison_config__analysis_qty
+msgid "Analysis Qty"
+msgstr ""
+
+#. module: upgrade_analysis
+#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_record__attribute_ids
+msgid "Attribute"
+msgstr ""
+
+#. module: upgrade_analysis
+#: model_terms:ir.ui.view,arch_db:upgrade_analysis.view_upgrade_record_form
+msgid "Attributes"
+msgstr ""
+
+#. module: upgrade_analysis
+#: code:addons/upgrade_analysis/wizards/upgrade_generate_record_wizard.py:0
+#, python-format
+msgid "Cannot seem to install or upgrade modules %s"
+msgstr ""
+
+#. module: upgrade_analysis
+#: model_terms:ir.ui.view,arch_db:upgrade_analysis.view_upgrade_install_wizard_form
+msgid "Clear the list"
+msgstr ""
+
+#. module: upgrade_analysis
+#: model_terms:ir.ui.view,arch_db:upgrade_analysis.view_upgrade_generate_record_wizard_form
+#: model_terms:ir.ui.view,arch_db:upgrade_analysis.view_upgrade_install_wizard_form
+msgid "Close"
+msgstr ""
+
+#. module: upgrade_analysis
+#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_analysis__config_id
+msgid "Comparison Config"
+msgstr ""
+
+#. module: upgrade_analysis
+#: model:ir.ui.menu,name:upgrade_analysis.menu_upgrade_comparison_config
+msgid "Comparison Configurations"
+msgstr ""
+
+#. module: upgrade_analysis
+#: code:addons/upgrade_analysis/models/upgrade_comparison_config.py:0
+#, python-format
+msgid ""
+"Connection failed.\n"
+"\n"
+"DETAIL: %s"
+msgstr ""
+
+#. module: upgrade_analysis
+#: model_terms:ir.ui.view,arch_db:upgrade_analysis.view_upgrade_generate_record_wizard_form
+msgid "Continue"
+msgstr ""
+
+#. module: upgrade_analysis
+#: code:addons/upgrade_analysis/models/upgrade_comparison_config.py:0
+#, python-format
+msgid "Could not connect the Odoo server at %s:%s"
+msgstr ""
+
+#. module: upgrade_analysis
+#: model:ir.model.fields.selection,name:upgrade_analysis.selection__upgrade_record__mode__create
+msgid "Create"
+msgstr ""
+
+#. module: upgrade_analysis
+#: model_terms:ir.ui.view,arch_db:upgrade_analysis.view_upgrade_record_search
+msgid "Create Mode"
+msgstr ""
+
+#. module: upgrade_analysis
+#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_analysis__create_uid
+#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_attribute__create_uid
+#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_comparison_config__create_uid
+#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_generate_record_wizard__create_uid
+#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_install_wizard__create_uid
+#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_record__create_uid
+msgid "Created by"
+msgstr ""
+
+#. module: upgrade_analysis
+#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_analysis__create_date
+#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_attribute__create_date
+#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_comparison_config__create_date
+#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_generate_record_wizard__create_date
+#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_install_wizard__create_date
+#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_record__create_date
+msgid "Created on"
+msgstr ""
+
+#. module: upgrade_analysis
+#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_comparison_config__database
+msgid "Database"
+msgstr ""
+
+#. module: upgrade_analysis
+#: model:ir.model.fields,field_description:upgrade_analysis.field_ir_module_module__display_name
+#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_analysis__display_name
+#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_attribute__display_name
+#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_comparison_config__display_name
+#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_generate_record_wizard__display_name
+#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_install_wizard__display_name
+#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_record__display_name
+msgid "Display Name"
+msgstr ""
+
+#. module: upgrade_analysis
+#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_record__domain
+msgid "Domain"
+msgstr ""
+
+#. module: upgrade_analysis
+#: model:ir.model.fields.selection,name:upgrade_analysis.selection__upgrade_analysis__state__done
+#: model:ir.model.fields.selection,name:upgrade_analysis.selection__upgrade_generate_record_wizard__state__done
+#: model:ir.model.fields.selection,name:upgrade_analysis.selection__upgrade_install_wizard__state__done
+msgid "Done"
+msgstr ""
+
+#. module: upgrade_analysis
+#: model:ir.model.fields.selection,name:upgrade_analysis.selection__upgrade_generate_record_wizard__state__draft
+#: model:ir.model.fields.selection,name:upgrade_analysis.selection__upgrade_install_wizard__state__draft
+msgid "Draft"
+msgstr ""
+
+#. module: upgrade_analysis
+#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_record__field
+#: model:ir.model.fields.selection,name:upgrade_analysis.selection__upgrade_record__type__field
+msgid "Field"
+msgstr ""
+
+#. module: upgrade_analysis
+#: model:ir.actions.act_window,name:upgrade_analysis.action_upgrade_generate_record_wizard
+#: model:ir.ui.menu,name:upgrade_analysis.menu_upgrade_generate_record
+msgid "Generate Records Wizard"
+msgstr ""
+
+#. module: upgrade_analysis
+#: model:ir.model.fields,field_description:upgrade_analysis.field_ir_module_module__id
+#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_analysis__id
+#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_attribute__id
+#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_comparison_config__id
+#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_generate_record_wizard__id
+#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_install_wizard__id
+#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_record__id
+msgid "ID"
+msgstr ""
+
+#. module: upgrade_analysis
+#: model_terms:ir.ui.view,arch_db:upgrade_analysis.view_upgrade_install_wizard_form
+msgid "Install Modules"
+msgstr ""
+
+#. module: upgrade_analysis
+#: model:ir.actions.act_window,name:upgrade_analysis.action_upgrade_install_wizard
+#: model:ir.ui.menu,name:upgrade_analysis.menu_upgrade_install
+msgid "Install Modules Wizard"
+msgstr ""
+
+#. module: upgrade_analysis
+#: model:ir.model.fields,field_description:upgrade_analysis.field_ir_module_module__is_oca_module
+msgid "Is Oca Module"
+msgstr ""
+
+#. module: upgrade_analysis
+#: model:ir.model.fields,field_description:upgrade_analysis.field_ir_module_module__is_odoo_module
+msgid "Is Odoo Module"
+msgstr ""
+
+#. module: upgrade_analysis
+#: model:ir.model.fields,field_description:upgrade_analysis.field_ir_module_module____last_update
+#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_analysis____last_update
+#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_attribute____last_update
+#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_comparison_config____last_update
+#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_generate_record_wizard____last_update
+#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_install_wizard____last_update
+#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_record____last_update
+msgid "Last Modified on"
+msgstr ""
+
+#. module: upgrade_analysis
+#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_analysis__write_uid
+#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_attribute__write_uid
+#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_comparison_config__write_uid
+#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_generate_record_wizard__write_uid
+#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_install_wizard__write_uid
+#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_record__write_uid
+msgid "Last Updated by"
+msgstr ""
+
+#. module: upgrade_analysis
+#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_analysis__write_date
+#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_attribute__write_date
+#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_comparison_config__write_date
+#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_generate_record_wizard__write_date
+#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_install_wizard__write_date
+#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_record__write_date
+msgid "Last Updated on"
+msgstr ""
+
+#. module: upgrade_analysis
+#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_analysis__log
+#: model_terms:ir.ui.view,arch_db:upgrade_analysis.view_upgrade_analysis_form
+msgid "Log"
+msgstr ""
+
+#. module: upgrade_analysis
+#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_record__mode
+msgid "Mode"
+msgstr ""
+
+#. module: upgrade_analysis
+#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_record__model
+#: model:ir.model.fields.selection,name:upgrade_analysis.selection__upgrade_record__type__model
+msgid "Model"
+msgstr ""
+
+#. module: upgrade_analysis
+#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_record__model_original_module
+msgid "Model Original Module"
+msgstr ""
+
+#. module: upgrade_analysis
+#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_record__model_type
+msgid "Model Type"
+msgstr ""
+
+#. module: upgrade_analysis
+#: model:ir.model.fields.selection,name:upgrade_analysis.selection__upgrade_record__mode__modify
+msgid "Modify"
+msgstr ""
+
+#. module: upgrade_analysis
+#: model_terms:ir.ui.view,arch_db:upgrade_analysis.view_upgrade_record_search
+msgid "Modify Mode"
+msgstr ""
+
+#. module: upgrade_analysis
+#: model:ir.model,name:upgrade_analysis.model_ir_module_module
+#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_install_wizard__module_ids
+#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_record__module
+msgid "Module"
+msgstr ""
+
+#. module: upgrade_analysis
+#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_install_wizard__module_qty
+msgid "Modules Quantity"
+msgstr ""
+
+#. module: upgrade_analysis
+#: model_terms:ir.ui.view,arch_db:upgrade_analysis.view_upgrade_generate_record_wizard_form
+msgid "Modules initialized and record created"
+msgstr ""
+
+#. module: upgrade_analysis
+#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_attribute__name
+#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_comparison_config__name
+#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_install_wizard__name
+#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_record__name
+msgid "Name"
+msgstr ""
+
+#. module: upgrade_analysis
+#: model_terms:ir.ui.view,arch_db:upgrade_analysis.view_upgrade_comparison_config_form
+msgid "New Analysis"
+msgstr ""
+
+#. module: upgrade_analysis
+#: code:addons/upgrade_analysis/models/upgrade_record.py:0
+#, python-format
+msgid "No manifest found in %s"
+msgstr ""
+
+#. module: upgrade_analysis
+#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_record__noupdate
+msgid "Noupdate"
+msgstr ""
+
+#. module: upgrade_analysis
+#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_comparison_config__password
+msgid "Password"
+msgstr ""
+
+#. module: upgrade_analysis
+#: model_terms:ir.ui.view,arch_db:upgrade_analysis.view_upgrade_analysis_form
+msgid "Perform Analysis"
+msgstr ""
+
+#. module: upgrade_analysis
+#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_comparison_config__port
+msgid "Port"
+msgstr ""
+
+#. module: upgrade_analysis
+#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_record__prefix
+msgid "Prefix"
+msgstr ""
+
+#. module: upgrade_analysis
+#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_attribute__record_id
+msgid "Record"
+msgstr ""
+
+#. module: upgrade_analysis
+#: model:ir.ui.menu,name:upgrade_analysis.menu_upgrade_records
+msgid "Records"
+msgstr ""
+
+#. module: upgrade_analysis
+#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_comparison_config__server
+msgid "Server"
+msgstr ""
+
+#. module: upgrade_analysis
+#: model:ir.model.fields,help:upgrade_analysis.field_upgrade_record__mode
+msgid ""
+"Set to Create if a field is newly created in this module. If this module "
+"modifies an attribute of an existing field, set to Modify."
+msgstr ""
+
+#. module: upgrade_analysis
+#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_analysis__state
+#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_generate_record_wizard__state
+#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_install_wizard__state
+msgid "State"
+msgstr ""
+
+#. module: upgrade_analysis
+#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_record__suffix
+msgid "Suffix"
+msgstr ""
+
+#. module: upgrade_analysis
+#: model_terms:ir.ui.view,arch_db:upgrade_analysis.view_upgrade_comparison_config_form
+msgid "Test Connection"
+msgstr ""
+
+#. module: upgrade_analysis
+#: model:ir.model.fields,help:upgrade_analysis.field_upgrade_analysis__upgrade_path
+msgid ""
+"The base file path to save the analyse files of Odoo modules. Taken from "
+"Odoo's --upgrade-path command line option or the 'scripts' subdirectory in "
+"the openupgrade_scripts addon."
+msgstr ""
+
+#. module: upgrade_analysis
+#: model_terms:ir.ui.view,arch_db:upgrade_analysis.view_upgrade_install_wizard_form
+msgid "The modules have been installed successfuly"
+msgstr ""
+
+#. module: upgrade_analysis
+#: model_terms:ir.ui.view,arch_db:upgrade_analysis.view_upgrade_install_wizard_form
+msgid ""
+"This will install the selected modules on the database. Do not continue if "
+"you use this database in production."
+msgstr ""
+
+#. module: upgrade_analysis
+#: model_terms:ir.ui.view,arch_db:upgrade_analysis.view_upgrade_generate_record_wizard_form
+msgid ""
+"This will reinitialize all the modules installed on this database. Do not "
+"continue if you use this database in production."
+msgstr ""
+
+#. module: upgrade_analysis
+#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_record__type
+msgid "Type"
+msgstr ""
+
+#. module: upgrade_analysis
+#: code:addons/upgrade_analysis/models/upgrade_analysis.py:0
+#, python-format
+msgid "Unexpected root Element: %s in file: %s"
+msgstr ""
+
+#. module: upgrade_analysis
+#: model:ir.actions.act_window,name:upgrade_analysis.action_upgrade_analysis_tree
+#: model:ir.model,name:upgrade_analysis.model_upgrade_analysis
+#: model:ir.ui.menu,name:upgrade_analysis.menu_upgrade_analysis
+msgid "Upgrade Analyses"
+msgstr ""
+
+#. module: upgrade_analysis
+#: model:ir.ui.menu,name:upgrade_analysis.menu_upgrade
+msgid "Upgrade Analysis"
+msgstr ""
+
+#. module: upgrade_analysis
+#: model:ir.model,name:upgrade_analysis.model_upgrade_attribute
+msgid "Upgrade Attribute"
+msgstr ""
+
+#. module: upgrade_analysis
+#: model:ir.model,name:upgrade_analysis.model_upgrade_comparison_config
+msgid "Upgrade Comparison Configuration"
+msgstr ""
+
+#. module: upgrade_analysis
+#: model:ir.model,name:upgrade_analysis.model_upgrade_generate_record_wizard
+msgid "Upgrade Generate Record Wizard"
+msgstr ""
+
+#. module: upgrade_analysis
+#: model:ir.model,name:upgrade_analysis.model_upgrade_install_wizard
+msgid "Upgrade Install Wizard"
+msgstr ""
+
+#. module: upgrade_analysis
+#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_analysis__upgrade_path
+msgid "Upgrade Path"
+msgstr ""
+
+#. module: upgrade_analysis
+#: model:ir.model,name:upgrade_analysis.model_upgrade_record
+msgid "Upgrade Record"
+msgstr ""
+
+#. module: upgrade_analysis
+#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_comparison_config__username
+msgid "Username"
+msgstr ""
+
+#. module: upgrade_analysis
+#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_attribute__value
+msgid "Value"
+msgstr ""
+
+#. module: upgrade_analysis
+#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_comparison_config__version
+msgid "Version"
+msgstr ""
+
+#. module: upgrade_analysis
+#: model:ir.model.fields,help:upgrade_analysis.field_upgrade_install_wizard__name
+msgid "Workaround for https://github.com/OCA/odoorpc/issues/57"
+msgstr ""
+
+#. module: upgrade_analysis
+#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_analysis__write_files
+msgid "Write Files"
+msgstr ""
+
+#. module: upgrade_analysis
+#: model:ir.model.fields,help:upgrade_analysis.field_upgrade_analysis__write_files
+msgid "Write analysis files to the module directories"
+msgstr ""
+
+#. module: upgrade_analysis
+#: model:ir.model.fields.selection,name:upgrade_analysis.selection__upgrade_record__type__xmlid
+msgid "XML ID"
+msgstr ""
+
+#. module: upgrade_analysis
+#: code:addons/upgrade_analysis/models/upgrade_comparison_config.py:0
+#, python-format
+msgid ""
+"You are correctly connected to the server %(server)s (version %(version)s) "
+"with the user %(user_name)s"
+msgstr ""
+
+#. module: upgrade_analysis
+#: model:ir.model.fields.selection,name:upgrade_analysis.selection__upgrade_analysis__state__draft
+msgid "draft"
+msgstr ""
+
+#. module: upgrade_analysis
+#: model:ir.actions.act_window,name:upgrade_analysis.action_upgrade_comparison_config_tree
+msgid "upgrade Comparison Configs"
+msgstr ""
+
+#. module: upgrade_analysis
+#: model:ir.actions.act_window,name:upgrade_analysis.action_upgrade_record_tree
+msgid "upgrade Records"
+msgstr ""
From 248424ca4f94e12293df55585ff000eee835fa02 Mon Sep 17 00:00:00 2001
From: OCA-git-bot
Date: Fri, 26 Feb 2021 19:32:00 +0000
Subject: [PATCH 19/67] [UPD] README.rst
---
upgrade_analysis/README.rst | 79 ++++
.../static/description/index.html | 435 ++++++++++++++++++
2 files changed, 514 insertions(+)
create mode 100644 upgrade_analysis/static/description/index.html
diff --git a/upgrade_analysis/README.rst b/upgrade_analysis/README.rst
index 2b99745a8..82b5e950e 100644
--- a/upgrade_analysis/README.rst
+++ b/upgrade_analysis/README.rst
@@ -6,3 +6,82 @@ Upgrade Analysis
!! This file is generated by oca-gen-addon-readme !!
!! changes will be overwritten. !!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+.. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png
+ :target: https://odoo-community.org/page/development-status
+ :alt: Beta
+.. |badge2| image:: https://img.shields.io/badge/licence-AGPL--3-blue.png
+ :target: http://www.gnu.org/licenses/agpl-3.0-standalone.html
+ :alt: License: AGPL-3
+.. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fserver--tools-lightgray.png?logo=github
+ :target: https://github.com/OCA/server-tools/tree/14.0/upgrade_analysis
+ :alt: OCA/server-tools
+.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png
+ :target: https://translation.odoo-community.org/projects/server-tools-14-0/server-tools-14-0-upgrade_analysis
+ :alt: Translate me on Weblate
+.. |badge5| image:: https://img.shields.io/badge/runbot-Try%20me-875A7B.png
+ :target: https://runbot.odoo-community.org/runbot/149/14.0
+ :alt: Try me on Runbot
+
+|badge1| |badge2| |badge3| |badge4| |badge5|
+
+This module provides the tool to generate the database analysis files that indicate how the Odoo data model and module data have changed between two versions of Odoo. Database analysis files for the core modules are included in the OpenUpgrade distribution so as a migration script developer you will not usually need to use this tool yourself. If you do need to run your analysis of a custom set of modules, please refer to the documentation here: https://doc.therp.nl/openupgrade/analysis.html
+
+**Table of contents**
+
+.. contents::
+ :local:
+
+Known issues / Roadmap
+======================
+
+* Log removed modules in the module that owned them (#468)
+* Detect renamed many2many tables (#213)
+
+Bug Tracker
+===========
+
+Bugs are tracked on `GitHub Issues `_.
+In case of trouble, please check there if your issue has already been reported.
+If you spotted it first, help us smashing it by providing a detailed and welcomed
+`feedback `_.
+
+Do not contact contributors directly about support or help with technical issues.
+
+Credits
+=======
+
+Authors
+~~~~~~~
+
+* Therp BV
+* Opener B.V.
+* GRAP
+
+Contributors
+~~~~~~~~~~~~
+
+* Stefan Rijnhart
+* Holger Brunn
+* Pedro M. Baeza
+* Ferdinand Gassauer
+* Florent Xicluna
+* Miquel Raïch
+* Sylvain LE GAL
+
+Maintainers
+~~~~~~~~~~~
+
+This module is maintained by the OCA.
+
+.. image:: https://odoo-community.org/logo.png
+ :alt: Odoo Community Association
+ :target: https://odoo-community.org
+
+OCA, or the Odoo Community Association, is a nonprofit organization whose
+mission is to support the collaborative development of Odoo features and
+promote its widespread use.
+
+This module is part of the `OCA/server-tools `_ project on GitHub.
+
+You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.
diff --git a/upgrade_analysis/static/description/index.html b/upgrade_analysis/static/description/index.html
new file mode 100644
index 000000000..0da55055a
--- /dev/null
+++ b/upgrade_analysis/static/description/index.html
@@ -0,0 +1,435 @@
+
+
+
+
+
+
+Upgrade Analysis
+
+
+
+
+
Upgrade Analysis
+
+
+
+
This module provides the tool to generate the database analysis files that indicate how the Odoo data model and module data have changed between two versions of Odoo. Database analysis files for the core modules are included in the OpenUpgrade distribution so as a migration script developer you will not usually need to use this tool yourself. If you do need to run your analysis of a custom set of modules, please refer to the documentation here: https://doc.therp.nl/openupgrade/analysis.html
+
Table of contents
+
+
+
+
+Log removed modules in the module that owned them (#468)
+Detect renamed many2many tables (#213)
+
+
+
+
+
Bugs are tracked on GitHub Issues .
+In case of trouble, please check there if your issue has already been reported.
+If you spotted it first, help us smashing it by providing a detailed and welcomed
+feedback .
+
Do not contact contributors directly about support or help with technical issues.
+
+
+
+
+
+
+Therp BV
+Opener B.V.
+GRAP
+
+
+
+
+
+
This module is maintained by the OCA.
+
+
OCA, or the Odoo Community Association, is a nonprofit organization whose
+mission is to support the collaborative development of Odoo features and
+promote its widespread use.
+
This module is part of the OCA/server-tools project on GitHub.
+
You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute .
+
+
+
+
+
From 036c7283caed8f69a4b6ebce51a28f97555e2afb Mon Sep 17 00:00:00 2001
From: OCA-git-bot
Date: Fri, 26 Feb 2021 19:32:01 +0000
Subject: [PATCH 20/67] [ADD] icon.png
---
upgrade_analysis/static/description/icon.png | Bin 0 -> 9455 bytes
1 file changed, 0 insertions(+), 0 deletions(-)
create mode 100644 upgrade_analysis/static/description/icon.png
diff --git a/upgrade_analysis/static/description/icon.png b/upgrade_analysis/static/description/icon.png
new file mode 100644
index 0000000000000000000000000000000000000000..3a0328b516c4980e8e44cdb63fd945757ddd132d
GIT binary patch
literal 9455
zcmW++2RxMjAAjx~&dlBk9S+%}OXg)AGE&Cb*&}d0jUxM@u(PQx^-s)697TX`ehR4?GS^qbkof1cslKgkU)h65qZ9Oc=ml_0temigYLJfnz{IDzUf>bGs4N!v3=Z3jMq&A#7%rM5eQ#dc?k~!
zVpnB`o+K7|Al`Q_U;eD$B
zfJtP*jH`siUq~{KE)`jP2|#TUEFGRryE2`i0**z#*^6~AI|YzIWy$Cu#CSLW3q=GA
z6`?GZymC;dCPk~rBS%eCb`5OLr;RUZ;D`}um=H)BfVIq%7VhiMr)_#G0N#zrNH|__
zc+blN2UAB0=617@>_u;MPHN;P;N#YoE=)R#i$k_`UAA>WWCcEVMh~L_
zj--gtp&|K1#58Yz*AHCTMziU1Jzt_jG0I@qAOHsk$2}yTmVkBp_eHuY$A9)>P6o~I
z%aQ?!(GqeQ-Y+b0I(m9pwgi(IIZZzsbMv+9w{PFtd_<_(LA~0H(xz{=FhLB@(1&qHA5EJw1>>=%q2f&^X>IQ{!GJ4e9U
z&KlB)z(84HmNgm2hg2C0>WM{E(DdPr+EeU_N@57;PC2&DmGFW_9kP&%?X4}+xWi)(
z;)z%wI5>D4a*5XwD)P--sPkoY(a~WBw;E~AW`Yue4kFa^LM3X`8x|}ZUeMnqr}>kH
zG%WWW>3ml$Yez?i%)2pbKPI7?5o?hydokgQyZsNEr{a|mLdt;X2TX(#B1j35xPnPW
z*bMSSOauW>o;*=kO8ojw91VX!qoOQb)zHJ!odWB}d+*K?#sY_jqPdg{Sm2HdYzdEx
zOGVPhVRTGPtv0o}RfVP;Nd(|CB)I;*t&QO8h
zFfekr30S!-LHmV_Su-W+rEwYXJ^;6&3|L$mMC8*bQptyOo9;>Qb9Q9`ySe3%V$A*9
zeKEe+b0{#KWGp$F+tga)0RtI)nhMa-K@JS}2krK~n8vJ=Ngm?R!9G<~RyuU0d?nz#
z-5EK$o(!F?hmX*2Yt6+coY`6jGbb7tF#6nHA
zuKk=GGJ;ZwON1iAfG$E#Y7MnZVmrY|j0eVI(DN_MNFJmyZ|;w4tf@=CCDZ#5N_0K=
z$;R~bbk?}TpfDjfB&aiQ$VA}s?P}xPERJG{kxk5~R`iRS(SK5d+Xs9swCozZISbnS
zk!)I0>t=A<-^z(cmSFz3=jZ23u13X><0b)P)^1T_))Kr`e!-pb#q&J*Q`p+B6la%C
zuVl&0duN<;uOsB3%T9Fp8t{ED108)`y_~Hnd9AUX7h-H?jVuU|}My+C=TjH(jKz
zqMVr0re3S$H@t{zI95qa)+Crz*5Zj}Ao%4Z><+W(nOZd?gDnfNBC3>M8WE61$So|P
zVvqH0SNtDTcsUdzaMDpT=Ty0pDHHNL@Z0w$Y`XO
z2M-_r1S+GaH%pz#Uy0*w$Vdl=X=rQXEzO}d6J^R6zjM1u&c9vYLvLp?W7w(?np9x1
zE_0JSAJCPB%i7p*Wvg)pn5T`8k3-uR?*NT|J`eS#_#54p>!p(mLDvmc-3o0mX*mp_
zN*AeS<>#^-{S%W<*mz^!X$w_2dHWpcJ6^j64qFBft-o}o_Vx80o0>}Du;>kLts;$8
zC`7q$QI(dKYG`Wa8#wl@V4jVWBRGQ@1dr-hstpQL)Tl+aqVpGpbSfN>5i&QMXfiZ>
zaA?T1VGe?rpQ@;+pkrVdd{klI&jVS@I5_iz!=UMpTsa~mBga?1r}aRBm1WS;TT*s0f0lY=JBl66Upy)-k4J}lh=P^8(SXk~0xW=T9v*B|gzIhN
z>qsO7dFd~mgxAy4V?&)=5ieYq?zi?ZEoj)&2o)RLy=@hbCRcfT5jigwtQGE{L*8<@Yd{zg;CsL5mvzfDY}P-wos_6PfprFVaeqNE%h
zKZhLtcQld;ZD+>=nqN~>GvROfueSzJD&BE*}XfU|H&(FssBqY=hPCt`d
zH?@s2>I(|;fcW&YM6#V#!kUIP8$Nkdh0A(bEVj``-AAyYgwY~jB
zT|I7Bf@%;7aL7Wf4dZ%VqF$eiaC38OV6oy3Z#TER2G+fOCd9Iaoy6aLYbPTN{XRPz
z;U!V|vBf%H!}52L2gH_+j;`bTcQRXB+y9onc^wLm5wi3-Be}U>k_u>2Eg$=k!(l@I
zcCg+flakT2Nej3i0yn+g+}%NYb?ta;R?(g5SnwsQ49U8Wng8d|{B+lyRcEDvR3+`O{zfmrmvFrL6acVP%yG98X
zo&+VBg@px@i)%o?dG(`T;n*$S5*rnyiR#=wW}}GsAcfyQpE|>a{=$Hjg=-*_K;UtD
z#z-)AXwSRY?OPefw^iI+
z)AXz#PfEjlwTes|_{sB?4(O@fg0AJ^g8gP}ex9Ucf*@_^J(s_5jJV}c)s$`Myn|Kd
z$6>}#q^n{4vN@+Os$m7KV+`}c%4)4pv@06af4-x5#wj!KKb%caK{A&Y#Rfs
z-po?Dcb1({W=6FKIUirH&(yg=*6aLCekcKwyfK^JN5{wcA3nhO(o}SK#!CINhI`-I
z1)6&n7O&ZmyFMuNwvEic#IiOAwNkR=u5it{B9n2sAJV5pNhar=j5`*N!Na;c7g!l$
z3aYBqUkqqTJ=Re-;)s!EOeij=7SQZ3Hq}ZRds%IM*PtM$wV
z@;rlc*NRK7i3y5BETSKuumEN`Xu_8GP1Ri=OKQ$@I^ko8>H6)4rjiG5{VBM>B|%`&&s^)jS|-_95&yc=GqjNo{zFkw%%HHhS~e=s
zD#sfS+-?*t|J!+ozP6KvtOl!R)@@-z24}`9{QaVLD^9VCSR2b`b!KC#o;Ki<+wXB6
zx3&O0LOWcg4&rv4QG0)4yb}7BFSEg~=IR5#ZRj8kg}dS7_V&^%#Do==#`u
zpy6{ox?jWuR(;pg+f@mT>#HGWHAJRRDDDv~@(IDw&R>9643kK#HN`!1vBJHnC+RM&yIh8{gG2q
zA%e*U3|N0XSRa~oX-3EAneep)@{h2vvd3Xvy$7og(sayr@95+e6~Xvi1tUqnIxoIH
zVWo*OwYElb#uyW{Imam6f2rGbjR!Y3`#gPqkv57dB6K^wRGxc9B(t|aYDGS=m$&S!NmCtrMMaUg(c
zc2qC=2Z`EEFMW-me5B)24AqF*bV5Dr-M5ig(l-WPS%CgaPzs6p_gnCIvTJ=Y<6!gT
zVt@AfYCzjjsMEGi=rDQHo0yc;HqoRNnNFeWZgcm?f;cp(6CNylj36DoL(?TS7eU#+
z7&mfr#y))+CJOXQKUMZ7QIdS9@#-}7y2K1{8)cCt0~-X0O!O?Qx#E4Og+;A2SjalQ
zs7r?qn0H044=sDN$SRG$arw~n=+T_DNdSrarmu)V6@|?1-ZB#hRn`uilTGPJ@fqEy
zGt(f0B+^JDP&f=r{#Y_wi#AVDf-y!RIXU^0jXsFpf>=Ji*TeqSY!H~AMbJdCGLhC)
zn7Rx+sXw6uYj;WRYrLd^5IZq@6JI1C^YkgnedZEYy<&4(z%Q$5yv#Boo{AH8n$a
zhb4Y3PWdr269&?V%uI$xMcUrMzl=;w<_nm*qr=c3Rl@i5wWB;e-`t7D&c-mcQl7x!
zZWB`UGcw=Y2=}~wzrfLx=uet<;m3~=8I~ZRuzvMQUQdr+yTV|ATf1Uuomr__nDf=X
zZ3WYJtHp_ri(}SQAPjv+Y+0=fH4krOP@S&=zZ-t1jW1o@}z;xk8
z(Nz1co&El^HK^NrhVHa-_;&88vTU>_J33=%{if;BEY*J#1n59=07jrGQ#IP>@u#3A
z;!q+E1Rj3ZJ+!4bq9F8PXJ@yMgZL;>&gYA0%_Kbi8?S=XGM~dnQZQ!yBSgcZhY96H
zrWnU;k)qy`rX&&xlDyA%(a1Hhi5CWkmg(`Gb%m(HKi-7Z!LKGRP_B8@`7&hdDy5n=
z`OIxqxiVfX@OX1p(mQu>0Ai*v_cTMiw4qRt3~NBvr9oBy0)r>w3p~V0SCm=An6@3n)>@z!|o-$HvDK
z|3D2ZMJkLE5loMKl6R^ez@Zz%S$&mbeoqH5`Bb){Ei21q&VP)hWS2tjShfFtGE+$z
zzCR$P#uktu+#!w)cX!lWN1XU%K-r=s{|j?)Akf@q#3b#{6cZCuJ~gCxuMXRmI$nGtnH+-h
z+GEi!*X=AP<|fG`1>MBdTb?28JYc=fGvAi2I<$B(rs$;eoJCyR6_bc~p!XR@O-+sD
z=eH`-ye})I5ic1eL~TDmtfJ|8`0VJ*Yr=hNCd)G1p2MMz4C3^Mj?7;!w|Ly%JqmuW
zlIEW^Ft%z?*|fpXda>Jr^1noFZEwFgVV%|*XhH@acv8rdGxeEX{M$(vG{Zw+x(ei@
zmfXb22}8-?Fi`vo-YVrTH*C?a8%M=Hv9MqVH7H^J$KsD?>!SFZ;ZsvnHr_gn=7acz
z#W?0eCdVhVMWN12VV^$>WlQ?f;P^{(&pYTops|btm6aj>_Uz+hqpGwB)vWp0Cf5y<
zft8-je~nn?W11plq}N)4A{l8I7$!ks_x$PXW-2XaRFswX_BnF{R#6YIwMhAgd5F9X
zGmwdadS6(a^fjHtXg8=l?Rc0Sm%hk6E9!5cLVloEy4eh(=FwgP`)~I^5~pBEWo+F6
zSf2ncyMurJN91#cJTy_u8Y}@%!bq1RkGC~-bV@SXRd4F{R-*V`bS+6;W5vZ(&+I<9$;-V|eNfLa5n-6%
z2(}&uGRF;p92eS*sE*oR$@pexaqr*meB)VhmIg@h{uzkk$9~qh#cHhw#>O%)b@+(|
z^IQgqzuj~Sk(J;swEM-3TrJAPCq9k^^^`q{IItKBRXYe}e0Tdr=Huf7da3$l4PdpwWDop%^}n;dD#K4s#DYA8SHZ
z&1!riV4W4R7R#C))JH1~axJ)RYnM$$lIR%6fIVA@zV{XVyx}C+a-Dt8Y9M)^KU0+H
zR4IUb2CJ{Hg>CuaXtD50jB(_Tcx=Z$^WYu2u5kubqmwp%drJ6
z?Fo40g!Qd<-l=TQxqHEOuPX0;^z7iX?Ke^a%XT<13TA^5`4Xcw6D@Ur&VT&CUe0d}
z1GjOVF1^L@>O)l@?bD~$wzgf(nxX1OGD8fEV?TdJcZc2KoUe|oP1#=$$7ee|xbY)A
zDZq+cuTpc(fFdj^=!;{k03C69lMQ(|>uhRfRu%+!k&YOi-3|1QKB
z
z?n?eq1XP>p-IM$Z^C;2L3itnbJZAip*Zo0aw2bs8@(s^~*8T9go!%dHcAz2lM;`yp
zD=7&xjFV$S&5uDaiScyD?B-i1ze`+CoRtz`Wn+Zls4&}MO{@N!ufrzjG$B79)Y2d3tBk&)TxUTw@QS0TEL_?njX|@vq?Uz(nBFK5Pq7*xj#u*R&i|?7+6#
z+|r_n#SW&LXhtheZdah{ZVoqwyT{D>MC3nkFF#N)xLi{p7J1jXlmVeb;cP5?e(=f#
zuT7fvjSbjS781v?7{)-X3*?>tq?)Yd)~|1{BDS(pqC
zC}~H#WXlkUW*H5CDOo<)#x7%RY)A;ShGhI5s*#cRDA8YgqG(HeKDx+#(ZQ?386dv!
zlXCO)w91~Vw4AmOcATuV653fa9R$fyK8ul%rG
z-wfS
zihugoZyr38Im?Zuh6@RcF~t1anQu7>#lPpb#}4cOA!EM11`%f*07RqOVkmX{p~KJ9
z^zP;K#|)$`^Rb{rnHGH{~>1(fawV0*Z#)}M`m8-?ZJV<+e}s9wE#
z)l&az?w^5{)`S(%MRzxdNqrs1n*-=jS^_jqE*5XDrA0+VE`5^*p3CuM<&dZEeCjoz
zR;uu_H9ZPZV|fQq`Cyw4nscrVwi!fE6ciMmX$!_hN7uF;jjKG)d2@aC4ropY)8etW=xJvni)8eHi`H$%#zn^WJ5NLc-rqk|u&&4Z6fD_m&JfSI1Bvb?b<*n&sfl0^t
z=HnmRl`XrFvMKB%9}>PaA`m-fK6a0(8=qPkWS5bb4=v?XcWi&hRY?O5HdulRi4?fN
zlsJ*N-0Qw+Yic@s0(2uy%F@ib;GjXt01Fmx5XbRo6+n|pP(&nodMoap^z{~q
ziEeaUT@Mxe3vJSfI6?uLND(CNr=#^W<1b}jzW58bIfyWTDle$mmS(|x-0|2UlX+9k
zQ^EX7Nw}?EzVoBfT(-LT|=9N@^hcn-_p&sqG
z&*oVs2JSU+N4ZD`FhCAWaS;>|wH2G*Id|?pa#@>tyxX`+4HyIArWDvVrX)2WAOQff
z0qyHu&-S@i^MS-+j--!pr4fPBj~_8({~e1bfcl0wI1kaoN>mJL6KUPQm5N7lB(ui1
zE-o%kq)&djzWJ}ob<-GfDlkB;F31j-VHKvQUGQ3sp`CwyGJk_i!y^sD0fqC@$9|jO
zOqN!r!8-p==F@ZVP=U$qSpY(gQ0)59P1&t@y?5rvg<}E+GB}26NYPp4f2YFQrQtot5mn3wu_qprZ=>Ig-$
zbW26Ws~IgY>}^5w`vTB(G`PTZaDiGBo5o(tp)qli|NeV(
z@H_=R8V39rt5J5YB2Ky?4eJJ#b`_iBe2ot~6%7mLt5t8Vwi^Jy7|jWXqa3amOIoRb
zOr}WVFP--DsS`1WpN%~)t3R!arKF^Q$e12KEqU36AWwnCBICpH4XCsfnyrHr>$I$4
z!DpKX$OKLWarN7nv@!uIA+~RNO)l$$w}p(;b>mx8pwYvu;dD_unryX_NhT8*Tj>BTrTTL&!?O+%Rv;b?B??gSzdp?6Uug9{
zd@V08Z$BdI?fpoCS$)t4mg4rT8Q_I}h`0d-vYZ^|dOB*Q^S|xqTV*vIg?@fVFSmMpaw0qtTRbx}
z({Pg?#{2`sc9)M5N$*N|4;^t$+QP?#mov
zGVC@I*lBVrOU-%2y!7%)fAKjpEFsgQc4{amtiHb95KQEwvf<(3T<9-Zm$xIew#P22
zc2Ix|App^>v6(3L_MCU0d3W##AB0M~3D00EWoKZqsJYT(#@w$Y_H7G22M~ApVFTRHMI_3be)Lkn#0F*V8Pq
zc}`Cjy$bE;FJ6H7p=0y#R>`}-m4(0F>%@P|?7fx{=R^uFdISRnZ2W_xQhD{YuR3t<
z{6yxu=4~JkeA;|(J6_nv#>Nvs&FuLA&PW^he@t(UwFFE8)|a!R{`E`K`i^ZnyE4$k
z;(749Ix|oi$c3QbEJ3b~D_kQsPz~fIUKym($a_7dJ?o+40*OLl^{=&oq$<#Q(yyrp
z{J-FAniyAw9tPbe&IhQ|a`DqFTVQGQ&Gq3!C2==4x{6EJwiPZ8zub-iXoUtkJiG{}
zPaR&}_fn8_z~(=;5lD-aPWD3z8PZS@AaUiomF!G8I}Mf>e~0g#BelA-5#`cj;O5>N
Xviia!U7SGha1wx#SCgwmn*{w2TRX*I
literal 0
HcmV?d00001
From 79c6c1a134096ea28c5f2299560fba1677dfbf67 Mon Sep 17 00:00:00 2001
From: mreficent
Date: Tue, 23 Mar 2021 18:03:08 +0100
Subject: [PATCH 21/67] [IMP] openupgrade_records: remove from analysis
updating records
Given that the records need to be managed in the modules that own them rather in the modules that override them, and that we also have the noupdate data xml for every module, then we left out the lines that where indicating the override of records.
---
upgrade_analysis/compare.py | 33 ++++++++++++++++++++++++++++-----
1 file changed, 28 insertions(+), 5 deletions(-)
diff --git a/upgrade_analysis/compare.py b/upgrade_analysis/compare.py
index bc817d9e0..bc505bd6f 100644
--- a/upgrade_analysis/compare.py
+++ b/upgrade_analysis/compare.py
@@ -83,16 +83,22 @@ def compare_records(dict_old, dict_new, fields):
return True
-def search(item, item_list, fields):
+def search(item, item_list, fields, get_all=None):
"""
Find a match of a dictionary in a list of similar dictionaries
with respect to the keys in the 'fields' arguments.
Return the item if found or None.
"""
+ all_found = []
for other in item_list:
if not compare_records(item, other, fields):
continue
- return other
+ if not get_all:
+ return other
+ if other["module"] != other["prefix"]:
+ all_found.append(other)
+ if get_all:
+ return all_found
# search for renamed fields
if "field" in fields:
for other in item_list:
@@ -249,7 +255,7 @@ def compare_sets(old_records, new_records):
# other module, same operation, other type
matched_other_type = match(
- ["mode", "model", "field"],
+ ["module", "mode", "model", "field"],
[
"relation",
"type",
@@ -330,6 +336,20 @@ def compare_sets(old_records, new_records):
def compare_xml_sets(old_records, new_records):
reprs = collections.defaultdict(list)
+ def match_updates(match_fields):
+ old_updated, new_updated = {}, {}
+ for column in copy.copy(old_records):
+ found_all = search(column, old_records, match_fields, True)
+ for found in found_all:
+ old_records.remove(found)
+ for column in copy.copy(new_records):
+ found_all = search(column, new_records, match_fields, True)
+ for found in found_all:
+ new_records.remove(found)
+ matched_records = list(old_updated.values()) + list(new_updated.values())
+ matched_records = [y for x in matched_records for y in x]
+ return matched_records
+
def match(match_fields, match_type="direct"):
matched_records = []
for column in copy.copy(old_records):
@@ -362,6 +382,9 @@ def compare_xml_sets(old_records, new_records):
# direct match
modified_records = match(["module", "model", "name"])
+ # updated records (will be excluded)
+ match_updates(["model", "name"])
+
# other module, same full xmlid
moved_records = match(["model", "name"], "moved")
@@ -386,13 +409,13 @@ def compare_xml_sets(old_records, new_records):
if "old" in entry:
content = "DEL %(model)s: %(name)s" % entry
if "moved" in entry:
- content += " [potentially moved to %(moved)s module]" % entry
+ content += " [moved to %(moved)s module]" % entry
elif "renamed" in entry:
content += " [renamed to %(renamed)s module]" % entry
elif "new" in entry:
content = "NEW %(model)s: %(name)s" % entry
if "moved" in entry:
- content += " [potentially moved from %(moved)s module]" % entry
+ content += " [moved from %(moved)s module]" % entry
elif "renamed" in entry:
content += " [renamed from %(renamed)s module]" % entry
if "old" not in entry and "new" not in entry:
From 5ddc029b323a929f2a76fa22c21c89d8aa724924 Mon Sep 17 00:00:00 2001
From: mreficent
Date: Tue, 23 Mar 2021 18:06:43 +0100
Subject: [PATCH 22/67] [FIX] openupgrade_records: _inherits was not being
compared
---
upgrade_analysis/compare.py | 8 ++++----
upgrade_analysis/models/upgrade_record.py | 2 +-
upgrade_analysis/upgrade_log.py | 1 -
3 files changed, 5 insertions(+), 6 deletions(-)
diff --git a/upgrade_analysis/compare.py b/upgrade_analysis/compare.py
index bc505bd6f..0b3496d93 100644
--- a/upgrade_analysis/compare.py
+++ b/upgrade_analysis/compare.py
@@ -228,7 +228,7 @@ def compare_sets(old_records, new_records):
"relation",
"type",
"selection_keys",
- "inherits",
+ "_inherits",
"stored",
"isfunction",
"isrelated",
@@ -244,7 +244,7 @@ def compare_sets(old_records, new_records):
"module",
"relation",
"selection_keys",
- "inherits",
+ "_inherits",
"stored",
"isfunction",
"isrelated",
@@ -260,7 +260,7 @@ def compare_sets(old_records, new_records):
"relation",
"type",
"selection_keys",
- "inherits",
+ "_inherits",
"stored",
"isfunction",
"isrelated",
@@ -274,7 +274,7 @@ def compare_sets(old_records, new_records):
"required",
"selection_keys",
"req_default",
- "inherits",
+ "_inherits",
"mode",
"attachment",
]
diff --git a/upgrade_analysis/models/upgrade_record.py b/upgrade_analysis/models/upgrade_record.py
index 6aa07cab6..2e93cf030 100644
--- a/upgrade_analysis/models/upgrade_record.py
+++ b/upgrade_analysis/models/upgrade_record.py
@@ -102,7 +102,7 @@ class UpgradeRecord(models.Model):
"req_default",
"hasdefault",
"table",
- "inherits",
+ "_inherits",
]
template = {x: False for x in keys}
diff --git a/upgrade_analysis/upgrade_log.py b/upgrade_analysis/upgrade_log.py
index 345b1d772..84547402f 100644
--- a/upgrade_analysis/upgrade_log.py
+++ b/upgrade_analysis/upgrade_log.py
@@ -137,7 +137,6 @@ def log_model(model, local_registry):
"selection_keys": "",
"req_default": "",
"hasdefault": model._fields[k].default and "hasdefault" or "",
- "inherits": "",
}
if v.type == "selection":
if isinstance(v.selection, (tuple, list)):
From c4e8d888496fa91f4faf3b81e06229fba95289ef Mon Sep 17 00:00:00 2001
From: mreficent
Date: Tue, 23 Mar 2021 18:10:00 +0100
Subject: [PATCH 23/67] [IMP] openupgrade_records: compare columns of many2many
tables
---
upgrade_analysis/compare.py | 10 ++++++++++
upgrade_analysis/models/upgrade_record.py | 11 +++++++++++
2 files changed, 21 insertions(+)
diff --git a/upgrade_analysis/compare.py b/upgrade_analysis/compare.py
index 0b3496d93..1300f90b9 100644
--- a/upgrade_analysis/compare.py
+++ b/upgrade_analysis/compare.py
@@ -114,6 +114,8 @@ def fieldprint(old, new, field, text, reprs):
fullrepr = "{:<12} / {:<24} / {:<30}".format(old["module"], old["model"], fieldrepr)
if not text:
text = "{} is now '{}' ('{}')".format(field, new[field], old[field])
+ if field in ("column1", "column2"):
+ text += " [%s]" % old["table"]
if field == "relation":
text += " [nothing to do]"
reprs[module_map(old["module"])].append("{}: {}".format(fullrepr, text))
@@ -161,6 +163,14 @@ def report_generic(new, old, attrs, reprs):
else:
text = "not related anymore"
fieldprint(old, new, "", text, reprs)
+ elif attr == "table":
+ if old[attr] != new[attr]:
+ fieldprint(old, new, attr, "", reprs)
+ if old[attr] and new[attr]:
+ if old["column1"] != new["column1"]:
+ fieldprint(old, new, "column1", "", reprs)
+ if old["column2"] != new["column2"]:
+ fieldprint(old, new, "column2", "", reprs)
elif old[attr] != new[attr]:
fieldprint(old, new, attr, "", reprs)
diff --git a/upgrade_analysis/models/upgrade_record.py b/upgrade_analysis/models/upgrade_record.py
index 2e93cf030..445a90c97 100644
--- a/upgrade_analysis/models/upgrade_record.py
+++ b/upgrade_analysis/models/upgrade_record.py
@@ -118,6 +118,17 @@ class UpgradeRecord(models.Model):
}
)
repre.update({x.name: x.value for x in record.attribute_ids})
+ if repre["table"]:
+ repre.update(
+ {
+ "column1": self.env[repre["model"]]
+ ._fields[repre["field"]]
+ .column1,
+ "column2": self.env[repre["model"]]
+ ._fields[repre["field"]]
+ .column2,
+ }
+ )
data.append(repre)
return data
From 480412abc81420c29889cb622e15e7acbf4c4179 Mon Sep 17 00:00:00 2001
From: mreficent
Date: Tue, 23 Mar 2021 18:18:17 +0100
Subject: [PATCH 24/67] [IMP] openupgrade_records: add _order comparison
---
upgrade_analysis/compare.py | 11 ++++++++++-
upgrade_analysis/models/upgrade_record.py | 1 +
upgrade_analysis/upgrade_log.py | 1 +
3 files changed, 12 insertions(+), 1 deletion(-)
diff --git a/upgrade_analysis/compare.py b/upgrade_analysis/compare.py
index 1300f90b9..3222bcd1a 100644
--- a/upgrade_analysis/compare.py
+++ b/upgrade_analysis/compare.py
@@ -110,7 +110,9 @@ def search(item, item_list, fields, get_all=None):
def fieldprint(old, new, field, text, reprs):
- fieldrepr = "{} ({})".format(old["field"], old["type"])
+ fieldrepr = "{}".format(old["field"])
+ if old["field"] not in ("_inherits", "_order"):
+ fieldrepr += " ({})".format(old["type"])
fullrepr = "{:<12} / {:<24} / {:<30}".format(old["module"], old["model"], fieldrepr)
if not text:
text = "{} is now '{}' ('{}')".format(field, new[field], old[field])
@@ -244,6 +246,7 @@ def compare_sets(old_records, new_records):
"isrelated",
"required",
"table",
+ "_order",
],
)
@@ -260,6 +263,7 @@ def compare_sets(old_records, new_records):
"isrelated",
"required",
"table",
+ "_order",
],
)
@@ -276,6 +280,7 @@ def compare_sets(old_records, new_records):
"isrelated",
"required",
"table",
+ "_order",
],
)
@@ -289,6 +294,8 @@ def compare_sets(old_records, new_records):
"attachment",
]
for column in old_records:
+ if column["field"] == "_order":
+ continue
# we do not care about removed non stored function fields
if not column["stored"] and (column["isfunction"] or column["isrelated"]):
continue
@@ -311,6 +318,8 @@ def compare_sets(old_records, new_records):
]
)
for column in new_records:
+ if column["field"] == "_order":
+ continue
# we do not care about newly added non stored function fields
if not column["stored"] and (column["isfunction"] or column["isrelated"]):
continue
diff --git a/upgrade_analysis/models/upgrade_record.py b/upgrade_analysis/models/upgrade_record.py
index 445a90c97..c31b453ea 100644
--- a/upgrade_analysis/models/upgrade_record.py
+++ b/upgrade_analysis/models/upgrade_record.py
@@ -103,6 +103,7 @@ class UpgradeRecord(models.Model):
"hasdefault",
"table",
"_inherits",
+ "_order",
]
template = {x: False for x in keys}
diff --git a/upgrade_analysis/upgrade_log.py b/upgrade_analysis/upgrade_log.py
index 84547402f..b102d3afa 100644
--- a/upgrade_analysis/upgrade_log.py
+++ b/upgrade_analysis/upgrade_log.py
@@ -124,6 +124,7 @@ def log_model(model, local_registry):
model_registry = local_registry.setdefault(model._name, {})
if model._inherits:
model_registry["_inherits"] = {"_inherits": str(model._inherits)}
+ model_registry["_order"] = {"_order": model._order}
for k, v in model._fields.items():
properties = {
"type": typemap.get(v.type, v.type),
From 9ddb08c5db616d51a07fe3b082b6b5068d4517b9 Mon Sep 17 00:00:00 2001
From: mreficent
Date: Tue, 23 Mar 2021 17:30:49 +0100
Subject: [PATCH 25/67] [IMP] upgrade_analysis: make us of odoorpc/openupgrade
master
Includes minor fixes.
---
upgrade_analysis/blacklist.py | 2 +-
upgrade_analysis/compare.py | 10 +++++-----
upgrade_analysis/models/upgrade_analysis.py | 2 +-
upgrade_analysis/odoo_patch/odoo_patch.py | 2 +-
upgrade_analysis/wizards/upgrade_install_wizard.py | 5 -----
5 files changed, 8 insertions(+), 13 deletions(-)
diff --git a/upgrade_analysis/blacklist.py b/upgrade_analysis/blacklist.py
index 41943d6fb..ea5007219 100644
--- a/upgrade_analysis/blacklist.py
+++ b/upgrade_analysis/blacklist.py
@@ -2,7 +2,7 @@ BLACKLIST_MODULES = []
# the hw_* modules are not affected by a migration as they don't
# contain any ORM functionality, but they do start up threads that
-# delay the process and spit out annoying log messages continously.
+# delay the process and spit out annoying log messages continuously.
# We also don't want to analyze tests modules
BLACKLIST_MODULES_STARTS_WITH = ["hw_", "test_"]
diff --git a/upgrade_analysis/compare.py b/upgrade_analysis/compare.py
index 3222bcd1a..864277310 100644
--- a/upgrade_analysis/compare.py
+++ b/upgrade_analysis/compare.py
@@ -14,14 +14,14 @@ import copy
try:
from odoo.addons.openupgrade_scripts import apriori
except ImportError:
- from dataclasses import dataclass, field
+ from dataclasses import dataclass, field as dc_field
@dataclass
class NullApriori:
- renamed_modules: dict = field(default_factory=dict)
- merged_modules: dict = field(default_factory=dict)
- renamed_models: dict = field(default_factory=dict)
- merged_models: dict = field(default_factory=dict)
+ renamed_modules: dict = dc_field(default_factory=dict)
+ merged_modules: dict = dc_field(default_factory=dict)
+ renamed_models: dict = dc_field(default_factory=dict)
+ merged_models: dict = dc_field(default_factory=dict)
apriori = NullApriori()
diff --git a/upgrade_analysis/models/upgrade_analysis.py b/upgrade_analysis/models/upgrade_analysis.py
index e9eca7b59..15e08e7ca 100644
--- a/upgrade_analysis/models/upgrade_analysis.py
+++ b/upgrade_analysis/models/upgrade_analysis.py
@@ -430,7 +430,7 @@ class UpgradeAnalysis(models.Model):
raise ValidationError(
_(
"Unexpected root Element: %s in file: %s"
- % (tree.getroot(), xml_file)
+ % (root_node.getroot(), xml_file)
)
)
for node in root_node:
diff --git a/upgrade_analysis/odoo_patch/odoo_patch.py b/upgrade_analysis/odoo_patch/odoo_patch.py
index c1956f51f..f2ad6f73c 100644
--- a/upgrade_analysis/odoo_patch/odoo_patch.py
+++ b/upgrade_analysis/odoo_patch/odoo_patch.py
@@ -54,7 +54,7 @@ class OdooPatch(object):
if hasattr(method, "_original_method"):
setattr(cls.target, method_name, method._original_method)
else:
- _logger.warn(
+ _logger.warning(
"_original_method not found on method %s of class %s",
method_name,
cls.target,
diff --git a/upgrade_analysis/wizards/upgrade_install_wizard.py b/upgrade_analysis/wizards/upgrade_install_wizard.py
index 94cc3a7fe..da28996fa 100644
--- a/upgrade_analysis/wizards/upgrade_install_wizard.py
+++ b/upgrade_analysis/wizards/upgrade_install_wizard.py
@@ -17,10 +17,6 @@ class UpgradeInstallWizard(models.TransientModel):
_name = "upgrade.install.wizard"
_description = "Upgrade Install Wizard"
- name = fields.Char(
- default=_description,
- help="Workaround for https://github.com/OCA/odoorpc/issues/57",
- )
state = fields.Selection(
[("draft", "Draft"), ("done", "Done")], readonly=True, default="draft"
)
@@ -109,7 +105,6 @@ class UpgradeInstallWizard(models.TransientModel):
"type": "ir.actions.act_window",
"res_model": "upgrade.install.wizard",
"view_mode": "form",
- "view_type": "form",
"res_id": self.id,
"views": [(False, "form")],
"target": "new",
From ed7ea58ad7109e619e9f83b548dc2faff2055b39 Mon Sep 17 00:00:00 2001
From: OCA-git-bot
Date: Thu, 25 Mar 2021 16:36:56 +0000
Subject: [PATCH 26/67] upgrade_analysis 14.0.2.0.0
---
upgrade_analysis/__manifest__.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/upgrade_analysis/__manifest__.py b/upgrade_analysis/__manifest__.py
index 44c755efb..21705c6b8 100644
--- a/upgrade_analysis/__manifest__.py
+++ b/upgrade_analysis/__manifest__.py
@@ -5,7 +5,7 @@
"name": "Upgrade Analysis",
"summary": "performs a difference analysis between modules"
" installed on two different Odoo instances",
- "version": "14.0.1.0.0",
+ "version": "14.0.2.0.0",
"category": "Migration",
"author": "Therp BV, Opener B.V., GRAP, Odoo Community Association (OCA)",
"website": "https://github.com/OCA/server-tools",
From a88e1c4a96264bafac27c91d2f129f9be03c15cd Mon Sep 17 00:00:00 2001
From: mreficent
Date: Thu, 25 Mar 2021 02:58:29 +0100
Subject: [PATCH 27/67] [OU-MIG] upgrade_analysis: add migration scripts
Just in case.
---
.../migrations/14.0.1.0.0/pre-migrate.py | 27 +++++++++++++++++++
upgrade_analysis/readme/DESCRIPTION.rst | 2 ++
2 files changed, 29 insertions(+)
create mode 100644 upgrade_analysis/migrations/14.0.1.0.0/pre-migrate.py
diff --git a/upgrade_analysis/migrations/14.0.1.0.0/pre-migrate.py b/upgrade_analysis/migrations/14.0.1.0.0/pre-migrate.py
new file mode 100644
index 000000000..ee9409ec4
--- /dev/null
+++ b/upgrade_analysis/migrations/14.0.1.0.0/pre-migrate.py
@@ -0,0 +1,27 @@
+# Copyright 2021 ForgeFlow S.L. (https://www.forgeflow.com)
+# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
+from openupgradelib import openupgrade
+
+_model_renames = [
+ ("openupgrade.analysis.wizard", "upgrade.analysis"),
+ ("openupgrade.attribute", "upgrade.attribute"),
+ ("openupgrade.comparison.config", "upgrade.comparison.config"),
+ ("openupgrade.record", "upgrade.record"),
+ ("openupgrade.generate.records.wizard", "upgrade.generate.record.wizard"),
+ ("openupgrade.install.all.wizard", "upgrade.install.wizard"),
+]
+
+_table_renames = [
+ ("openupgrade_analysis_wizard", "upgrade_analysis"),
+ ("openupgrade_attribute", "upgrade_attribute"),
+ ("openupgrade_comparison_config", "upgrade_comparison_config"),
+ ("openupgrade_record", "upgrade_record"),
+ ("openupgrade_generate_records_wizard", "upgrade_generate_record_wizard"),
+ ("openupgrade_install_all_wizard", "upgrade_install_wizard"),
+]
+
+
+@openupgrade.migrate()
+def migrate(env, version):
+ openupgrade.rename_models(env.cr, _model_renames)
+ openupgrade.rename_tables(env.cr, _table_renames)
diff --git a/upgrade_analysis/readme/DESCRIPTION.rst b/upgrade_analysis/readme/DESCRIPTION.rst
index ff1a57292..1b12e675f 100644
--- a/upgrade_analysis/readme/DESCRIPTION.rst
+++ b/upgrade_analysis/readme/DESCRIPTION.rst
@@ -1 +1,3 @@
This module provides the tool to generate the database analysis files that indicate how the Odoo data model and module data have changed between two versions of Odoo. Database analysis files for the core modules are included in the OpenUpgrade distribution so as a migration script developer you will not usually need to use this tool yourself. If you do need to run your analysis of a custom set of modules, please refer to the documentation here: https://doc.therp.nl/openupgrade/analysis.html
+
+This module is just a tool, a continuation of the old openupgrade_records in OpenUpgrade in previous versions. It's not recommended to have this module in a production database.
From 53c3278f891e11f0ce17f70e5611b93b003a53ee Mon Sep 17 00:00:00 2001
From: OCA-git-bot
Date: Thu, 25 Mar 2021 18:21:03 +0000
Subject: [PATCH 28/67] [UPD] README.rst
---
upgrade_analysis/README.rst | 2 ++
upgrade_analysis/static/description/index.html | 1 +
2 files changed, 3 insertions(+)
diff --git a/upgrade_analysis/README.rst b/upgrade_analysis/README.rst
index 82b5e950e..c42ee1736 100644
--- a/upgrade_analysis/README.rst
+++ b/upgrade_analysis/README.rst
@@ -27,6 +27,8 @@ Upgrade Analysis
This module provides the tool to generate the database analysis files that indicate how the Odoo data model and module data have changed between two versions of Odoo. Database analysis files for the core modules are included in the OpenUpgrade distribution so as a migration script developer you will not usually need to use this tool yourself. If you do need to run your analysis of a custom set of modules, please refer to the documentation here: https://doc.therp.nl/openupgrade/analysis.html
+This module is just a tool, a continuation of the old openupgrade_records in OpenUpgrade in previous versions. It's not recommended to have this module in a production database.
+
**Table of contents**
.. contents::
diff --git a/upgrade_analysis/static/description/index.html b/upgrade_analysis/static/description/index.html
index 0da55055a..9d40422de 100644
--- a/upgrade_analysis/static/description/index.html
+++ b/upgrade_analysis/static/description/index.html
@@ -369,6 +369,7 @@ ul.auto-toc {
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->
This module provides the tool to generate the database analysis files that indicate how the Odoo data model and module data have changed between two versions of Odoo. Database analysis files for the core modules are included in the OpenUpgrade distribution so as a migration script developer you will not usually need to use this tool yourself. If you do need to run your analysis of a custom set of modules, please refer to the documentation here: https://doc.therp.nl/openupgrade/analysis.html
+This module is just a tool, a continuation of the old openupgrade_records in OpenUpgrade in previous versions. It’s not recommended to have this module in a production database.
Table of contents
From 41dcdbc45909385c29788b40eefe9398820f925d Mon Sep 17 00:00:00 2001
From: oca-travis
Date: Thu, 25 Mar 2021 18:41:29 +0000
Subject: [PATCH 29/67] [UPD] Update upgrade_analysis.pot
---
upgrade_analysis/i18n/upgrade_analysis.pot | 6 ------
1 file changed, 6 deletions(-)
diff --git a/upgrade_analysis/i18n/upgrade_analysis.pot b/upgrade_analysis/i18n/upgrade_analysis.pot
index 63f58e38a..a892cf2e9 100644
--- a/upgrade_analysis/i18n/upgrade_analysis.pot
+++ b/upgrade_analysis/i18n/upgrade_analysis.pot
@@ -302,7 +302,6 @@ msgstr ""
#. module: upgrade_analysis
#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_attribute__name
#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_comparison_config__name
-#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_install_wizard__name
#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_record__name
msgid "Name"
msgstr ""
@@ -477,11 +476,6 @@ msgstr ""
msgid "Version"
msgstr ""
-#. module: upgrade_analysis
-#: model:ir.model.fields,help:upgrade_analysis.field_upgrade_install_wizard__name
-msgid "Workaround for https://github.com/OCA/odoorpc/issues/57"
-msgstr ""
-
#. module: upgrade_analysis
#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_analysis__write_files
msgid "Write Files"
From dc9a87fffde276d1b75949142ef6006f6692d766 Mon Sep 17 00:00:00 2001
From: OCA-git-bot
Date: Thu, 25 Mar 2021 18:49:31 +0000
Subject: [PATCH 30/67] upgrade_analysis 14.0.2.0.1
---
upgrade_analysis/__manifest__.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/upgrade_analysis/__manifest__.py b/upgrade_analysis/__manifest__.py
index 21705c6b8..62d019b39 100644
--- a/upgrade_analysis/__manifest__.py
+++ b/upgrade_analysis/__manifest__.py
@@ -5,7 +5,7 @@
"name": "Upgrade Analysis",
"summary": "performs a difference analysis between modules"
" installed on two different Odoo instances",
- "version": "14.0.2.0.0",
+ "version": "14.0.2.0.1",
"category": "Migration",
"author": "Therp BV, Opener B.V., GRAP, Odoo Community Association (OCA)",
"website": "https://github.com/OCA/server-tools",
From 7de18509c60d9b8fd8e4a8ebafae4c1765b288f9 Mon Sep 17 00:00:00 2001
From: mreficent
Date: Sat, 27 Mar 2021 00:44:50 +0100
Subject: [PATCH 31/67] [FIX] upgrade_analysis: fix methods related to noupdate
data
---
upgrade_analysis/__manifest__.py | 3 +-
upgrade_analysis/models/upgrade_analysis.py | 30 +++++++++++--------
upgrade_analysis/models/upgrade_record.py | 9 +++---
upgrade_analysis/readme/CONTRIBUTORS.rst | 2 +-
.../static/description/index.html | 2 +-
5 files changed, 25 insertions(+), 21 deletions(-)
diff --git a/upgrade_analysis/__manifest__.py b/upgrade_analysis/__manifest__.py
index 62d019b39..ee70913e1 100644
--- a/upgrade_analysis/__manifest__.py
+++ b/upgrade_analysis/__manifest__.py
@@ -3,7 +3,7 @@
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
{
"name": "Upgrade Analysis",
- "summary": "performs a difference analysis between modules"
+ "summary": "Performs a difference analysis between modules"
" installed on two different Odoo instances",
"version": "14.0.2.0.1",
"category": "Migration",
@@ -19,6 +19,7 @@
"wizards/view_upgrade_install_wizard.xml",
],
"installable": True,
+ "depends": ["base"],
"external_dependencies": {
"python": ["dataclasses", "odoorpc", "openupgradelib"],
},
diff --git a/upgrade_analysis/models/upgrade_analysis.py b/upgrade_analysis/models/upgrade_analysis.py
index 15e08e7ca..26038249f 100644
--- a/upgrade_analysis/models/upgrade_analysis.py
+++ b/upgrade_analysis/models/upgrade_analysis.py
@@ -1,6 +1,6 @@
# Copyright 2011-2015 Therp BV
# Copyright 2016-2020 Opener B.V.
-# Copyright 2019 Eficent
+# Copyright 2019 ForgeFlow
# Copyright 2020 GRAP
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
# flake8: noqa: C901
@@ -19,9 +19,10 @@ from odoo.tools.convert import nodeattr2bool
from odoo.tools.translate import _
try:
- from odoo.addons.openupgrade_scripts.apriori import renamed_modules
+ from odoo.addons.openupgrade_scripts.apriori import merged_modules, renamed_modules
except ImportError:
renamed_modules = {}
+ merged_modules = {}
from .. import compare
@@ -73,7 +74,7 @@ class UpgradeAnalysis(models.Model):
def _get_remote_model(self, connection, model):
self.ensure_one()
if model == "record":
- if float(self.config_id.version) < 14:
+ if float(self.config_id.version) < 14.0:
return connection.env["openupgrade.record"]
else:
return connection.env["upgrade.record"]
@@ -407,30 +408,31 @@ class UpgradeAnalysis(models.Model):
target_dict[xml_id] = record
@classmethod
- def _parse_files(self, xml_files, module_name):
+ def _parse_paths(self, xml_paths, module_name):
records_update = {}
records_noupdate = {}
parser = etree.XMLParser(
remove_blank_text=True,
strip_cdata=False,
)
- for xml_file in xml_files:
+ for xml_path in xml_paths:
try:
# This is for a final correct pretty print
# Ref.: https://stackoverflow.com/a/7904066
# Also don't strip CDATA tags as needed for HTML content
- root_node = etree.fromstring(xml_file.encode("utf-8"), parser=parser)
+ tree = etree.parse(xml_path, parser=parser)
except etree.XMLSyntaxError:
continue
# Support xml files with root Element either odoo or openerp
# Condition: each xml file should have only one root element
# {, or —rarely— };
+ root_node = tree.getroot()
root_node_noupdate = nodeattr2bool(root_node, "noupdate", False)
if root_node.tag not in ("openerp", "odoo", "data"):
raise ValidationError(
_(
"Unexpected root Element: %s in file: %s"
- % (root_node.getroot(), xml_file)
+ % (tree.getroot(), xml_path)
)
)
for node in root_node:
@@ -460,15 +462,17 @@ class UpgradeAnalysis(models.Model):
local_record_obj = self.env["upgrade.record"]
local_modules = local_record_obj.list_modules()
for remote_module in remote_record_obj.list_modules():
- local_module = renamed_modules.get(remote_module, remote_module)
+ local_module = renamed_modules.get(
+ remote_module, merged_modules.get(remote_module, remote_module)
+ )
if local_module not in local_modules:
continue
- remote_files = remote_record_obj.get_xml_records(remote_module)
- local_files = local_record_obj.get_xml_records(local_module)
- remote_update, remote_noupdate = self._parse_files(
- remote_files, remote_module
+ remote_paths = remote_record_obj.get_xml_records(remote_module)
+ local_paths = local_record_obj.get_xml_records(local_module)
+ remote_update, remote_noupdate = self._parse_paths(
+ remote_paths, remote_module
)
- local_update, local_noupdate = self._parse_files(local_files, local_module)
+ local_update, local_noupdate = self._parse_paths(local_paths, local_module)
diff = self._get_xml_diff(
remote_update, remote_noupdate, local_update, local_noupdate
)
diff --git a/upgrade_analysis/models/upgrade_record.py b/upgrade_analysis/models/upgrade_record.py
index c31b453ea..fdcd0e707 100644
--- a/upgrade_analysis/models/upgrade_record.py
+++ b/upgrade_analysis/models/upgrade_record.py
@@ -1,6 +1,6 @@
# Copyright 2011-2015 Therp BV
# Copyright 2016-2020 Opener B.V.
-# Copyright 2019 Eficent
+# Copyright 2019 ForgeFlow
# Copyright 2020 GRAP
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
@@ -159,7 +159,7 @@ class UpgradeRecord(models.Model):
# The order of the keys are important.
# Load files in the same order as in
# module/loading.py:load_module_graph
- files = []
+ paths = []
for key in ["init_xml", "update_xml", "data"]:
if not manifest.get(key):
continue
@@ -167,6 +167,5 @@ class UpgradeRecord(models.Model):
if not xml_file.lower().endswith(".xml"):
continue
parts = xml_file.split("/")
- with open(os.path.join(addon_dir, *parts), "r") as xml_handle:
- files.append(xml_handle.read())
- return files
+ paths.append(os.path.join(addon_dir, *parts))
+ return paths
diff --git a/upgrade_analysis/readme/CONTRIBUTORS.rst b/upgrade_analysis/readme/CONTRIBUTORS.rst
index 5de0e93e5..b8c8505e9 100644
--- a/upgrade_analysis/readme/CONTRIBUTORS.rst
+++ b/upgrade_analysis/readme/CONTRIBUTORS.rst
@@ -3,5 +3,5 @@
* Pedro M. Baeza
* Ferdinand Gassauer
* Florent Xicluna
-* Miquel Raïch
+* Miquel Raïch
* Sylvain LE GAL
diff --git a/upgrade_analysis/static/description/index.html b/upgrade_analysis/static/description/index.html
index 9d40422de..6a1087c8f 100644
--- a/upgrade_analysis/static/description/index.html
+++ b/upgrade_analysis/static/description/index.html
@@ -416,7 +416,7 @@ If you spotted it first, help us smashing it by providing a detailed and welcome
Pedro M. Baeza <pedro.baeza@gmail.com >
Ferdinand Gassauer <gass@cc-l-12.chircar.at >
Florent Xicluna <florent.xicluna@gmail.com >
-Miquel Raïch <miquel.raich@eficent.com >
+Miquel Raïch <miquel.raich@forgeflow.com >
Sylvain LE GAL <https://twitter.com/legalsylvain >
From 989b37924e6c16377ef386533f2e96a01f067ceb Mon Sep 17 00:00:00 2001
From: mreficent
Date: Sun, 28 Mar 2021 12:51:41 +0200
Subject: [PATCH 32/67] [FIX] upgrade_analysis: truncate upgrade records before
generating new ones
---
upgrade_analysis/wizards/upgrade_generate_record_wizard.py | 3 +++
1 file changed, 3 insertions(+)
diff --git a/upgrade_analysis/wizards/upgrade_generate_record_wizard.py b/upgrade_analysis/wizards/upgrade_generate_record_wizard.py
index ace540646..3a766b1b1 100644
--- a/upgrade_analysis/wizards/upgrade_generate_record_wizard.py
+++ b/upgrade_analysis/wizards/upgrade_generate_record_wizard.py
@@ -25,6 +25,9 @@ class GenerateWizard(models.TransientModel):
TODO: update module list and versions, then update all modules?"""
+ # Truncate the records table
+ self.env.cr.execute("TRUNCATE upgrade_attribute, upgrade_record;")
+
# Check of all the modules are correctly installed
modules = self.env["ir.module.module"].search(
[("state", "in", ["to install", "to upgrade"])]
From 423732a416a8e24924c0fa6538832bfd7533c2b0 Mon Sep 17 00:00:00 2001
From: OCA-git-bot
Date: Mon, 29 Mar 2021 11:47:58 +0000
Subject: [PATCH 33/67] [UPD] README.rst
---
upgrade_analysis/README.rst | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/upgrade_analysis/README.rst b/upgrade_analysis/README.rst
index c42ee1736..4fcf7f0cf 100644
--- a/upgrade_analysis/README.rst
+++ b/upgrade_analysis/README.rst
@@ -68,7 +68,7 @@ Contributors
* Pedro M. Baeza
* Ferdinand Gassauer
* Florent Xicluna
-* Miquel Raïch
+* Miquel Raïch
* Sylvain LE GAL
Maintainers
From 94013a71604387dc4c3220bc07e67aab0ad109bc Mon Sep 17 00:00:00 2001
From: OCA-git-bot
Date: Mon, 29 Mar 2021 11:47:58 +0000
Subject: [PATCH 34/67] upgrade_analysis 14.0.2.1.0
---
upgrade_analysis/__manifest__.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/upgrade_analysis/__manifest__.py b/upgrade_analysis/__manifest__.py
index ee70913e1..5c3aa3444 100644
--- a/upgrade_analysis/__manifest__.py
+++ b/upgrade_analysis/__manifest__.py
@@ -5,7 +5,7 @@
"name": "Upgrade Analysis",
"summary": "Performs a difference analysis between modules"
" installed on two different Odoo instances",
- "version": "14.0.2.0.1",
+ "version": "14.0.2.1.0",
"category": "Migration",
"author": "Therp BV, Opener B.V., GRAP, Odoo Community Association (OCA)",
"website": "https://github.com/OCA/server-tools",
From c919a2e77ba5b6b8415ccc91b269d8224b9c0a28 Mon Sep 17 00:00:00 2001
From: mreficent
Date: Wed, 21 Apr 2021 17:40:16 +0200
Subject: [PATCH 35/67] [FIX] upgrade_analysis: merged modules affecting
noupdate files
Due to https://github.com/OCA/server-tools/pull/2057, noupdate data now considers merged modules. But the fix was incomplete, as the diff files between merged modules and local_module were rewritting already generated diff between original remote_module and local_module.
---
upgrade_analysis/models/upgrade_analysis.py | 30 ++++++++++++++-------
1 file changed, 20 insertions(+), 10 deletions(-)
diff --git a/upgrade_analysis/models/upgrade_analysis.py b/upgrade_analysis/models/upgrade_analysis.py
index 26038249f..2c67ac051 100644
--- a/upgrade_analysis/models/upgrade_analysis.py
+++ b/upgrade_analysis/models/upgrade_analysis.py
@@ -368,7 +368,7 @@ class UpgradeAnalysis(models.Model):
if "name" in element.attrib:
query = "./{}[@name='{}']".format(element.tag, element.attrib["name"])
else:
- # query = "./%s" % element.tag
+ # query = "./{}".format(element.tag)
continue
for existing in target.xpath(query):
target.remove(existing)
@@ -461,17 +461,27 @@ class UpgradeAnalysis(models.Model):
remote_record_obj = self._get_remote_model(connection, "record")
local_record_obj = self.env["upgrade.record"]
local_modules = local_record_obj.list_modules()
- for remote_module in remote_record_obj.list_modules():
- local_module = renamed_modules.get(
- remote_module, merged_modules.get(remote_module, remote_module)
- )
- if local_module not in local_modules:
+ all_remote_modules = remote_record_obj.list_modules()
+ for local_module in local_modules:
+ remote_paths = []
+ remote_modules = []
+ remote_update, remote_noupdate = {}, {}
+ for remote_module in all_remote_modules:
+ if local_module == renamed_modules.get(
+ remote_module, merged_modules.get(remote_module, remote_module)
+ ):
+ remote_paths.extend(
+ remote_record_obj.get_xml_records(remote_module)
+ )
+ remote_modules.append(remote_module)
+ add_remote_update, add_remote_noupdate = self._parse_paths(
+ remote_paths, remote_module
+ )
+ remote_update.update(add_remote_update)
+ remote_noupdate.update(add_remote_noupdate)
+ if not remote_modules:
continue
- remote_paths = remote_record_obj.get_xml_records(remote_module)
local_paths = local_record_obj.get_xml_records(local_module)
- remote_update, remote_noupdate = self._parse_paths(
- remote_paths, remote_module
- )
local_update, local_noupdate = self._parse_paths(local_paths, local_module)
diff = self._get_xml_diff(
remote_update, remote_noupdate, local_update, local_noupdate
From 8d511cee62100302bf09dc3bd23ebb01e869127a Mon Sep 17 00:00:00 2001
From: mreficent
Date: Wed, 21 Apr 2021 18:37:36 +0200
Subject: [PATCH 36/67] [FIX] upgrade_analysis: revert to 'files' approach
instead of 'paths'
---
upgrade_analysis/models/upgrade_analysis.py | 21 ++++++++++-----------
upgrade_analysis/models/upgrade_record.py | 17 ++++++++++++++---
2 files changed, 24 insertions(+), 14 deletions(-)
diff --git a/upgrade_analysis/models/upgrade_analysis.py b/upgrade_analysis/models/upgrade_analysis.py
index 2c67ac051..fcdd48774 100644
--- a/upgrade_analysis/models/upgrade_analysis.py
+++ b/upgrade_analysis/models/upgrade_analysis.py
@@ -408,31 +408,30 @@ class UpgradeAnalysis(models.Model):
target_dict[xml_id] = record
@classmethod
- def _parse_paths(self, xml_paths, module_name):
+ def _parse_files(self, xml_files, module_name):
records_update = {}
records_noupdate = {}
parser = etree.XMLParser(
remove_blank_text=True,
strip_cdata=False,
)
- for xml_path in xml_paths:
+ for xml_file in xml_files:
try:
# This is for a final correct pretty print
# Ref.: https://stackoverflow.com/a/7904066
# Also don't strip CDATA tags as needed for HTML content
- tree = etree.parse(xml_path, parser=parser)
+ root_node = etree.fromstring(xml_file.encode("utf-8"), parser=parser)
except etree.XMLSyntaxError:
continue
# Support xml files with root Element either odoo or openerp
# Condition: each xml file should have only one root element
# {, or —rarely— };
- root_node = tree.getroot()
root_node_noupdate = nodeattr2bool(root_node, "noupdate", False)
if root_node.tag not in ("openerp", "odoo", "data"):
raise ValidationError(
_(
"Unexpected root Element: %s in file: %s"
- % (tree.getroot(), xml_path)
+ % (root_node.getroot(), xml_file)
)
)
for node in root_node:
@@ -463,26 +462,26 @@ class UpgradeAnalysis(models.Model):
local_modules = local_record_obj.list_modules()
all_remote_modules = remote_record_obj.list_modules()
for local_module in local_modules:
- remote_paths = []
+ remote_files = []
remote_modules = []
remote_update, remote_noupdate = {}, {}
for remote_module in all_remote_modules:
if local_module == renamed_modules.get(
remote_module, merged_modules.get(remote_module, remote_module)
):
- remote_paths.extend(
+ remote_files.extend(
remote_record_obj.get_xml_records(remote_module)
)
remote_modules.append(remote_module)
- add_remote_update, add_remote_noupdate = self._parse_paths(
- remote_paths, remote_module
+ add_remote_update, add_remote_noupdate = self._parse_files(
+ remote_files, remote_module
)
remote_update.update(add_remote_update)
remote_noupdate.update(add_remote_noupdate)
if not remote_modules:
continue
- local_paths = local_record_obj.get_xml_records(local_module)
- local_update, local_noupdate = self._parse_paths(local_paths, local_module)
+ local_files = local_record_obj.get_xml_records(local_module)
+ local_update, local_noupdate = self._parse_files(local_files, local_module)
diff = self._get_xml_diff(
remote_update, remote_noupdate, local_update, local_noupdate
)
diff --git a/upgrade_analysis/models/upgrade_record.py b/upgrade_analysis/models/upgrade_record.py
index fdcd0e707..f62c7ca3e 100644
--- a/upgrade_analysis/models/upgrade_record.py
+++ b/upgrade_analysis/models/upgrade_record.py
@@ -5,6 +5,7 @@
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
import ast
+import logging
import os
from odoo import api, fields, models
@@ -12,6 +13,8 @@ from odoo.exceptions import ValidationError
from odoo.modules.module import MANIFEST_NAMES, get_module_path
from odoo.tools.translate import _
+_logger = logging.getLogger(__name__)
+
class UpgradeRecord(models.Model):
_name = "upgrade.record"
@@ -159,7 +162,7 @@ class UpgradeRecord(models.Model):
# The order of the keys are important.
# Load files in the same order as in
# module/loading.py:load_module_graph
- paths = []
+ files = []
for key in ["init_xml", "update_xml", "data"]:
if not manifest.get(key):
continue
@@ -167,5 +170,13 @@ class UpgradeRecord(models.Model):
if not xml_file.lower().endswith(".xml"):
continue
parts = xml_file.split("/")
- paths.append(os.path.join(addon_dir, *parts))
- return paths
+ try:
+ with open(os.path.join(addon_dir, *parts), "r") as xml_handle:
+ files.append(xml_handle.read())
+ except UnicodeDecodeError:
+ _logger.warning(
+ "Encoding error: Unable to read %s",
+ os.path.join(addon_dir, *parts),
+ )
+ continue
+ return files
From 9d87f8b82d29ae4755f1bdbb2c5b95c380c6d02f Mon Sep 17 00:00:00 2001
From: oca-travis
Date: Fri, 30 Apr 2021 17:45:58 +0000
Subject: [PATCH 37/67] [UPD] Update upgrade_analysis.pot
---
upgrade_analysis/i18n/upgrade_analysis.pot | 11 +++++++++++
1 file changed, 11 insertions(+)
diff --git a/upgrade_analysis/i18n/upgrade_analysis.pot b/upgrade_analysis/i18n/upgrade_analysis.pot
index a892cf2e9..fb0550c0a 100644
--- a/upgrade_analysis/i18n/upgrade_analysis.pot
+++ b/upgrade_analysis/i18n/upgrade_analysis.pot
@@ -364,6 +364,17 @@ msgid ""
"modifies an attribute of an existing field, set to Modify."
msgstr ""
+#. module: upgrade_analysis
+#: model:ir.model.fields,field_description:upgrade_analysis.field_ir_module_module__smart_search
+#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_analysis__smart_search
+#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_attribute__smart_search
+#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_comparison_config__smart_search
+#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_generate_record_wizard__smart_search
+#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_install_wizard__smart_search
+#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_record__smart_search
+msgid "Smart Search"
+msgstr ""
+
#. module: upgrade_analysis
#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_analysis__state
#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_generate_record_wizard__state
From 402c27f3be9eda8810d03e95301bc119c1c38c65 Mon Sep 17 00:00:00 2001
From: Yves Le Doeuff
Date: Fri, 14 May 2021 17:03:50 +0000
Subject: [PATCH 38/67] Added translation using Weblate (French)
---
upgrade_analysis/i18n/fr.po | 527 ++++++++++++++++++++++++++++++++++++
1 file changed, 527 insertions(+)
create mode 100644 upgrade_analysis/i18n/fr.po
diff --git a/upgrade_analysis/i18n/fr.po b/upgrade_analysis/i18n/fr.po
new file mode 100644
index 000000000..6ab2f70f6
--- /dev/null
+++ b/upgrade_analysis/i18n/fr.po
@@ -0,0 +1,527 @@
+# Translation of Odoo Server.
+# This file contains the translation of the following modules:
+# * upgrade_analysis
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: Odoo Server 14.0\n"
+"Report-Msgid-Bugs-To: \n"
+"Last-Translator: Automatically generated\n"
+"Language-Team: none\n"
+"Language: fr\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: \n"
+"Plural-Forms: nplurals=2; plural=n > 1;\n"
+
+#. module: upgrade_analysis
+#: model_terms:ir.ui.view,arch_db:upgrade_analysis.view_upgrade_install_wizard_form
+msgid "All Modules"
+msgstr ""
+
+#. module: upgrade_analysis
+#: model_terms:ir.ui.view,arch_db:upgrade_analysis.view_upgrade_install_wizard_form
+msgid "All OCA Modules"
+msgstr ""
+
+#. module: upgrade_analysis
+#: model_terms:ir.ui.view,arch_db:upgrade_analysis.view_upgrade_install_wizard_form
+msgid "All Odoo SA Modules"
+msgstr ""
+
+#. module: upgrade_analysis
+#: model_terms:ir.ui.view,arch_db:upgrade_analysis.view_upgrade_install_wizard_form
+msgid "All Other Modules"
+msgstr ""
+
+#. module: upgrade_analysis
+#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_comparison_config__analysis_ids
+#: model_terms:ir.ui.view,arch_db:upgrade_analysis.view_upgrade_comparison_config_form
+msgid "Analyses"
+msgstr ""
+
+#. module: upgrade_analysis
+#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_analysis__analysis_date
+msgid "Analysis Date"
+msgstr ""
+
+#. module: upgrade_analysis
+#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_comparison_config__analysis_qty
+msgid "Analysis Qty"
+msgstr ""
+
+#. module: upgrade_analysis
+#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_record__attribute_ids
+msgid "Attribute"
+msgstr ""
+
+#. module: upgrade_analysis
+#: model_terms:ir.ui.view,arch_db:upgrade_analysis.view_upgrade_record_form
+msgid "Attributes"
+msgstr ""
+
+#. module: upgrade_analysis
+#: code:addons/upgrade_analysis/wizards/upgrade_generate_record_wizard.py:0
+#, python-format
+msgid "Cannot seem to install or upgrade modules %s"
+msgstr ""
+
+#. module: upgrade_analysis
+#: model_terms:ir.ui.view,arch_db:upgrade_analysis.view_upgrade_install_wizard_form
+msgid "Clear the list"
+msgstr ""
+
+#. module: upgrade_analysis
+#: model_terms:ir.ui.view,arch_db:upgrade_analysis.view_upgrade_generate_record_wizard_form
+#: model_terms:ir.ui.view,arch_db:upgrade_analysis.view_upgrade_install_wizard_form
+msgid "Close"
+msgstr ""
+
+#. module: upgrade_analysis
+#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_analysis__config_id
+msgid "Comparison Config"
+msgstr ""
+
+#. module: upgrade_analysis
+#: model:ir.ui.menu,name:upgrade_analysis.menu_upgrade_comparison_config
+msgid "Comparison Configurations"
+msgstr ""
+
+#. module: upgrade_analysis
+#: code:addons/upgrade_analysis/models/upgrade_comparison_config.py:0
+#, python-format
+msgid ""
+"Connection failed.\n"
+"\n"
+"DETAIL: %s"
+msgstr ""
+
+#. module: upgrade_analysis
+#: model_terms:ir.ui.view,arch_db:upgrade_analysis.view_upgrade_generate_record_wizard_form
+msgid "Continue"
+msgstr ""
+
+#. module: upgrade_analysis
+#: code:addons/upgrade_analysis/models/upgrade_comparison_config.py:0
+#, python-format
+msgid "Could not connect the Odoo server at %s:%s"
+msgstr ""
+
+#. module: upgrade_analysis
+#: model:ir.model.fields.selection,name:upgrade_analysis.selection__upgrade_record__mode__create
+msgid "Create"
+msgstr ""
+
+#. module: upgrade_analysis
+#: model_terms:ir.ui.view,arch_db:upgrade_analysis.view_upgrade_record_search
+msgid "Create Mode"
+msgstr ""
+
+#. module: upgrade_analysis
+#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_analysis__create_uid
+#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_attribute__create_uid
+#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_comparison_config__create_uid
+#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_generate_record_wizard__create_uid
+#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_install_wizard__create_uid
+#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_record__create_uid
+msgid "Created by"
+msgstr ""
+
+#. module: upgrade_analysis
+#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_analysis__create_date
+#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_attribute__create_date
+#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_comparison_config__create_date
+#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_generate_record_wizard__create_date
+#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_install_wizard__create_date
+#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_record__create_date
+msgid "Created on"
+msgstr ""
+
+#. module: upgrade_analysis
+#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_comparison_config__database
+msgid "Database"
+msgstr ""
+
+#. module: upgrade_analysis
+#: model:ir.model.fields,field_description:upgrade_analysis.field_ir_module_module__display_name
+#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_analysis__display_name
+#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_attribute__display_name
+#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_comparison_config__display_name
+#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_generate_record_wizard__display_name
+#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_install_wizard__display_name
+#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_record__display_name
+msgid "Display Name"
+msgstr ""
+
+#. module: upgrade_analysis
+#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_record__domain
+msgid "Domain"
+msgstr ""
+
+#. module: upgrade_analysis
+#: model:ir.model.fields.selection,name:upgrade_analysis.selection__upgrade_analysis__state__done
+#: model:ir.model.fields.selection,name:upgrade_analysis.selection__upgrade_generate_record_wizard__state__done
+#: model:ir.model.fields.selection,name:upgrade_analysis.selection__upgrade_install_wizard__state__done
+msgid "Done"
+msgstr ""
+
+#. module: upgrade_analysis
+#: model:ir.model.fields.selection,name:upgrade_analysis.selection__upgrade_generate_record_wizard__state__draft
+#: model:ir.model.fields.selection,name:upgrade_analysis.selection__upgrade_install_wizard__state__draft
+msgid "Draft"
+msgstr ""
+
+#. module: upgrade_analysis
+#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_record__field
+#: model:ir.model.fields.selection,name:upgrade_analysis.selection__upgrade_record__type__field
+msgid "Field"
+msgstr ""
+
+#. module: upgrade_analysis
+#: model:ir.actions.act_window,name:upgrade_analysis.action_upgrade_generate_record_wizard
+#: model:ir.ui.menu,name:upgrade_analysis.menu_upgrade_generate_record
+msgid "Generate Records Wizard"
+msgstr ""
+
+#. module: upgrade_analysis
+#: model:ir.model.fields,field_description:upgrade_analysis.field_ir_module_module__id
+#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_analysis__id
+#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_attribute__id
+#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_comparison_config__id
+#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_generate_record_wizard__id
+#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_install_wizard__id
+#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_record__id
+msgid "ID"
+msgstr ""
+
+#. module: upgrade_analysis
+#: model_terms:ir.ui.view,arch_db:upgrade_analysis.view_upgrade_install_wizard_form
+msgid "Install Modules"
+msgstr ""
+
+#. module: upgrade_analysis
+#: model:ir.actions.act_window,name:upgrade_analysis.action_upgrade_install_wizard
+#: model:ir.ui.menu,name:upgrade_analysis.menu_upgrade_install
+msgid "Install Modules Wizard"
+msgstr ""
+
+#. module: upgrade_analysis
+#: model:ir.model.fields,field_description:upgrade_analysis.field_ir_module_module__is_oca_module
+msgid "Is Oca Module"
+msgstr ""
+
+#. module: upgrade_analysis
+#: model:ir.model.fields,field_description:upgrade_analysis.field_ir_module_module__is_odoo_module
+msgid "Is Odoo Module"
+msgstr ""
+
+#. module: upgrade_analysis
+#: model:ir.model.fields,field_description:upgrade_analysis.field_ir_module_module____last_update
+#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_analysis____last_update
+#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_attribute____last_update
+#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_comparison_config____last_update
+#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_generate_record_wizard____last_update
+#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_install_wizard____last_update
+#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_record____last_update
+msgid "Last Modified on"
+msgstr ""
+
+#. module: upgrade_analysis
+#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_analysis__write_uid
+#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_attribute__write_uid
+#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_comparison_config__write_uid
+#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_generate_record_wizard__write_uid
+#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_install_wizard__write_uid
+#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_record__write_uid
+msgid "Last Updated by"
+msgstr ""
+
+#. module: upgrade_analysis
+#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_analysis__write_date
+#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_attribute__write_date
+#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_comparison_config__write_date
+#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_generate_record_wizard__write_date
+#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_install_wizard__write_date
+#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_record__write_date
+msgid "Last Updated on"
+msgstr ""
+
+#. module: upgrade_analysis
+#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_analysis__log
+#: model_terms:ir.ui.view,arch_db:upgrade_analysis.view_upgrade_analysis_form
+msgid "Log"
+msgstr ""
+
+#. module: upgrade_analysis
+#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_record__mode
+msgid "Mode"
+msgstr ""
+
+#. module: upgrade_analysis
+#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_record__model
+#: model:ir.model.fields.selection,name:upgrade_analysis.selection__upgrade_record__type__model
+msgid "Model"
+msgstr ""
+
+#. module: upgrade_analysis
+#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_record__model_original_module
+msgid "Model Original Module"
+msgstr ""
+
+#. module: upgrade_analysis
+#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_record__model_type
+msgid "Model Type"
+msgstr ""
+
+#. module: upgrade_analysis
+#: model:ir.model.fields.selection,name:upgrade_analysis.selection__upgrade_record__mode__modify
+msgid "Modify"
+msgstr ""
+
+#. module: upgrade_analysis
+#: model_terms:ir.ui.view,arch_db:upgrade_analysis.view_upgrade_record_search
+msgid "Modify Mode"
+msgstr ""
+
+#. module: upgrade_analysis
+#: model:ir.model,name:upgrade_analysis.model_ir_module_module
+#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_install_wizard__module_ids
+#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_record__module
+msgid "Module"
+msgstr ""
+
+#. module: upgrade_analysis
+#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_install_wizard__module_qty
+msgid "Modules Quantity"
+msgstr ""
+
+#. module: upgrade_analysis
+#: model_terms:ir.ui.view,arch_db:upgrade_analysis.view_upgrade_generate_record_wizard_form
+msgid "Modules initialized and record created"
+msgstr ""
+
+#. module: upgrade_analysis
+#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_attribute__name
+#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_comparison_config__name
+#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_record__name
+msgid "Name"
+msgstr ""
+
+#. module: upgrade_analysis
+#: model_terms:ir.ui.view,arch_db:upgrade_analysis.view_upgrade_comparison_config_form
+msgid "New Analysis"
+msgstr ""
+
+#. module: upgrade_analysis
+#: code:addons/upgrade_analysis/models/upgrade_record.py:0
+#, python-format
+msgid "No manifest found in %s"
+msgstr ""
+
+#. module: upgrade_analysis
+#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_record__noupdate
+msgid "Noupdate"
+msgstr ""
+
+#. module: upgrade_analysis
+#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_comparison_config__password
+msgid "Password"
+msgstr ""
+
+#. module: upgrade_analysis
+#: model_terms:ir.ui.view,arch_db:upgrade_analysis.view_upgrade_analysis_form
+msgid "Perform Analysis"
+msgstr ""
+
+#. module: upgrade_analysis
+#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_comparison_config__port
+msgid "Port"
+msgstr ""
+
+#. module: upgrade_analysis
+#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_record__prefix
+msgid "Prefix"
+msgstr ""
+
+#. module: upgrade_analysis
+#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_attribute__record_id
+msgid "Record"
+msgstr ""
+
+#. module: upgrade_analysis
+#: model:ir.ui.menu,name:upgrade_analysis.menu_upgrade_records
+msgid "Records"
+msgstr ""
+
+#. module: upgrade_analysis
+#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_comparison_config__server
+msgid "Server"
+msgstr ""
+
+#. module: upgrade_analysis
+#: model:ir.model.fields,help:upgrade_analysis.field_upgrade_record__mode
+msgid ""
+"Set to Create if a field is newly created in this module. If this module "
+"modifies an attribute of an existing field, set to Modify."
+msgstr ""
+
+#. module: upgrade_analysis
+#: model:ir.model.fields,field_description:upgrade_analysis.field_ir_module_module__smart_search
+#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_analysis__smart_search
+#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_attribute__smart_search
+#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_comparison_config__smart_search
+#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_generate_record_wizard__smart_search
+#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_install_wizard__smart_search
+#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_record__smart_search
+msgid "Smart Search"
+msgstr ""
+
+#. module: upgrade_analysis
+#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_analysis__state
+#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_generate_record_wizard__state
+#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_install_wizard__state
+msgid "State"
+msgstr ""
+
+#. module: upgrade_analysis
+#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_record__suffix
+msgid "Suffix"
+msgstr ""
+
+#. module: upgrade_analysis
+#: model_terms:ir.ui.view,arch_db:upgrade_analysis.view_upgrade_comparison_config_form
+msgid "Test Connection"
+msgstr ""
+
+#. module: upgrade_analysis
+#: model:ir.model.fields,help:upgrade_analysis.field_upgrade_analysis__upgrade_path
+msgid ""
+"The base file path to save the analyse files of Odoo modules. Taken from "
+"Odoo's --upgrade-path command line option or the 'scripts' subdirectory in "
+"the openupgrade_scripts addon."
+msgstr ""
+
+#. module: upgrade_analysis
+#: model_terms:ir.ui.view,arch_db:upgrade_analysis.view_upgrade_install_wizard_form
+msgid "The modules have been installed successfuly"
+msgstr ""
+
+#. module: upgrade_analysis
+#: model_terms:ir.ui.view,arch_db:upgrade_analysis.view_upgrade_install_wizard_form
+msgid ""
+"This will install the selected modules on the database. Do not continue if "
+"you use this database in production."
+msgstr ""
+
+#. module: upgrade_analysis
+#: model_terms:ir.ui.view,arch_db:upgrade_analysis.view_upgrade_generate_record_wizard_form
+msgid ""
+"This will reinitialize all the modules installed on this database. Do not "
+"continue if you use this database in production."
+msgstr ""
+
+#. module: upgrade_analysis
+#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_record__type
+msgid "Type"
+msgstr ""
+
+#. module: upgrade_analysis
+#: code:addons/upgrade_analysis/models/upgrade_analysis.py:0
+#, python-format
+msgid "Unexpected root Element: %s in file: %s"
+msgstr ""
+
+#. module: upgrade_analysis
+#: model:ir.actions.act_window,name:upgrade_analysis.action_upgrade_analysis_tree
+#: model:ir.model,name:upgrade_analysis.model_upgrade_analysis
+#: model:ir.ui.menu,name:upgrade_analysis.menu_upgrade_analysis
+msgid "Upgrade Analyses"
+msgstr ""
+
+#. module: upgrade_analysis
+#: model:ir.ui.menu,name:upgrade_analysis.menu_upgrade
+msgid "Upgrade Analysis"
+msgstr ""
+
+#. module: upgrade_analysis
+#: model:ir.model,name:upgrade_analysis.model_upgrade_attribute
+msgid "Upgrade Attribute"
+msgstr ""
+
+#. module: upgrade_analysis
+#: model:ir.model,name:upgrade_analysis.model_upgrade_comparison_config
+msgid "Upgrade Comparison Configuration"
+msgstr ""
+
+#. module: upgrade_analysis
+#: model:ir.model,name:upgrade_analysis.model_upgrade_generate_record_wizard
+msgid "Upgrade Generate Record Wizard"
+msgstr ""
+
+#. module: upgrade_analysis
+#: model:ir.model,name:upgrade_analysis.model_upgrade_install_wizard
+msgid "Upgrade Install Wizard"
+msgstr ""
+
+#. module: upgrade_analysis
+#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_analysis__upgrade_path
+msgid "Upgrade Path"
+msgstr ""
+
+#. module: upgrade_analysis
+#: model:ir.model,name:upgrade_analysis.model_upgrade_record
+msgid "Upgrade Record"
+msgstr ""
+
+#. module: upgrade_analysis
+#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_comparison_config__username
+msgid "Username"
+msgstr ""
+
+#. module: upgrade_analysis
+#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_attribute__value
+msgid "Value"
+msgstr ""
+
+#. module: upgrade_analysis
+#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_comparison_config__version
+msgid "Version"
+msgstr ""
+
+#. module: upgrade_analysis
+#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_analysis__write_files
+msgid "Write Files"
+msgstr ""
+
+#. module: upgrade_analysis
+#: model:ir.model.fields,help:upgrade_analysis.field_upgrade_analysis__write_files
+msgid "Write analysis files to the module directories"
+msgstr ""
+
+#. module: upgrade_analysis
+#: model:ir.model.fields.selection,name:upgrade_analysis.selection__upgrade_record__type__xmlid
+msgid "XML ID"
+msgstr ""
+
+#. module: upgrade_analysis
+#: code:addons/upgrade_analysis/models/upgrade_comparison_config.py:0
+#, python-format
+msgid ""
+"You are correctly connected to the server %(server)s (version %(version)s) "
+"with the user %(user_name)s"
+msgstr ""
+
+#. module: upgrade_analysis
+#: model:ir.model.fields.selection,name:upgrade_analysis.selection__upgrade_analysis__state__draft
+msgid "draft"
+msgstr ""
+
+#. module: upgrade_analysis
+#: model:ir.actions.act_window,name:upgrade_analysis.action_upgrade_comparison_config_tree
+msgid "upgrade Comparison Configs"
+msgstr ""
+
+#. module: upgrade_analysis
+#: model:ir.actions.act_window,name:upgrade_analysis.action_upgrade_record_tree
+msgid "upgrade Records"
+msgstr ""
From 53a10b8a5fe4c5dc85b0e8654b360d7614c20719 Mon Sep 17 00:00:00 2001
From: oca-git-bot
Date: Fri, 14 May 2021 19:30:51 +0200
Subject: [PATCH 39/67] [IMP] update dotfiles [ci skip]
---
upgrade_analysis/models/upgrade_analysis.py | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/upgrade_analysis/models/upgrade_analysis.py b/upgrade_analysis/models/upgrade_analysis.py
index fcdd48774..43a29a1b2 100644
--- a/upgrade_analysis/models/upgrade_analysis.py
+++ b/upgrade_analysis/models/upgrade_analysis.py
@@ -12,7 +12,7 @@ from copy import deepcopy
from lxml import etree
from odoo import fields, models
-from odoo.exceptions import UserError, ValidationError
+from odoo.exceptions import ValidationError
from odoo.modules import get_module_path
from odoo.tools import config
from odoo.tools.convert import nodeattr2bool
@@ -189,7 +189,7 @@ class UpgradeAnalysis(models.Model):
)
if "base" in affected_modules:
try:
- from odoo.addons.openupgrade_scripts import apriori
+ pass
except ImportError:
_logger.error(
"You are using upgrade_analysis on core modules without "
From 15a3e6c6bd01692a8df6e9238a58bfa432bc35ba Mon Sep 17 00:00:00 2001
From: Yves Le Doeuff
Date: Fri, 14 May 2021 17:04:35 +0000
Subject: [PATCH 40/67] Translated using Weblate (French)
Currently translated at 4.6% (4 of 86 strings)
Translation: server-tools-14.0/server-tools-14.0-upgrade_analysis
Translate-URL: https://translation.odoo-community.org/projects/server-tools-14-0/server-tools-14-0-upgrade_analysis/fr/
---
upgrade_analysis/i18n/fr.po | 12 +++++++-----
1 file changed, 7 insertions(+), 5 deletions(-)
diff --git a/upgrade_analysis/i18n/fr.po b/upgrade_analysis/i18n/fr.po
index 6ab2f70f6..234427e4a 100644
--- a/upgrade_analysis/i18n/fr.po
+++ b/upgrade_analysis/i18n/fr.po
@@ -6,33 +6,35 @@ msgid ""
msgstr ""
"Project-Id-Version: Odoo Server 14.0\n"
"Report-Msgid-Bugs-To: \n"
-"Last-Translator: Automatically generated\n"
+"PO-Revision-Date: 2021-05-14 19:47+0000\n"
+"Last-Translator: Yves Le Doeuff \n"
"Language-Team: none\n"
"Language: fr\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: \n"
"Plural-Forms: nplurals=2; plural=n > 1;\n"
+"X-Generator: Weblate 4.3.2\n"
#. module: upgrade_analysis
#: model_terms:ir.ui.view,arch_db:upgrade_analysis.view_upgrade_install_wizard_form
msgid "All Modules"
-msgstr ""
+msgstr "Tous les modules"
#. module: upgrade_analysis
#: model_terms:ir.ui.view,arch_db:upgrade_analysis.view_upgrade_install_wizard_form
msgid "All OCA Modules"
-msgstr ""
+msgstr "Tous les modules OCA"
#. module: upgrade_analysis
#: model_terms:ir.ui.view,arch_db:upgrade_analysis.view_upgrade_install_wizard_form
msgid "All Odoo SA Modules"
-msgstr ""
+msgstr "Tous les modules Odoo SA"
#. module: upgrade_analysis
#: model_terms:ir.ui.view,arch_db:upgrade_analysis.view_upgrade_install_wizard_form
msgid "All Other Modules"
-msgstr ""
+msgstr "Tous les autres modules"
#. module: upgrade_analysis
#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_comparison_config__analysis_ids
From e55ef6c7a911b08de6528ca903f05bd255a39f36 Mon Sep 17 00:00:00 2001
From: Payam Yasaie
Date: Tue, 12 Oct 2021 09:04:28 +0330
Subject: [PATCH 41/67] [FIX] Other modules upgrade write file full path
Parentheses placement was wrong in other modules full_path that lead to create migrations on root of modules
---
upgrade_analysis/models/upgrade_analysis.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/upgrade_analysis/models/upgrade_analysis.py b/upgrade_analysis/models/upgrade_analysis.py
index 43a29a1b2..932ce80f0 100644
--- a/upgrade_analysis/models/upgrade_analysis.py
+++ b/upgrade_analysis/models/upgrade_analysis.py
@@ -93,7 +93,7 @@ class UpgradeAnalysis(models.Model):
full_path = os.path.join(self.upgrade_path, module_name, version)
else:
full_path = os.path.join(
- get_module_path(module_name, "migrations", version)
+ get_module_path(module_name), "migrations", version
)
if not os.path.exists(full_path):
try:
From 767fb01fa1970b5e6f5654fe6ea5e06e120faef0 Mon Sep 17 00:00:00 2001
From: OCA-git-bot
Date: Wed, 13 Oct 2021 10:47:04 +0000
Subject: [PATCH 42/67] upgrade_analysis 14.0.2.1.1
---
upgrade_analysis/__manifest__.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/upgrade_analysis/__manifest__.py b/upgrade_analysis/__manifest__.py
index 5c3aa3444..c3d5e6f1b 100644
--- a/upgrade_analysis/__manifest__.py
+++ b/upgrade_analysis/__manifest__.py
@@ -5,7 +5,7 @@
"name": "Upgrade Analysis",
"summary": "Performs a difference analysis between modules"
" installed on two different Odoo instances",
- "version": "14.0.2.1.0",
+ "version": "14.0.2.1.1",
"category": "Migration",
"author": "Therp BV, Opener B.V., GRAP, Odoo Community Association (OCA)",
"website": "https://github.com/OCA/server-tools",
From a3336031ed97552d3045b80b2dd9254db5ae7d84 Mon Sep 17 00:00:00 2001
From: Sylvain LE GAL
Date: Thu, 21 Oct 2021 00:20:36 +0200
Subject: [PATCH 43/67] [MIG] upgrade_analysis from 14.0 to 15.0
---
upgrade_analysis/__manifest__.py | 2 +-
.../migrations/14.0.1.0.0/pre-migrate.py | 27 -------------------
upgrade_analysis/models/upgrade_analysis.py | 6 ++---
.../models/upgrade_comparison_config.py | 10 +++----
upgrade_analysis/models/upgrade_record.py | 8 +++---
.../odoo_patch/addons/mrp/__init__.py | 2 +-
.../addons/point_of_sale/__init__.py | 2 +-
.../odoo_patch/addons/stock/__init__.py | 2 +-
upgrade_analysis/odoo_patch/odoo/models.py | 2 +-
upgrade_analysis/upgrade_log.py | 2 +-
10 files changed, 18 insertions(+), 45 deletions(-)
delete mode 100644 upgrade_analysis/migrations/14.0.1.0.0/pre-migrate.py
diff --git a/upgrade_analysis/__manifest__.py b/upgrade_analysis/__manifest__.py
index c3d5e6f1b..d07930884 100644
--- a/upgrade_analysis/__manifest__.py
+++ b/upgrade_analysis/__manifest__.py
@@ -5,7 +5,7 @@
"name": "Upgrade Analysis",
"summary": "Performs a difference analysis between modules"
" installed on two different Odoo instances",
- "version": "14.0.2.1.1",
+ "version": "15.0.1.0.1",
"category": "Migration",
"author": "Therp BV, Opener B.V., GRAP, Odoo Community Association (OCA)",
"website": "https://github.com/OCA/server-tools",
diff --git a/upgrade_analysis/migrations/14.0.1.0.0/pre-migrate.py b/upgrade_analysis/migrations/14.0.1.0.0/pre-migrate.py
deleted file mode 100644
index ee9409ec4..000000000
--- a/upgrade_analysis/migrations/14.0.1.0.0/pre-migrate.py
+++ /dev/null
@@ -1,27 +0,0 @@
-# Copyright 2021 ForgeFlow S.L. (https://www.forgeflow.com)
-# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
-from openupgradelib import openupgrade
-
-_model_renames = [
- ("openupgrade.analysis.wizard", "upgrade.analysis"),
- ("openupgrade.attribute", "upgrade.attribute"),
- ("openupgrade.comparison.config", "upgrade.comparison.config"),
- ("openupgrade.record", "upgrade.record"),
- ("openupgrade.generate.records.wizard", "upgrade.generate.record.wizard"),
- ("openupgrade.install.all.wizard", "upgrade.install.wizard"),
-]
-
-_table_renames = [
- ("openupgrade_analysis_wizard", "upgrade_analysis"),
- ("openupgrade_attribute", "upgrade_attribute"),
- ("openupgrade_comparison_config", "upgrade_comparison_config"),
- ("openupgrade_record", "upgrade_record"),
- ("openupgrade_generate_records_wizard", "upgrade_generate_record_wizard"),
- ("openupgrade_install_all_wizard", "upgrade_install_wizard"),
-]
-
-
-@openupgrade.migrate()
-def migrate(env, version):
- openupgrade.rename_models(env.cr, _model_renames)
- openupgrade.rename_tables(env.cr, _table_renames)
diff --git a/upgrade_analysis/models/upgrade_analysis.py b/upgrade_analysis/models/upgrade_analysis.py
index 932ce80f0..2a6046e54 100644
--- a/upgrade_analysis/models/upgrade_analysis.py
+++ b/upgrade_analysis/models/upgrade_analysis.py
@@ -429,10 +429,8 @@ class UpgradeAnalysis(models.Model):
root_node_noupdate = nodeattr2bool(root_node, "noupdate", False)
if root_node.tag not in ("openerp", "odoo", "data"):
raise ValidationError(
- _(
- "Unexpected root Element: %s in file: %s"
- % (root_node.getroot(), xml_file)
- )
+ _("Unexpected root Element: %(root)s in file: %(file)s")
+ % {"root": root_node.getroot(), "file": xml_file}
)
for node in root_node:
if node.tag == "data":
diff --git a/upgrade_analysis/models/upgrade_comparison_config.py b/upgrade_analysis/models/upgrade_comparison_config.py
index 35fcd5005..649866379 100644
--- a/upgrade_analysis/models/upgrade_comparison_config.py
+++ b/upgrade_analysis/models/upgrade_comparison_config.py
@@ -43,11 +43,11 @@ class UpgradeComparisonConfig(models.Model):
self.ensure_one()
try:
remote = odoorpc.ODOO(self.server, port=self.port)
- except URLError:
+ except URLError as exc:
raise UserError(
- _("Could not connect the Odoo server at %s:%s")
- % (self.server, self.port)
- )
+ _("Could not connect the Odoo server at %(server)s:%(port)s")
+ % {"server": self.server, "port": self.port}
+ ) from exc
remote.login(self.database, self.username, self.password)
self.version = remote.version
return remote
@@ -60,7 +60,7 @@ class UpgradeComparisonConfig(models.Model):
ids = user_model.search([("login", "=", "admin")])
user_info = user_model.read([ids[0]], ["name"])[0]
except Exception as e:
- raise UserError(_("Connection failed.\n\nDETAIL: %s") % e)
+ raise UserError(_("Connection failed.\n\nDETAIL: %s") % e) from e
return {
"type": "ir.actions.client",
"tag": "display_notification",
diff --git a/upgrade_analysis/models/upgrade_record.py b/upgrade_analysis/models/upgrade_record.py
index f62c7ca3e..2f0db3827 100644
--- a/upgrade_analysis/models/upgrade_record.py
+++ b/upgrade_analysis/models/upgrade_record.py
@@ -138,7 +138,7 @@ class UpgradeRecord(models.Model):
@api.model
def list_modules(self):
- """ Return the set of covered modules """
+ """Return the set of covered modules"""
self.env.cr.execute(
"""SELECT DISTINCT(module) FROM upgrade_record
ORDER BY module"""
@@ -152,11 +152,13 @@ class UpgradeRecord(models.Model):
with open(os.path.join(addon_dir, manifest_name), "r") as f:
manifest_string = f.read()
return ast.literal_eval(manifest_string)
- raise ValidationError(_("No manifest found in %s" % addon_dir))
+ raise ValidationError(
+ _("No manifest found in %(addon_dir)s") % {"addon_dir": addon_dir}
+ )
@api.model
def get_xml_records(self, module):
- """ Return all XML records from the given module """
+ """Return all XML records from the given module"""
addon_dir = get_module_path(module)
manifest = self._read_manifest(addon_dir)
# The order of the keys are important.
diff --git a/upgrade_analysis/odoo_patch/addons/mrp/__init__.py b/upgrade_analysis/odoo_patch/addons/mrp/__init__.py
index 09caee64c..e795cbc33 100644
--- a/upgrade_analysis/odoo_patch/addons/mrp/__init__.py
+++ b/upgrade_analysis/odoo_patch/addons/mrp/__init__.py
@@ -8,4 +8,4 @@ class PreInitHookPatch(OdooPatch):
method_names = ["_pre_init_mrp"]
def _pre_init_mrp(cr):
- """ Don't try to create an existing column on reinstall """
+ """Don't try to create an existing column on reinstall"""
diff --git a/upgrade_analysis/odoo_patch/addons/point_of_sale/__init__.py b/upgrade_analysis/odoo_patch/addons/point_of_sale/__init__.py
index 66f003c17..f363b8106 100644
--- a/upgrade_analysis/odoo_patch/addons/point_of_sale/__init__.py
+++ b/upgrade_analysis/odoo_patch/addons/point_of_sale/__init__.py
@@ -10,4 +10,4 @@ class PreInitHookPatch(OdooPatch):
@api.model
def post_install_pos_localisation(cr):
- """ Do not configure twice pos_localisation"""
+ """Do not configure twice pos_localisation"""
diff --git a/upgrade_analysis/odoo_patch/addons/stock/__init__.py b/upgrade_analysis/odoo_patch/addons/stock/__init__.py
index 206795b42..3ff1cb0a2 100644
--- a/upgrade_analysis/odoo_patch/addons/stock/__init__.py
+++ b/upgrade_analysis/odoo_patch/addons/stock/__init__.py
@@ -8,4 +8,4 @@ class PreInitHookPatch(OdooPatch):
method_names = ["pre_init_hook"]
def pre_init_hook(cr):
- """ Don't unlink stock data on reinstall """
+ """Don't unlink stock data on reinstall"""
diff --git a/upgrade_analysis/odoo_patch/odoo/models.py b/upgrade_analysis/odoo_patch/odoo/models.py
index 431fc9635..51de8037b 100644
--- a/upgrade_analysis/odoo_patch/odoo/models.py
+++ b/upgrade_analysis/odoo_patch/odoo/models.py
@@ -10,7 +10,7 @@ class BaseModelPatch(OdooPatch):
@api.model
def _convert_records(self, records, log=lambda a: None):
- """ Log data ids that are imported with `load` """
+ """Log data ids that are imported with `load`"""
current_module = self.env.context["module"]
for res in BaseModelPatch._convert_records._original_method(
self, records, log=log
diff --git a/upgrade_analysis/upgrade_log.py b/upgrade_analysis/upgrade_log.py
index b102d3afa..3a8d13127 100644
--- a/upgrade_analysis/upgrade_log.py
+++ b/upgrade_analysis/upgrade_log.py
@@ -141,7 +141,7 @@ def log_model(model, local_registry):
}
if v.type == "selection":
if isinstance(v.selection, (tuple, list)):
- properties["selection_keys"] = str(sorted([x[0] for x in v.selection]))
+ properties["selection_keys"] = str(sorted(x[0] for x in v.selection))
else:
properties["selection_keys"] = "function"
elif v.type == "binary":
From a4a1ec3fd711c4a2bb12a9a9a6dd516dbc521ff3 Mon Sep 17 00:00:00 2001
From: oca-ci
Date: Wed, 10 Nov 2021 20:11:18 +0000
Subject: [PATCH 44/67] [UPD] Update upgrade_analysis.pot
---
upgrade_analysis/i18n/upgrade_analysis.pot | 22 ++++------------------
1 file changed, 4 insertions(+), 18 deletions(-)
diff --git a/upgrade_analysis/i18n/upgrade_analysis.pot b/upgrade_analysis/i18n/upgrade_analysis.pot
index fb0550c0a..2b4f5e051 100644
--- a/upgrade_analysis/i18n/upgrade_analysis.pot
+++ b/upgrade_analysis/i18n/upgrade_analysis.pot
@@ -4,7 +4,7 @@
#
msgid ""
msgstr ""
-"Project-Id-Version: Odoo Server 14.0\n"
+"Project-Id-Version: Odoo Server 15.0\n"
"Report-Msgid-Bugs-To: \n"
"Last-Translator: \n"
"Language-Team: \n"
@@ -103,7 +103,7 @@ msgstr ""
#. module: upgrade_analysis
#: code:addons/upgrade_analysis/models/upgrade_comparison_config.py:0
#, python-format
-msgid "Could not connect the Odoo server at %s:%s"
+msgid "Could not connect the Odoo server at %(server)s:%(port)s"
msgstr ""
#. module: upgrade_analysis
@@ -142,7 +142,6 @@ msgid "Database"
msgstr ""
#. module: upgrade_analysis
-#: model:ir.model.fields,field_description:upgrade_analysis.field_ir_module_module__display_name
#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_analysis__display_name
#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_attribute__display_name
#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_comparison_config__display_name
@@ -183,7 +182,6 @@ msgid "Generate Records Wizard"
msgstr ""
#. module: upgrade_analysis
-#: model:ir.model.fields,field_description:upgrade_analysis.field_ir_module_module__id
#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_analysis__id
#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_attribute__id
#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_comparison_config__id
@@ -215,7 +213,6 @@ msgid "Is Odoo Module"
msgstr ""
#. module: upgrade_analysis
-#: model:ir.model.fields,field_description:upgrade_analysis.field_ir_module_module____last_update
#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_analysis____last_update
#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_attribute____last_update
#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_comparison_config____last_update
@@ -314,7 +311,7 @@ msgstr ""
#. module: upgrade_analysis
#: code:addons/upgrade_analysis/models/upgrade_record.py:0
#, python-format
-msgid "No manifest found in %s"
+msgid "No manifest found in %(addon_dir)s"
msgstr ""
#. module: upgrade_analysis
@@ -364,17 +361,6 @@ msgid ""
"modifies an attribute of an existing field, set to Modify."
msgstr ""
-#. module: upgrade_analysis
-#: model:ir.model.fields,field_description:upgrade_analysis.field_ir_module_module__smart_search
-#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_analysis__smart_search
-#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_attribute__smart_search
-#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_comparison_config__smart_search
-#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_generate_record_wizard__smart_search
-#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_install_wizard__smart_search
-#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_record__smart_search
-msgid "Smart Search"
-msgstr ""
-
#. module: upgrade_analysis
#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_analysis__state
#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_generate_record_wizard__state
@@ -427,7 +413,7 @@ msgstr ""
#. module: upgrade_analysis
#: code:addons/upgrade_analysis/models/upgrade_analysis.py:0
#, python-format
-msgid "Unexpected root Element: %s in file: %s"
+msgid "Unexpected root Element: %(root)s in file: %(file)s"
msgstr ""
#. module: upgrade_analysis
From 7ea1edc7a13ac85aa0d367cae38a3a8765137431 Mon Sep 17 00:00:00 2001
From: OCA-git-bot
Date: Wed, 10 Nov 2021 20:13:40 +0000
Subject: [PATCH 45/67] [UPD] README.rst
---
upgrade_analysis/README.rst | 10 +++++-----
upgrade_analysis/static/description/index.html | 6 +++---
2 files changed, 8 insertions(+), 8 deletions(-)
diff --git a/upgrade_analysis/README.rst b/upgrade_analysis/README.rst
index 4fcf7f0cf..13b346f3f 100644
--- a/upgrade_analysis/README.rst
+++ b/upgrade_analysis/README.rst
@@ -14,13 +14,13 @@ Upgrade Analysis
:target: http://www.gnu.org/licenses/agpl-3.0-standalone.html
:alt: License: AGPL-3
.. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fserver--tools-lightgray.png?logo=github
- :target: https://github.com/OCA/server-tools/tree/14.0/upgrade_analysis
+ :target: https://github.com/OCA/server-tools/tree/15.0/upgrade_analysis
:alt: OCA/server-tools
.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png
- :target: https://translation.odoo-community.org/projects/server-tools-14-0/server-tools-14-0-upgrade_analysis
+ :target: https://translation.odoo-community.org/projects/server-tools-15-0/server-tools-15-0-upgrade_analysis
:alt: Translate me on Weblate
.. |badge5| image:: https://img.shields.io/badge/runbot-Try%20me-875A7B.png
- :target: https://runbot.odoo-community.org/runbot/149/14.0
+ :target: https://runbot.odoo-community.org/runbot/149/15.0
:alt: Try me on Runbot
|badge1| |badge2| |badge3| |badge4| |badge5|
@@ -46,7 +46,7 @@ Bug Tracker
Bugs are tracked on `GitHub Issues `_.
In case of trouble, please check there if your issue has already been reported.
If you spotted it first, help us smashing it by providing a detailed and welcomed
-`feedback `_.
+`feedback `_.
Do not contact contributors directly about support or help with technical issues.
@@ -84,6 +84,6 @@ OCA, or the Odoo Community Association, is a nonprofit organization whose
mission is to support the collaborative development of Odoo features and
promote its widespread use.
-This module is part of the `OCA/server-tools `_ project on GitHub.
+This module is part of the `OCA/server-tools `_ project on GitHub.
You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.
diff --git a/upgrade_analysis/static/description/index.html b/upgrade_analysis/static/description/index.html
index 6a1087c8f..fc5151a8e 100644
--- a/upgrade_analysis/static/description/index.html
+++ b/upgrade_analysis/static/description/index.html
@@ -367,7 +367,7 @@ ul.auto-toc {
!! This file is generated by oca-gen-addon-readme !!
!! changes will be overwritten. !!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->
-
+
This module provides the tool to generate the database analysis files that indicate how the Odoo data model and module data have changed between two versions of Odoo. Database analysis files for the core modules are included in the OpenUpgrade distribution so as a migration script developer you will not usually need to use this tool yourself. If you do need to run your analysis of a custom set of modules, please refer to the documentation here: https://doc.therp.nl/openupgrade/analysis.html
This module is just a tool, a continuation of the old openupgrade_records in OpenUpgrade in previous versions. It’s not recommended to have this module in a production database.
Table of contents
@@ -395,7 +395,7 @@ ul.auto-toc {
Bugs are tracked on GitHub Issues .
In case of trouble, please check there if your issue has already been reported.
If you spotted it first, help us smashing it by providing a detailed and welcomed
-feedback .
+feedback .
Do not contact contributors directly about support or help with technical issues.
@@ -427,7 +427,7 @@ If you spotted it first, help us smashing it by providing a detailed and welcome
OCA, or the Odoo Community Association, is a nonprofit organization whose
mission is to support the collaborative development of Odoo features and
promote its widespread use.
-
This module is part of the OCA/server-tools project on GitHub.
+
This module is part of the OCA/server-tools project on GitHub.
You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute .
From 56903660f7a3b1c2905f00320d5e77592e9956e7 Mon Sep 17 00:00:00 2001
From: Sylvain LE GAL
Date: Thu, 11 Nov 2021 11:52:16 +0100
Subject: [PATCH 46/67] [IMP] upgrade_coverage : generate coverage module file
---
upgrade_analysis/__manifest__.py | 2 +-
upgrade_analysis/models/upgrade_analysis.py | 71 ++++++++++++++++++-
.../src/module_coverage_template.rst.mako | 12 ++++
3 files changed, 83 insertions(+), 2 deletions(-)
create mode 100644 upgrade_analysis/static/src/module_coverage_template.rst.mako
diff --git a/upgrade_analysis/__manifest__.py b/upgrade_analysis/__manifest__.py
index d07930884..47e9fdff1 100644
--- a/upgrade_analysis/__manifest__.py
+++ b/upgrade_analysis/__manifest__.py
@@ -21,7 +21,7 @@
"installable": True,
"depends": ["base"],
"external_dependencies": {
- "python": ["dataclasses", "odoorpc", "openupgradelib"],
+ "python": ["mako", "dataclasses", "odoorpc", "openupgradelib"],
},
"license": "AGPL-3",
}
diff --git a/upgrade_analysis/models/upgrade_analysis.py b/upgrade_analysis/models/upgrade_analysis.py
index 2a6046e54..e9037765c 100644
--- a/upgrade_analysis/models/upgrade_analysis.py
+++ b/upgrade_analysis/models/upgrade_analysis.py
@@ -10,8 +10,9 @@ import os
from copy import deepcopy
from lxml import etree
+from mako.template import Template
-from odoo import fields, models
+from odoo import fields, models, release
from odoo.exceptions import ValidationError
from odoo.modules import get_module_path
from odoo.tools import config
@@ -265,6 +266,12 @@ class UpgradeAnalysis(models.Model):
_logger.exception("Error generating noupdate changes: %s" % e)
general_log += "ERROR: error when generating noupdate changes: %s\n" % e
+ try:
+ self.generate_module_coverage_file()
+ except Exception as e:
+ _logger.exception("Error generating module coverage file: %s" % e)
+ general_log += "ERROR: error when generating module coverage file: %s\n" % e
+
self.write(
{
"state": "done",
@@ -494,3 +501,65 @@ class UpgradeAnalysis(models.Model):
filename="noupdate_changes.xml",
)
return True
+
+ def generate_module_coverage_file(self):
+ self.ensure_one()
+
+ module_coverage_file_folder = config.get("module_coverage_file_folder", False)
+
+ if not module_coverage_file_folder:
+ return
+
+ file_template = Template(
+ filename=os.path.join(
+ get_module_path("upgrade_analysis"),
+ "static",
+ "src",
+ "module_coverage_template.rst.mako",
+ )
+ )
+
+ module_domain = [
+ ("state", "=", "installed"),
+ ("name", "not in", ["upgrade_analysis", "openupgrade_records"]),
+ ]
+
+ connection = self.config_id.get_connection()
+ all_local_modules = (
+ self.env["ir.module.module"].search(module_domain).mapped("name")
+ )
+ all_remote_modules = (
+ connection.env["ir.module.module"]
+ .browse(connection.env["ir.module.module"].search(module_domain))
+ .mapped("name")
+ )
+
+ start_version = connection.version
+ end_version = release.major_version
+
+ all_modules = sorted(list(set(all_remote_modules + all_local_modules)))
+ module_descriptions = []
+ for module in all_modules:
+ if module in all_local_modules and module in all_remote_modules:
+ module_description = " %s" % module
+ elif module in all_local_modules:
+ module_description = " |new| %s" % module
+ else:
+ module_description = " |del| %s" % module
+ module_descriptions.append(module_description.ljust(49, " "))
+
+ rendered_text = file_template.render(
+ start_version=start_version,
+ end_version=end_version,
+ module_descriptions=module_descriptions,
+ )
+
+ file_name = "modules{}-{}.rst".format(
+ start_version.replace(".", ""),
+ end_version.replace(".", ""),
+ )
+
+ file_path = os.path.join(module_coverage_file_folder, file_name)
+ f = open(file_path, "w+")
+ f.write(rendered_text)
+ f.close()
diff --git a/upgrade_analysis/static/src/module_coverage_template.rst.mako b/upgrade_analysis/static/src/module_coverage_template.rst.mako
new file mode 100644
index 000000000..a9b5f0599
--- /dev/null
+++ b/upgrade_analysis/static/src/module_coverage_template.rst.mako
@@ -0,0 +1,12 @@
+Module coverage ${start_version} -> ${end_version}
+============================
+
+.. include:: coverage_legend.rst
+
++-------------------------------------------------+-------------------------------------------------+
+|Module |Status |
++=================================================+=================================================+
+% for module_description in module_descriptions:
+|${module_description}| |
++-------------------------------------------------+-------------------------------------------------+
+% endfor
From 1297458211f667c09c5845d65e2c9f1ae3163e74 Mon Sep 17 00:00:00 2001
From: Sylvain LE GAL
Date: Sun, 14 Nov 2021 09:11:58 +0100
Subject: [PATCH 47/67] [IMP] upgrade_analysis : prefill status with trivial
information
---
upgrade_analysis/models/upgrade_analysis.py | 31 ++++++++++++++++---
.../src/module_coverage_template.rst.mako | 4 +--
2 files changed, 29 insertions(+), 6 deletions(-)
diff --git a/upgrade_analysis/models/upgrade_analysis.py b/upgrade_analysis/models/upgrade_analysis.py
index e9037765c..3cbfcd127 100644
--- a/upgrade_analysis/models/upgrade_analysis.py
+++ b/upgrade_analysis/models/upgrade_analysis.py
@@ -210,6 +210,8 @@ class UpgradeAnalysis(models.Model):
}
general_log = ""
+ no_changes_modules = []
+
for ignore_module in _IGNORE_MODULES:
if ignore_module in keys:
keys.remove(ignore_module)
@@ -232,6 +234,7 @@ class UpgradeAnalysis(models.Model):
contents += "\n"
if key not in res and key not in res_xml and key not in res_model:
contents += "---nothing has changed in this module--\n"
+ no_changes_modules.append(key)
if key == "general":
general_log += contents
continue
@@ -267,7 +270,7 @@ class UpgradeAnalysis(models.Model):
general_log += "ERROR: error when generating noupdate changes: %s\n" % e
try:
- self.generate_module_coverage_file()
+ self.generate_module_coverage_file(no_changes_modules)
except Exception as e:
_logger.exception("Error generating module coverage file: %s" % e)
general_log += "ERROR: error when generating module coverage file: %s\n" % e
@@ -502,7 +505,7 @@ class UpgradeAnalysis(models.Model):
)
return True
- def generate_module_coverage_file(self):
+ def generate_module_coverage_file(self, no_changes_modules):
self.ensure_one()
module_coverage_file_folder = config.get("module_coverage_file_folder", False)
@@ -538,15 +541,34 @@ class UpgradeAnalysis(models.Model):
end_version = release.major_version
all_modules = sorted(list(set(all_remote_modules + all_local_modules)))
- module_descriptions = []
+ module_descriptions = {}
for module in all_modules:
+ status = ""
if module in all_local_modules and module in all_remote_modules:
module_description = " %s" % module
elif module in all_local_modules:
module_description = " |new| %s" % module
else:
module_description = " |del| %s" % module
- module_descriptions.append(module_description.ljust(49, " "))
+
+ if module in compare.apriori.merged_modules:
+ status = "Merged into %s. " % compare.apriori.merged_modules[module]
+ elif module in compare.apriori.renamed_modules:
+ status = "Renamed to %s. " % compare.apriori.renamed_modules[module]
+ elif module in compare.apriori.renamed_modules.values():
+ status = (
+ "Renamed from %s. "
+ % [
+ x
+ for x in compare.apriori.renamed_modules
+ if compare.apriori.renamed_modules[x] == module
+ ][0]
+ )
+ if module in no_changes_modules:
+ status += "No changes. "
+ module_descriptions[module_description.ljust(49, " ")] = status.ljust(
+ 49, " "
+ )
rendered_text = file_template.render(
start_version=start_version,
@@ -563,3 +585,4 @@ class UpgradeAnalysis(models.Model):
f = open(file_path, "w+")
f.write(rendered_text)
f.close()
+ return True
diff --git a/upgrade_analysis/static/src/module_coverage_template.rst.mako b/upgrade_analysis/static/src/module_coverage_template.rst.mako
index a9b5f0599..f5d532e5b 100644
--- a/upgrade_analysis/static/src/module_coverage_template.rst.mako
+++ b/upgrade_analysis/static/src/module_coverage_template.rst.mako
@@ -6,7 +6,7 @@ Module coverage ${start_version} -> ${end_version}
+-------------------------------------------------+-------------------------------------------------+
|Module |Status |
+=================================================+=================================================+
-% for module_description in module_descriptions:
-|${module_description}| |
+% for module, status in module_descriptions.items():
+|${module}|${status}|
+-------------------------------------------------+-------------------------------------------------+
% endfor
From a53fcb17de2e806a5e8426c861e63eb0e733bf96 Mon Sep 17 00:00:00 2001
From: Sylvain LE GAL
Date: Mon, 15 Nov 2021 11:23:15 +0100
Subject: [PATCH 48/67] [REF] in coverage module file, split column into 2. a
column that should be filled by openupgrader, and a column that is
automatically filled when importing apriori and making analysis
---
upgrade_analysis/models/upgrade_analysis.py | 4 ++--
.../static/src/module_coverage_template.rst.mako | 12 ++++++------
2 files changed, 8 insertions(+), 8 deletions(-)
diff --git a/upgrade_analysis/models/upgrade_analysis.py b/upgrade_analysis/models/upgrade_analysis.py
index 3cbfcd127..f717b5c86 100644
--- a/upgrade_analysis/models/upgrade_analysis.py
+++ b/upgrade_analysis/models/upgrade_analysis.py
@@ -564,8 +564,8 @@ class UpgradeAnalysis(models.Model):
if compare.apriori.renamed_modules[x] == module
][0]
)
- if module in no_changes_modules:
- status += "No changes. "
+ elif module in no_changes_modules:
+ status += "No DB layout changes. "
module_descriptions[module_description.ljust(49, " ")] = status.ljust(
49, " "
)
diff --git a/upgrade_analysis/static/src/module_coverage_template.rst.mako b/upgrade_analysis/static/src/module_coverage_template.rst.mako
index f5d532e5b..ab598ae4d 100644
--- a/upgrade_analysis/static/src/module_coverage_template.rst.mako
+++ b/upgrade_analysis/static/src/module_coverage_template.rst.mako
@@ -3,10 +3,10 @@ Module coverage ${start_version} -> ${end_version}
.. include:: coverage_legend.rst
-+-------------------------------------------------+-------------------------------------------------+
-|Module |Status |
-+=================================================+=================================================+
-% for module, status in module_descriptions.items():
-|${module}|${status}|
-+-------------------------------------------------+-------------------------------------------------+
++-------------------------------------------------+----------------------+-------------------------------------------------+
+| Module | Status + Extra Information |
++=================================================+======================+=================================================+
+% for module, extra_information in module_descriptions.items():
+|${module}| |${extra_information}|
++-------------------------------------------------+----------------------+-------------------------------------------------+
% endfor
From a2d690368f60111d7fddb2c14654b3251aadcda1 Mon Sep 17 00:00:00 2001
From: OCA-git-bot
Date: Mon, 15 Nov 2021 20:20:10 +0000
Subject: [PATCH 49/67] upgrade_analysis 15.0.1.0.2
---
upgrade_analysis/__manifest__.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/upgrade_analysis/__manifest__.py b/upgrade_analysis/__manifest__.py
index 47e9fdff1..e5e4cdd10 100644
--- a/upgrade_analysis/__manifest__.py
+++ b/upgrade_analysis/__manifest__.py
@@ -5,7 +5,7 @@
"name": "Upgrade Analysis",
"summary": "Performs a difference analysis between modules"
" installed on two different Odoo instances",
- "version": "15.0.1.0.1",
+ "version": "15.0.1.0.2",
"category": "Migration",
"author": "Therp BV, Opener B.V., GRAP, Odoo Community Association (OCA)",
"website": "https://github.com/OCA/server-tools",
From e6fc3834c33a694338b58a6f2c834c742b577f7e Mon Sep 17 00:00:00 2001
From: Jean-Charles Drubay
Date: Tue, 10 May 2022 22:41:28 +0700
Subject: [PATCH 50/67] [15.0][ADD] link to usage instructions
---
upgrade_analysis/readme/USAGE.rst | 1 +
1 file changed, 1 insertion(+)
create mode 100644 upgrade_analysis/readme/USAGE.rst
diff --git a/upgrade_analysis/readme/USAGE.rst b/upgrade_analysis/readme/USAGE.rst
new file mode 100644
index 000000000..bd341e59d
--- /dev/null
+++ b/upgrade_analysis/readme/USAGE.rst
@@ -0,0 +1 @@
+`Usage instructions `_
From a68b71300ea77c47d3603ca222cfb688f4225aac Mon Sep 17 00:00:00 2001
From: OCA-git-bot
Date: Tue, 10 May 2022 21:01:36 +0000
Subject: [PATCH 51/67] [UPD] README.rst
---
upgrade_analysis/README.rst | 5 ++++
.../static/description/index.html | 29 +++++++++++--------
2 files changed, 22 insertions(+), 12 deletions(-)
diff --git a/upgrade_analysis/README.rst b/upgrade_analysis/README.rst
index 13b346f3f..7756c2666 100644
--- a/upgrade_analysis/README.rst
+++ b/upgrade_analysis/README.rst
@@ -34,6 +34,11 @@ This module is just a tool, a continuation of the old openupgrade_records in Ope
.. contents::
:local:
+Usage
+=====
+
+`Usage instructions `_
+
Known issues / Roadmap
======================
diff --git a/upgrade_analysis/static/description/index.html b/upgrade_analysis/static/description/index.html
index fc5151a8e..80d236835 100644
--- a/upgrade_analysis/static/description/index.html
+++ b/upgrade_analysis/static/description/index.html
@@ -373,25 +373,30 @@ ul.auto-toc {
Table of contents
+
-
+
Log removed modules in the module that owned them (#468)
Detect renamed many2many tables (#213)
-
+
Bugs are tracked on GitHub Issues .
In case of trouble, please check there if your issue has already been reported.
If you spotted it first, help us smashing it by providing a detailed and welcomed
@@ -399,9 +404,9 @@ If you spotted it first, help us smashing it by providing a detailed and welcome
Do not contact contributors directly about support or help with technical issues.
-
+
-
+
Therp BV
Opener B.V.
@@ -409,7 +414,7 @@ If you spotted it first, help us smashing it by providing a detailed and welcome
-
+
This module is maintained by the OCA.
OCA, or the Odoo Community Association, is a nonprofit organization whose
From da786756aa9db3ac9b5787a337fcbc06106faf02 Mon Sep 17 00:00:00 2001
From: OCA-git-bot
Date: Tue, 10 May 2022 21:01:36 +0000
Subject: [PATCH 52/67] upgrade_analysis 15.0.1.0.3
---
upgrade_analysis/__manifest__.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/upgrade_analysis/__manifest__.py b/upgrade_analysis/__manifest__.py
index e5e4cdd10..2cafcde86 100644
--- a/upgrade_analysis/__manifest__.py
+++ b/upgrade_analysis/__manifest__.py
@@ -5,7 +5,7 @@
"name": "Upgrade Analysis",
"summary": "Performs a difference analysis between modules"
" installed on two different Odoo instances",
- "version": "15.0.1.0.2",
+ "version": "15.0.1.0.3",
"category": "Migration",
"author": "Therp BV, Opener B.V., GRAP, Odoo Community Association (OCA)",
"website": "https://github.com/OCA/server-tools",
From c6d23b5088b809e0cfeea2f5b380e9631d0bcd98 Mon Sep 17 00:00:00 2001
From: Sylvain LE GAL
Date: Thu, 16 Jun 2022 12:15:04 +0200
Subject: [PATCH 53/67] [DOC] upgrade_analysis : update roadmap.rst
Add new item in the roadmap section for the next migration of the module in V16
---
upgrade_analysis/readme/ROADMAP.rst | 1 +
1 file changed, 1 insertion(+)
diff --git a/upgrade_analysis/readme/ROADMAP.rst b/upgrade_analysis/readme/ROADMAP.rst
index 79e8c5939..48d1f8d94 100644
--- a/upgrade_analysis/readme/ROADMAP.rst
+++ b/upgrade_analysis/readme/ROADMAP.rst
@@ -1,2 +1,3 @@
* Log removed modules in the module that owned them (#468)
* Detect renamed many2many tables (#213)
+* Make sure that the ``migration_analysis.txt`` file is always generated in all cases. (See: https://github.com/OCA/OpenUpgrade/pull/3209#issuecomment-1157449981)
From 661f117e85e4346a71b52970f70c9aa8eeae2a49 Mon Sep 17 00:00:00 2001
From: Sylvain LE GAL
Date: Thu, 16 Jun 2022 12:42:07 +0200
Subject: [PATCH 54/67] [REF] upgrade_analysis add maintainers
---
upgrade_analysis/__manifest__.py | 1 +
1 file changed, 1 insertion(+)
diff --git a/upgrade_analysis/__manifest__.py b/upgrade_analysis/__manifest__.py
index 2cafcde86..251af030e 100644
--- a/upgrade_analysis/__manifest__.py
+++ b/upgrade_analysis/__manifest__.py
@@ -8,6 +8,7 @@
"version": "15.0.1.0.3",
"category": "Migration",
"author": "Therp BV, Opener B.V., GRAP, Odoo Community Association (OCA)",
+ "maintainers": ["StefanRijnhart", "legalsylvain"],
"website": "https://github.com/OCA/server-tools",
"data": [
"security/ir.model.access.csv",
From ebde0db3ee69c166d3e48b318dbc8b8dcca526b7 Mon Sep 17 00:00:00 2001
From: OCA-git-bot
Date: Thu, 16 Jun 2022 10:53:15 +0000
Subject: [PATCH 55/67] [UPD] README.rst
---
upgrade_analysis/README.rst | 12 ++++++++++++
upgrade_analysis/static/description/index.html | 3 +++
2 files changed, 15 insertions(+)
diff --git a/upgrade_analysis/README.rst b/upgrade_analysis/README.rst
index 7756c2666..2b543ab74 100644
--- a/upgrade_analysis/README.rst
+++ b/upgrade_analysis/README.rst
@@ -44,6 +44,7 @@ Known issues / Roadmap
* Log removed modules in the module that owned them (#468)
* Detect renamed many2many tables (#213)
+* Make sure that the ``migration_analysis.txt`` file is always generated in all cases. (See: https://github.com/OCA/OpenUpgrade/pull/3209#issuecomment-1157449981)
Bug Tracker
===========
@@ -89,6 +90,17 @@ OCA, or the Odoo Community Association, is a nonprofit organization whose
mission is to support the collaborative development of Odoo features and
promote its widespread use.
+.. |maintainer-StefanRijnhart| image:: https://github.com/StefanRijnhart.png?size=40px
+ :target: https://github.com/StefanRijnhart
+ :alt: StefanRijnhart
+.. |maintainer-legalsylvain| image:: https://github.com/legalsylvain.png?size=40px
+ :target: https://github.com/legalsylvain
+ :alt: legalsylvain
+
+Current `maintainers `__:
+
+|maintainer-StefanRijnhart| |maintainer-legalsylvain|
+
This module is part of the `OCA/server-tools `_ project on GitHub.
You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.
diff --git a/upgrade_analysis/static/description/index.html b/upgrade_analysis/static/description/index.html
index 80d236835..1f0de603c 100644
--- a/upgrade_analysis/static/description/index.html
+++ b/upgrade_analysis/static/description/index.html
@@ -393,6 +393,7 @@ ul.auto-toc {
@@ -432,6 +433,8 @@ If you spotted it first, help us smashing it by providing a detailed and welcome
OCA, or the Odoo Community Association, is a nonprofit organization whose
mission is to support the collaborative development of Odoo features and
promote its widespread use.
+
Current maintainers :
+
This module is part of the OCA/server-tools project on GitHub.
You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute .
From 0c5e91cf7090507192efcd284c1634d80e6ff285 Mon Sep 17 00:00:00 2001
From: OCA-git-bot
Date: Thu, 16 Jun 2022 10:53:15 +0000
Subject: [PATCH 56/67] upgrade_analysis 15.0.1.0.4
---
upgrade_analysis/__manifest__.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/upgrade_analysis/__manifest__.py b/upgrade_analysis/__manifest__.py
index 251af030e..017ab77ab 100644
--- a/upgrade_analysis/__manifest__.py
+++ b/upgrade_analysis/__manifest__.py
@@ -5,7 +5,7 @@
"name": "Upgrade Analysis",
"summary": "Performs a difference analysis between modules"
" installed on two different Odoo instances",
- "version": "15.0.1.0.3",
+ "version": "15.0.1.0.4",
"category": "Migration",
"author": "Therp BV, Opener B.V., GRAP, Odoo Community Association (OCA)",
"maintainers": ["StefanRijnhart", "legalsylvain"],
From 2978a6132e37c6253aaabdfc8afa26c941a5b140 Mon Sep 17 00:00:00 2001
From: Roy Le
Date: Tue, 5 Jul 2022 16:27:37 +0700
Subject: [PATCH 57/67] [ADD] upgrade_analysis: generate noupdate_changes for
template tag
---
upgrade_analysis/models/upgrade_analysis.py | 9 ++++++++-
1 file changed, 8 insertions(+), 1 deletion(-)
diff --git a/upgrade_analysis/models/upgrade_analysis.py b/upgrade_analysis/models/upgrade_analysis.py
index f717b5c86..dc52d4761 100644
--- a/upgrade_analysis/models/upgrade_analysis.py
+++ b/upgrade_analysis/models/upgrade_analysis.py
@@ -324,6 +324,13 @@ class UpgradeAnalysis(models.Model):
if remote_record is None and not module_xmlid:
continue
+ if local_record.tag == "template":
+ old_tmpl = etree.tostring(remote_record, encoding="utf-8")
+ new_tmpl = etree.tostring(local_record, encoding="utf-8")
+ if old_tmpl != new_tmpl:
+ odoo.append(local_record)
+ continue
+
element = etree.Element(
"record", id=xml_id, model=local_record.attrib["model"]
)
@@ -389,7 +396,7 @@ class UpgradeAnalysis(models.Model):
self, data_node, records_update, records_noupdate, module_name
):
noupdate = nodeattr2bool(data_node, "noupdate", False)
- for record in data_node.xpath("./record"):
+ for record in data_node.xpath("./record") + data_node.xpath("./template"):
self._process_record_node(
record, noupdate, records_update, records_noupdate, module_name
)
From edc31da81c6665f49c1a006b2e78c2c7702e89d8 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Miquel=20Ra=C3=AFch?=
Date: Mon, 13 Dec 2021 18:00:58 +0100
Subject: [PATCH 58/67] [IMP] upgrade_analysis: log sql_constraints in analysis
---
upgrade_analysis/compare.py | 18 +++++++--
upgrade_analysis/models/upgrade_analysis.py | 1 +
upgrade_analysis/models/upgrade_record.py | 2 +
upgrade_analysis/odoo_patch/odoo/__init__.py | 1 +
.../odoo_patch/odoo/addons/__init__.py | 1 +
.../odoo_patch/odoo/addons/base/__init__.py | 1 +
.../odoo/addons/base/models/__init__.py | 1 +
.../odoo/addons/base/models/ir_model.py | 40 +++++++++++++++++++
upgrade_analysis/upgrade_log.py | 5 ++-
.../wizards/upgrade_generate_record_wizard.py | 18 +++++++++
10 files changed, 84 insertions(+), 4 deletions(-)
create mode 100644 upgrade_analysis/odoo_patch/odoo/addons/__init__.py
create mode 100644 upgrade_analysis/odoo_patch/odoo/addons/base/__init__.py
create mode 100644 upgrade_analysis/odoo_patch/odoo/addons/base/models/__init__.py
create mode 100644 upgrade_analysis/odoo_patch/odoo/addons/base/models/ir_model.py
diff --git a/upgrade_analysis/compare.py b/upgrade_analysis/compare.py
index 864277310..0a6f9ebb9 100644
--- a/upgrade_analysis/compare.py
+++ b/upgrade_analysis/compare.py
@@ -387,14 +387,22 @@ def compare_xml_sets(old_records, new_records):
and found["domain"] is False
)
column["domain"] = False
+ found["definition"] = (
+ column["definition"]
+ and column["definition"] != found["definition"]
+ and "is now '{}' ('{}')".format(
+ found["definition"], column["definition"]
+ )
+ )
+ column["definition"] = False
column["noupdate_switched"] = False
found["noupdate_switched"] = column["noupdate"] != found["noupdate"]
if match_type != "direct":
matched_records.append(column)
matched_records.append(found)
- elif (match_type == "direct" and found["domain"]) or found[
- "noupdate_switched"
- ]:
+ elif (
+ match_type == "direct" and (found["domain"] or found["definition"])
+ ) or found["noupdate_switched"]:
matched_records.append(found)
return matched_records
@@ -413,10 +421,12 @@ def compare_xml_sets(old_records, new_records):
for record in old_records:
record["old"] = True
record["domain"] = False
+ record["definition"] = False
record["noupdate_switched"] = False
for record in new_records:
record["new"] = True
record["domain"] = False
+ record["definition"] = False
record["noupdate_switched"] = False
sorted_records = sorted(
@@ -441,6 +451,8 @@ def compare_xml_sets(old_records, new_records):
content = "%(model)s: %(name)s" % entry
if entry["domain"]:
content += " (deleted domain)"
+ if entry["definition"]:
+ content += " (changed definition: %(definition)s)" % entry
if entry["noupdate"]:
content += " (noupdate)"
if entry["noupdate_switched"]:
diff --git a/upgrade_analysis/models/upgrade_analysis.py b/upgrade_analysis/models/upgrade_analysis.py
index dc52d4761..8d0e53aa5 100644
--- a/upgrade_analysis/models/upgrade_analysis.py
+++ b/upgrade_analysis/models/upgrade_analysis.py
@@ -144,6 +144,7 @@ class UpgradeAnalysis(models.Model):
"prefix",
"suffix",
"domain",
+ "definition",
]
local_xml_records = [
{field: record[field] for field in flds}
diff --git a/upgrade_analysis/models/upgrade_record.py b/upgrade_analysis/models/upgrade_record.py
index 2f0db3827..b8886fc61 100644
--- a/upgrade_analysis/models/upgrade_record.py
+++ b/upgrade_analysis/models/upgrade_record.py
@@ -49,6 +49,8 @@ class UpgradeRecord(models.Model):
domain = fields.Char(readonly=True)
+ definition = fields.Char(readonly=True)
+
prefix = fields.Char(compute="_compute_prefix_and_suffix")
suffix = fields.Char(compute="_compute_prefix_and_suffix")
diff --git a/upgrade_analysis/odoo_patch/odoo/__init__.py b/upgrade_analysis/odoo_patch/odoo/__init__.py
index 4541924d9..42c35ff23 100644
--- a/upgrade_analysis/odoo_patch/odoo/__init__.py
+++ b/upgrade_analysis/odoo_patch/odoo/__init__.py
@@ -1,3 +1,4 @@
+from . import addons
from . import models
from . import modules
from . import tools
diff --git a/upgrade_analysis/odoo_patch/odoo/addons/__init__.py b/upgrade_analysis/odoo_patch/odoo/addons/__init__.py
new file mode 100644
index 000000000..0e4444933
--- /dev/null
+++ b/upgrade_analysis/odoo_patch/odoo/addons/__init__.py
@@ -0,0 +1 @@
+from . import base
diff --git a/upgrade_analysis/odoo_patch/odoo/addons/base/__init__.py b/upgrade_analysis/odoo_patch/odoo/addons/base/__init__.py
new file mode 100644
index 000000000..0650744f6
--- /dev/null
+++ b/upgrade_analysis/odoo_patch/odoo/addons/base/__init__.py
@@ -0,0 +1 @@
+from . import models
diff --git a/upgrade_analysis/odoo_patch/odoo/addons/base/models/__init__.py b/upgrade_analysis/odoo_patch/odoo/addons/base/models/__init__.py
new file mode 100644
index 000000000..413bb2380
--- /dev/null
+++ b/upgrade_analysis/odoo_patch/odoo/addons/base/models/__init__.py
@@ -0,0 +1 @@
+from . import ir_model
diff --git a/upgrade_analysis/odoo_patch/odoo/addons/base/models/ir_model.py b/upgrade_analysis/odoo_patch/odoo/addons/base/models/ir_model.py
new file mode 100644
index 000000000..68cab246a
--- /dev/null
+++ b/upgrade_analysis/odoo_patch/odoo/addons/base/models/ir_model.py
@@ -0,0 +1,40 @@
+from odoo.addons.base.models import ir_model
+
+from ...... import upgrade_log
+from .....odoo_patch import OdooPatch
+
+
+class IrModelConstraintPatch(OdooPatch):
+ target = ir_model.IrModelConstraint
+ method_names = ["_reflect_model"]
+
+ def _reflect_model(self, model):
+ """Reflect the _sql_constraints of the given model."""
+
+ def cons_text(txt):
+ return txt.lower().replace(", ", ",").replace(" (", "(")
+
+ # map each constraint on the name of the module where it is defined
+ constraint_module = {
+ constraint[0]: cls._module
+ for cls in reversed(type(model).mro())
+ if not getattr(cls, "pool", None)
+ for constraint in getattr(cls, "_local_sql_constraints", ())
+ }
+
+ data_list = []
+ for (key, definition, message) in model._sql_constraints:
+ conname = "%s_%s" % (model._table, key)
+ module = constraint_module.get(key)
+ record = self._reflect_constraint(
+ model, conname, "u", cons_text(definition), module, message
+ )
+ if record:
+ xml_id = "%s.constraint_%s" % (module, conname)
+ data_list.append(dict(xml_id=xml_id, record=record))
+
+ self.env["ir.model.data"]._update_xmlids(data_list)
+ for data in data_list:
+ xml_id = data.get("xml_id")
+ module = xml_id.split(".")[0]
+ upgrade_log.log_xml_id(self.env.cr, module, xml_id)
diff --git a/upgrade_analysis/upgrade_log.py b/upgrade_analysis/upgrade_log.py
index 3a8d13127..bfab4e55b 100644
--- a/upgrade_analysis/upgrade_log.py
+++ b/upgrade_analysis/upgrade_log.py
@@ -165,7 +165,10 @@ def log_model(model, local_registry):
def log_xml_id(cr, module, xml_id):
"""
Log xml_ids at load time in the records table.
- Called from tools/convert.py:xml_import._test_xml_id()
+ Called from:
+ - tools/convert.py:xml_import._test_xml_id()
+ - odoo/models.py:BaseModel._convert_records()
+ - odoo/addons/base/models/ir_model.py:IrModelConstraint._reflect_model()
# Catcha's
- The module needs to be loaded with 'init', or the calling method
diff --git a/upgrade_analysis/wizards/upgrade_generate_record_wizard.py b/upgrade_analysis/wizards/upgrade_generate_record_wizard.py
index 3a766b1b1..0fd0464d6 100644
--- a/upgrade_analysis/wizards/upgrade_generate_record_wizard.py
+++ b/upgrade_analysis/wizards/upgrade_generate_record_wizard.py
@@ -72,6 +72,24 @@ class GenerateWizard(models.TransientModel):
]
)
+ # Set constraint definition
+ self.env.cr.execute(
+ """ UPDATE upgrade_record our
+ SET definition = btrim(replace(replace(replace(replace(
+ imc.definition, chr(9), ' '), chr(10), ' '), ' ', ' '), ' ', ' '))
+ FROM ir_model_data imd
+ JOIN ir_model_constraint imc ON imd.res_id = imc.id
+ WHERE our.type = 'xmlid'
+ AND imd.model = 'ir.model.constraint'
+ AND our.model = imd.model
+ AND our.name = imd.module || '.' || imd.name"""
+ )
+ self.env.cache.invalidate(
+ [
+ (self.env["upgrade.record"]._fields["definition"], None),
+ ]
+ )
+
# Set noupdate property from ir_model_data
self.env.cr.execute(
""" UPDATE upgrade_record our
From 684fcff90e4a68883b82e42b42ed0ad23ea0e82a Mon Sep 17 00:00:00 2001
From: oca-ci
Date: Mon, 18 Jul 2022 10:37:38 +0000
Subject: [PATCH 59/67] [UPD] Update upgrade_analysis.pot
---
upgrade_analysis/i18n/upgrade_analysis.pot | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/upgrade_analysis/i18n/upgrade_analysis.pot b/upgrade_analysis/i18n/upgrade_analysis.pot
index 2b4f5e051..0fdfaae71 100644
--- a/upgrade_analysis/i18n/upgrade_analysis.pot
+++ b/upgrade_analysis/i18n/upgrade_analysis.pot
@@ -141,6 +141,11 @@ msgstr ""
msgid "Database"
msgstr ""
+#. module: upgrade_analysis
+#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_record__definition
+msgid "Definition"
+msgstr ""
+
#. module: upgrade_analysis
#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_analysis__display_name
#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_attribute__display_name
From 76eef21a87596e2d08e91773d2d5cece80557cf1 Mon Sep 17 00:00:00 2001
From: OCA-git-bot
Date: Mon, 18 Jul 2022 10:41:22 +0000
Subject: [PATCH 60/67] upgrade_analysis 15.0.2.0.0
---
upgrade_analysis/__manifest__.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/upgrade_analysis/__manifest__.py b/upgrade_analysis/__manifest__.py
index 017ab77ab..39ef860d0 100644
--- a/upgrade_analysis/__manifest__.py
+++ b/upgrade_analysis/__manifest__.py
@@ -5,7 +5,7 @@
"name": "Upgrade Analysis",
"summary": "Performs a difference analysis between modules"
" installed on two different Odoo instances",
- "version": "15.0.1.0.4",
+ "version": "15.0.2.0.0",
"category": "Migration",
"author": "Therp BV, Opener B.V., GRAP, Odoo Community Association (OCA)",
"maintainers": ["StefanRijnhart", "legalsylvain"],
From 8c6ea5cf6faf22f5fdcca886d9cc4543ffdcaffa Mon Sep 17 00:00:00 2001
From: OCA Transbot
Date: Mon, 18 Jul 2022 10:41:30 +0000
Subject: [PATCH 61/67] Update translation files
Updated by "Update PO files to match POT (msgmerge)" hook in Weblate.
Translation: server-tools-15.0/server-tools-15.0-upgrade_analysis
Translate-URL: https://translation.odoo-community.org/projects/server-tools-15-0/server-tools-15-0-upgrade_analysis/
---
upgrade_analysis/i18n/fr.po | 25 ++++++++-----------------
1 file changed, 8 insertions(+), 17 deletions(-)
diff --git a/upgrade_analysis/i18n/fr.po b/upgrade_analysis/i18n/fr.po
index 234427e4a..4bc6821e0 100644
--- a/upgrade_analysis/i18n/fr.po
+++ b/upgrade_analysis/i18n/fr.po
@@ -106,7 +106,7 @@ msgstr ""
#. module: upgrade_analysis
#: code:addons/upgrade_analysis/models/upgrade_comparison_config.py:0
#, python-format
-msgid "Could not connect the Odoo server at %s:%s"
+msgid "Could not connect the Odoo server at %(server)s:%(port)s"
msgstr ""
#. module: upgrade_analysis
@@ -145,7 +145,11 @@ msgid "Database"
msgstr ""
#. module: upgrade_analysis
-#: model:ir.model.fields,field_description:upgrade_analysis.field_ir_module_module__display_name
+#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_record__definition
+msgid "Definition"
+msgstr ""
+
+#. module: upgrade_analysis
#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_analysis__display_name
#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_attribute__display_name
#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_comparison_config__display_name
@@ -186,7 +190,6 @@ msgid "Generate Records Wizard"
msgstr ""
#. module: upgrade_analysis
-#: model:ir.model.fields,field_description:upgrade_analysis.field_ir_module_module__id
#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_analysis__id
#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_attribute__id
#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_comparison_config__id
@@ -218,7 +221,6 @@ msgid "Is Odoo Module"
msgstr ""
#. module: upgrade_analysis
-#: model:ir.model.fields,field_description:upgrade_analysis.field_ir_module_module____last_update
#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_analysis____last_update
#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_attribute____last_update
#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_comparison_config____last_update
@@ -317,7 +319,7 @@ msgstr ""
#. module: upgrade_analysis
#: code:addons/upgrade_analysis/models/upgrade_record.py:0
#, python-format
-msgid "No manifest found in %s"
+msgid "No manifest found in %(addon_dir)s"
msgstr ""
#. module: upgrade_analysis
@@ -367,17 +369,6 @@ msgid ""
"modifies an attribute of an existing field, set to Modify."
msgstr ""
-#. module: upgrade_analysis
-#: model:ir.model.fields,field_description:upgrade_analysis.field_ir_module_module__smart_search
-#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_analysis__smart_search
-#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_attribute__smart_search
-#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_comparison_config__smart_search
-#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_generate_record_wizard__smart_search
-#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_install_wizard__smart_search
-#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_record__smart_search
-msgid "Smart Search"
-msgstr ""
-
#. module: upgrade_analysis
#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_analysis__state
#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_generate_record_wizard__state
@@ -430,7 +421,7 @@ msgstr ""
#. module: upgrade_analysis
#: code:addons/upgrade_analysis/models/upgrade_analysis.py:0
#, python-format
-msgid "Unexpected root Element: %s in file: %s"
+msgid "Unexpected root Element: %(root)s in file: %(file)s"
msgstr ""
#. module: upgrade_analysis
From 9a4834d14ada5a0e49ac312907ce2f3d37ef3f82 Mon Sep 17 00:00:00 2001
From: Ignacio Buioli
Date: Sun, 4 Sep 2022 03:50:33 +0000
Subject: [PATCH 62/67] Added translation using Weblate (Spanish (Argentina))
---
upgrade_analysis/i18n/es_AR.po | 518 +++++++++++++++++++++++++++++++++
1 file changed, 518 insertions(+)
create mode 100644 upgrade_analysis/i18n/es_AR.po
diff --git a/upgrade_analysis/i18n/es_AR.po b/upgrade_analysis/i18n/es_AR.po
new file mode 100644
index 000000000..447536233
--- /dev/null
+++ b/upgrade_analysis/i18n/es_AR.po
@@ -0,0 +1,518 @@
+# Translation of Odoo Server.
+# This file contains the translation of the following modules:
+# * upgrade_analysis
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: Odoo Server 15.0\n"
+"Report-Msgid-Bugs-To: \n"
+"Last-Translator: Automatically generated\n"
+"Language-Team: none\n"
+"Language: es_AR\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: \n"
+"Plural-Forms: nplurals=2; plural=n != 1;\n"
+
+#. module: upgrade_analysis
+#: model_terms:ir.ui.view,arch_db:upgrade_analysis.view_upgrade_install_wizard_form
+msgid "All Modules"
+msgstr ""
+
+#. module: upgrade_analysis
+#: model_terms:ir.ui.view,arch_db:upgrade_analysis.view_upgrade_install_wizard_form
+msgid "All OCA Modules"
+msgstr ""
+
+#. module: upgrade_analysis
+#: model_terms:ir.ui.view,arch_db:upgrade_analysis.view_upgrade_install_wizard_form
+msgid "All Odoo SA Modules"
+msgstr ""
+
+#. module: upgrade_analysis
+#: model_terms:ir.ui.view,arch_db:upgrade_analysis.view_upgrade_install_wizard_form
+msgid "All Other Modules"
+msgstr ""
+
+#. module: upgrade_analysis
+#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_comparison_config__analysis_ids
+#: model_terms:ir.ui.view,arch_db:upgrade_analysis.view_upgrade_comparison_config_form
+msgid "Analyses"
+msgstr ""
+
+#. module: upgrade_analysis
+#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_analysis__analysis_date
+msgid "Analysis Date"
+msgstr ""
+
+#. module: upgrade_analysis
+#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_comparison_config__analysis_qty
+msgid "Analysis Qty"
+msgstr ""
+
+#. module: upgrade_analysis
+#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_record__attribute_ids
+msgid "Attribute"
+msgstr ""
+
+#. module: upgrade_analysis
+#: model_terms:ir.ui.view,arch_db:upgrade_analysis.view_upgrade_record_form
+msgid "Attributes"
+msgstr ""
+
+#. module: upgrade_analysis
+#: code:addons/upgrade_analysis/wizards/upgrade_generate_record_wizard.py:0
+#, python-format
+msgid "Cannot seem to install or upgrade modules %s"
+msgstr ""
+
+#. module: upgrade_analysis
+#: model_terms:ir.ui.view,arch_db:upgrade_analysis.view_upgrade_install_wizard_form
+msgid "Clear the list"
+msgstr ""
+
+#. module: upgrade_analysis
+#: model_terms:ir.ui.view,arch_db:upgrade_analysis.view_upgrade_generate_record_wizard_form
+#: model_terms:ir.ui.view,arch_db:upgrade_analysis.view_upgrade_install_wizard_form
+msgid "Close"
+msgstr ""
+
+#. module: upgrade_analysis
+#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_analysis__config_id
+msgid "Comparison Config"
+msgstr ""
+
+#. module: upgrade_analysis
+#: model:ir.ui.menu,name:upgrade_analysis.menu_upgrade_comparison_config
+msgid "Comparison Configurations"
+msgstr ""
+
+#. module: upgrade_analysis
+#: code:addons/upgrade_analysis/models/upgrade_comparison_config.py:0
+#, python-format
+msgid ""
+"Connection failed.\n"
+"\n"
+"DETAIL: %s"
+msgstr ""
+
+#. module: upgrade_analysis
+#: model_terms:ir.ui.view,arch_db:upgrade_analysis.view_upgrade_generate_record_wizard_form
+msgid "Continue"
+msgstr ""
+
+#. module: upgrade_analysis
+#: code:addons/upgrade_analysis/models/upgrade_comparison_config.py:0
+#, python-format
+msgid "Could not connect the Odoo server at %(server)s:%(port)s"
+msgstr ""
+
+#. module: upgrade_analysis
+#: model:ir.model.fields.selection,name:upgrade_analysis.selection__upgrade_record__mode__create
+msgid "Create"
+msgstr ""
+
+#. module: upgrade_analysis
+#: model_terms:ir.ui.view,arch_db:upgrade_analysis.view_upgrade_record_search
+msgid "Create Mode"
+msgstr ""
+
+#. module: upgrade_analysis
+#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_analysis__create_uid
+#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_attribute__create_uid
+#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_comparison_config__create_uid
+#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_generate_record_wizard__create_uid
+#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_install_wizard__create_uid
+#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_record__create_uid
+msgid "Created by"
+msgstr ""
+
+#. module: upgrade_analysis
+#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_analysis__create_date
+#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_attribute__create_date
+#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_comparison_config__create_date
+#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_generate_record_wizard__create_date
+#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_install_wizard__create_date
+#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_record__create_date
+msgid "Created on"
+msgstr ""
+
+#. module: upgrade_analysis
+#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_comparison_config__database
+msgid "Database"
+msgstr ""
+
+#. module: upgrade_analysis
+#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_record__definition
+msgid "Definition"
+msgstr ""
+
+#. module: upgrade_analysis
+#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_analysis__display_name
+#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_attribute__display_name
+#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_comparison_config__display_name
+#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_generate_record_wizard__display_name
+#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_install_wizard__display_name
+#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_record__display_name
+msgid "Display Name"
+msgstr ""
+
+#. module: upgrade_analysis
+#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_record__domain
+msgid "Domain"
+msgstr ""
+
+#. module: upgrade_analysis
+#: model:ir.model.fields.selection,name:upgrade_analysis.selection__upgrade_analysis__state__done
+#: model:ir.model.fields.selection,name:upgrade_analysis.selection__upgrade_generate_record_wizard__state__done
+#: model:ir.model.fields.selection,name:upgrade_analysis.selection__upgrade_install_wizard__state__done
+msgid "Done"
+msgstr ""
+
+#. module: upgrade_analysis
+#: model:ir.model.fields.selection,name:upgrade_analysis.selection__upgrade_generate_record_wizard__state__draft
+#: model:ir.model.fields.selection,name:upgrade_analysis.selection__upgrade_install_wizard__state__draft
+msgid "Draft"
+msgstr ""
+
+#. module: upgrade_analysis
+#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_record__field
+#: model:ir.model.fields.selection,name:upgrade_analysis.selection__upgrade_record__type__field
+msgid "Field"
+msgstr ""
+
+#. module: upgrade_analysis
+#: model:ir.actions.act_window,name:upgrade_analysis.action_upgrade_generate_record_wizard
+#: model:ir.ui.menu,name:upgrade_analysis.menu_upgrade_generate_record
+msgid "Generate Records Wizard"
+msgstr ""
+
+#. module: upgrade_analysis
+#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_analysis__id
+#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_attribute__id
+#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_comparison_config__id
+#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_generate_record_wizard__id
+#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_install_wizard__id
+#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_record__id
+msgid "ID"
+msgstr ""
+
+#. module: upgrade_analysis
+#: model_terms:ir.ui.view,arch_db:upgrade_analysis.view_upgrade_install_wizard_form
+msgid "Install Modules"
+msgstr ""
+
+#. module: upgrade_analysis
+#: model:ir.actions.act_window,name:upgrade_analysis.action_upgrade_install_wizard
+#: model:ir.ui.menu,name:upgrade_analysis.menu_upgrade_install
+msgid "Install Modules Wizard"
+msgstr ""
+
+#. module: upgrade_analysis
+#: model:ir.model.fields,field_description:upgrade_analysis.field_ir_module_module__is_oca_module
+msgid "Is Oca Module"
+msgstr ""
+
+#. module: upgrade_analysis
+#: model:ir.model.fields,field_description:upgrade_analysis.field_ir_module_module__is_odoo_module
+msgid "Is Odoo Module"
+msgstr ""
+
+#. module: upgrade_analysis
+#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_analysis____last_update
+#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_attribute____last_update
+#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_comparison_config____last_update
+#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_generate_record_wizard____last_update
+#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_install_wizard____last_update
+#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_record____last_update
+msgid "Last Modified on"
+msgstr ""
+
+#. module: upgrade_analysis
+#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_analysis__write_uid
+#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_attribute__write_uid
+#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_comparison_config__write_uid
+#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_generate_record_wizard__write_uid
+#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_install_wizard__write_uid
+#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_record__write_uid
+msgid "Last Updated by"
+msgstr ""
+
+#. module: upgrade_analysis
+#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_analysis__write_date
+#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_attribute__write_date
+#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_comparison_config__write_date
+#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_generate_record_wizard__write_date
+#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_install_wizard__write_date
+#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_record__write_date
+msgid "Last Updated on"
+msgstr ""
+
+#. module: upgrade_analysis
+#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_analysis__log
+#: model_terms:ir.ui.view,arch_db:upgrade_analysis.view_upgrade_analysis_form
+msgid "Log"
+msgstr ""
+
+#. module: upgrade_analysis
+#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_record__mode
+msgid "Mode"
+msgstr ""
+
+#. module: upgrade_analysis
+#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_record__model
+#: model:ir.model.fields.selection,name:upgrade_analysis.selection__upgrade_record__type__model
+msgid "Model"
+msgstr ""
+
+#. module: upgrade_analysis
+#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_record__model_original_module
+msgid "Model Original Module"
+msgstr ""
+
+#. module: upgrade_analysis
+#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_record__model_type
+msgid "Model Type"
+msgstr ""
+
+#. module: upgrade_analysis
+#: model:ir.model.fields.selection,name:upgrade_analysis.selection__upgrade_record__mode__modify
+msgid "Modify"
+msgstr ""
+
+#. module: upgrade_analysis
+#: model_terms:ir.ui.view,arch_db:upgrade_analysis.view_upgrade_record_search
+msgid "Modify Mode"
+msgstr ""
+
+#. module: upgrade_analysis
+#: model:ir.model,name:upgrade_analysis.model_ir_module_module
+#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_install_wizard__module_ids
+#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_record__module
+msgid "Module"
+msgstr ""
+
+#. module: upgrade_analysis
+#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_install_wizard__module_qty
+msgid "Modules Quantity"
+msgstr ""
+
+#. module: upgrade_analysis
+#: model_terms:ir.ui.view,arch_db:upgrade_analysis.view_upgrade_generate_record_wizard_form
+msgid "Modules initialized and record created"
+msgstr ""
+
+#. module: upgrade_analysis
+#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_attribute__name
+#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_comparison_config__name
+#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_record__name
+msgid "Name"
+msgstr ""
+
+#. module: upgrade_analysis
+#: model_terms:ir.ui.view,arch_db:upgrade_analysis.view_upgrade_comparison_config_form
+msgid "New Analysis"
+msgstr ""
+
+#. module: upgrade_analysis
+#: code:addons/upgrade_analysis/models/upgrade_record.py:0
+#, python-format
+msgid "No manifest found in %(addon_dir)s"
+msgstr ""
+
+#. module: upgrade_analysis
+#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_record__noupdate
+msgid "Noupdate"
+msgstr ""
+
+#. module: upgrade_analysis
+#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_comparison_config__password
+msgid "Password"
+msgstr ""
+
+#. module: upgrade_analysis
+#: model_terms:ir.ui.view,arch_db:upgrade_analysis.view_upgrade_analysis_form
+msgid "Perform Analysis"
+msgstr ""
+
+#. module: upgrade_analysis
+#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_comparison_config__port
+msgid "Port"
+msgstr ""
+
+#. module: upgrade_analysis
+#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_record__prefix
+msgid "Prefix"
+msgstr ""
+
+#. module: upgrade_analysis
+#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_attribute__record_id
+msgid "Record"
+msgstr ""
+
+#. module: upgrade_analysis
+#: model:ir.ui.menu,name:upgrade_analysis.menu_upgrade_records
+msgid "Records"
+msgstr ""
+
+#. module: upgrade_analysis
+#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_comparison_config__server
+msgid "Server"
+msgstr ""
+
+#. module: upgrade_analysis
+#: model:ir.model.fields,help:upgrade_analysis.field_upgrade_record__mode
+msgid ""
+"Set to Create if a field is newly created in this module. If this module "
+"modifies an attribute of an existing field, set to Modify."
+msgstr ""
+
+#. module: upgrade_analysis
+#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_analysis__state
+#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_generate_record_wizard__state
+#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_install_wizard__state
+msgid "State"
+msgstr ""
+
+#. module: upgrade_analysis
+#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_record__suffix
+msgid "Suffix"
+msgstr ""
+
+#. module: upgrade_analysis
+#: model_terms:ir.ui.view,arch_db:upgrade_analysis.view_upgrade_comparison_config_form
+msgid "Test Connection"
+msgstr ""
+
+#. module: upgrade_analysis
+#: model:ir.model.fields,help:upgrade_analysis.field_upgrade_analysis__upgrade_path
+msgid ""
+"The base file path to save the analyse files of Odoo modules. Taken from "
+"Odoo's --upgrade-path command line option or the 'scripts' subdirectory in "
+"the openupgrade_scripts addon."
+msgstr ""
+
+#. module: upgrade_analysis
+#: model_terms:ir.ui.view,arch_db:upgrade_analysis.view_upgrade_install_wizard_form
+msgid "The modules have been installed successfuly"
+msgstr ""
+
+#. module: upgrade_analysis
+#: model_terms:ir.ui.view,arch_db:upgrade_analysis.view_upgrade_install_wizard_form
+msgid ""
+"This will install the selected modules on the database. Do not continue if "
+"you use this database in production."
+msgstr ""
+
+#. module: upgrade_analysis
+#: model_terms:ir.ui.view,arch_db:upgrade_analysis.view_upgrade_generate_record_wizard_form
+msgid ""
+"This will reinitialize all the modules installed on this database. Do not "
+"continue if you use this database in production."
+msgstr ""
+
+#. module: upgrade_analysis
+#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_record__type
+msgid "Type"
+msgstr ""
+
+#. module: upgrade_analysis
+#: code:addons/upgrade_analysis/models/upgrade_analysis.py:0
+#, python-format
+msgid "Unexpected root Element: %(root)s in file: %(file)s"
+msgstr ""
+
+#. module: upgrade_analysis
+#: model:ir.actions.act_window,name:upgrade_analysis.action_upgrade_analysis_tree
+#: model:ir.model,name:upgrade_analysis.model_upgrade_analysis
+#: model:ir.ui.menu,name:upgrade_analysis.menu_upgrade_analysis
+msgid "Upgrade Analyses"
+msgstr ""
+
+#. module: upgrade_analysis
+#: model:ir.ui.menu,name:upgrade_analysis.menu_upgrade
+msgid "Upgrade Analysis"
+msgstr ""
+
+#. module: upgrade_analysis
+#: model:ir.model,name:upgrade_analysis.model_upgrade_attribute
+msgid "Upgrade Attribute"
+msgstr ""
+
+#. module: upgrade_analysis
+#: model:ir.model,name:upgrade_analysis.model_upgrade_comparison_config
+msgid "Upgrade Comparison Configuration"
+msgstr ""
+
+#. module: upgrade_analysis
+#: model:ir.model,name:upgrade_analysis.model_upgrade_generate_record_wizard
+msgid "Upgrade Generate Record Wizard"
+msgstr ""
+
+#. module: upgrade_analysis
+#: model:ir.model,name:upgrade_analysis.model_upgrade_install_wizard
+msgid "Upgrade Install Wizard"
+msgstr ""
+
+#. module: upgrade_analysis
+#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_analysis__upgrade_path
+msgid "Upgrade Path"
+msgstr ""
+
+#. module: upgrade_analysis
+#: model:ir.model,name:upgrade_analysis.model_upgrade_record
+msgid "Upgrade Record"
+msgstr ""
+
+#. module: upgrade_analysis
+#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_comparison_config__username
+msgid "Username"
+msgstr ""
+
+#. module: upgrade_analysis
+#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_attribute__value
+msgid "Value"
+msgstr ""
+
+#. module: upgrade_analysis
+#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_comparison_config__version
+msgid "Version"
+msgstr ""
+
+#. module: upgrade_analysis
+#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_analysis__write_files
+msgid "Write Files"
+msgstr ""
+
+#. module: upgrade_analysis
+#: model:ir.model.fields,help:upgrade_analysis.field_upgrade_analysis__write_files
+msgid "Write analysis files to the module directories"
+msgstr ""
+
+#. module: upgrade_analysis
+#: model:ir.model.fields.selection,name:upgrade_analysis.selection__upgrade_record__type__xmlid
+msgid "XML ID"
+msgstr ""
+
+#. module: upgrade_analysis
+#: code:addons/upgrade_analysis/models/upgrade_comparison_config.py:0
+#, python-format
+msgid ""
+"You are correctly connected to the server %(server)s (version %(version)s) "
+"with the user %(user_name)s"
+msgstr ""
+
+#. module: upgrade_analysis
+#: model:ir.model.fields.selection,name:upgrade_analysis.selection__upgrade_analysis__state__draft
+msgid "draft"
+msgstr ""
+
+#. module: upgrade_analysis
+#: model:ir.actions.act_window,name:upgrade_analysis.action_upgrade_comparison_config_tree
+msgid "upgrade Comparison Configs"
+msgstr ""
+
+#. module: upgrade_analysis
+#: model:ir.actions.act_window,name:upgrade_analysis.action_upgrade_record_tree
+msgid "upgrade Records"
+msgstr ""
From 4675fb77db665976fe92f3c7d67e6ec61b9cae74 Mon Sep 17 00:00:00 2001
From: Ignacio Buioli
Date: Sun, 4 Sep 2022 04:20:41 +0000
Subject: [PATCH 63/67] Translated using Weblate (Spanish (Argentina))
Currently translated at 100.0% (86 of 86 strings)
Translation: server-tools-15.0/server-tools-15.0-upgrade_analysis
Translate-URL: https://translation.odoo-community.org/projects/server-tools-15-0/server-tools-15-0-upgrade_analysis/es_AR/
---
upgrade_analysis/i18n/es_AR.po | 179 ++++++++++++++++++---------------
1 file changed, 98 insertions(+), 81 deletions(-)
diff --git a/upgrade_analysis/i18n/es_AR.po b/upgrade_analysis/i18n/es_AR.po
index 447536233..73cf7b78e 100644
--- a/upgrade_analysis/i18n/es_AR.po
+++ b/upgrade_analysis/i18n/es_AR.po
@@ -6,86 +6,88 @@ msgid ""
msgstr ""
"Project-Id-Version: Odoo Server 15.0\n"
"Report-Msgid-Bugs-To: \n"
-"Last-Translator: Automatically generated\n"
+"PO-Revision-Date: 2022-09-04 06:07+0000\n"
+"Last-Translator: Ignacio Buioli \n"
"Language-Team: none\n"
"Language: es_AR\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: \n"
"Plural-Forms: nplurals=2; plural=n != 1;\n"
+"X-Generator: Weblate 4.3.2\n"
#. module: upgrade_analysis
#: model_terms:ir.ui.view,arch_db:upgrade_analysis.view_upgrade_install_wizard_form
msgid "All Modules"
-msgstr ""
+msgstr "Todos los Módulos"
#. module: upgrade_analysis
#: model_terms:ir.ui.view,arch_db:upgrade_analysis.view_upgrade_install_wizard_form
msgid "All OCA Modules"
-msgstr ""
+msgstr "Todos los Módulos de OCA"
#. module: upgrade_analysis
#: model_terms:ir.ui.view,arch_db:upgrade_analysis.view_upgrade_install_wizard_form
msgid "All Odoo SA Modules"
-msgstr ""
+msgstr "Todos los Módulos de Odoo SA"
#. module: upgrade_analysis
#: model_terms:ir.ui.view,arch_db:upgrade_analysis.view_upgrade_install_wizard_form
msgid "All Other Modules"
-msgstr ""
+msgstr "Todos los Otros Módulos"
#. module: upgrade_analysis
#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_comparison_config__analysis_ids
#: model_terms:ir.ui.view,arch_db:upgrade_analysis.view_upgrade_comparison_config_form
msgid "Analyses"
-msgstr ""
+msgstr "Análisis"
#. module: upgrade_analysis
#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_analysis__analysis_date
msgid "Analysis Date"
-msgstr ""
+msgstr "Fecha de Análisis"
#. module: upgrade_analysis
#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_comparison_config__analysis_qty
msgid "Analysis Qty"
-msgstr ""
+msgstr "Análisis de Cantidad"
#. module: upgrade_analysis
#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_record__attribute_ids
msgid "Attribute"
-msgstr ""
+msgstr "Atributo"
#. module: upgrade_analysis
#: model_terms:ir.ui.view,arch_db:upgrade_analysis.view_upgrade_record_form
msgid "Attributes"
-msgstr ""
+msgstr "Atributos"
#. module: upgrade_analysis
#: code:addons/upgrade_analysis/wizards/upgrade_generate_record_wizard.py:0
#, python-format
msgid "Cannot seem to install or upgrade modules %s"
-msgstr ""
+msgstr "Parece que no se pueden instalar o actualizar los módulos %s"
#. module: upgrade_analysis
#: model_terms:ir.ui.view,arch_db:upgrade_analysis.view_upgrade_install_wizard_form
msgid "Clear the list"
-msgstr ""
+msgstr "Limpiar la lista"
#. module: upgrade_analysis
#: model_terms:ir.ui.view,arch_db:upgrade_analysis.view_upgrade_generate_record_wizard_form
#: model_terms:ir.ui.view,arch_db:upgrade_analysis.view_upgrade_install_wizard_form
msgid "Close"
-msgstr ""
+msgstr "Cerrar"
#. module: upgrade_analysis
#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_analysis__config_id
msgid "Comparison Config"
-msgstr ""
+msgstr "Configuración de Comparación"
#. module: upgrade_analysis
#: model:ir.ui.menu,name:upgrade_analysis.menu_upgrade_comparison_config
msgid "Comparison Configurations"
-msgstr ""
+msgstr "Configuraciones de Comparación"
#. module: upgrade_analysis
#: code:addons/upgrade_analysis/models/upgrade_comparison_config.py:0
@@ -95,27 +97,30 @@ msgid ""
"\n"
"DETAIL: %s"
msgstr ""
+"Conexión fallida.\n"
+"\n"
+"DETALLES: %s"
#. module: upgrade_analysis
#: model_terms:ir.ui.view,arch_db:upgrade_analysis.view_upgrade_generate_record_wizard_form
msgid "Continue"
-msgstr ""
+msgstr "Continuar"
#. module: upgrade_analysis
#: code:addons/upgrade_analysis/models/upgrade_comparison_config.py:0
#, python-format
msgid "Could not connect the Odoo server at %(server)s:%(port)s"
-msgstr ""
+msgstr "No es posible conectar al servidor de Odoo en %(server)s:%(port)s"
#. module: upgrade_analysis
#: model:ir.model.fields.selection,name:upgrade_analysis.selection__upgrade_record__mode__create
msgid "Create"
-msgstr ""
+msgstr "Crear"
#. module: upgrade_analysis
#: model_terms:ir.ui.view,arch_db:upgrade_analysis.view_upgrade_record_search
msgid "Create Mode"
-msgstr ""
+msgstr "Modo de Creación"
#. module: upgrade_analysis
#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_analysis__create_uid
@@ -125,7 +130,7 @@ msgstr ""
#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_install_wizard__create_uid
#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_record__create_uid
msgid "Created by"
-msgstr ""
+msgstr "Creado por"
#. module: upgrade_analysis
#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_analysis__create_date
@@ -135,17 +140,17 @@ msgstr ""
#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_install_wizard__create_date
#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_record__create_date
msgid "Created on"
-msgstr ""
+msgstr "Creado en"
#. module: upgrade_analysis
#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_comparison_config__database
msgid "Database"
-msgstr ""
+msgstr "Base de Datos"
#. module: upgrade_analysis
#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_record__definition
msgid "Definition"
-msgstr ""
+msgstr "Definición"
#. module: upgrade_analysis
#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_analysis__display_name
@@ -155,37 +160,37 @@ msgstr ""
#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_install_wizard__display_name
#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_record__display_name
msgid "Display Name"
-msgstr ""
+msgstr "Mostrar Nombre"
#. module: upgrade_analysis
#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_record__domain
msgid "Domain"
-msgstr ""
+msgstr "Dominio"
#. module: upgrade_analysis
#: model:ir.model.fields.selection,name:upgrade_analysis.selection__upgrade_analysis__state__done
#: model:ir.model.fields.selection,name:upgrade_analysis.selection__upgrade_generate_record_wizard__state__done
#: model:ir.model.fields.selection,name:upgrade_analysis.selection__upgrade_install_wizard__state__done
msgid "Done"
-msgstr ""
+msgstr "Hecho"
#. module: upgrade_analysis
#: model:ir.model.fields.selection,name:upgrade_analysis.selection__upgrade_generate_record_wizard__state__draft
#: model:ir.model.fields.selection,name:upgrade_analysis.selection__upgrade_install_wizard__state__draft
msgid "Draft"
-msgstr ""
+msgstr "Borrador"
#. module: upgrade_analysis
#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_record__field
#: model:ir.model.fields.selection,name:upgrade_analysis.selection__upgrade_record__type__field
msgid "Field"
-msgstr ""
+msgstr "Campo"
#. module: upgrade_analysis
#: model:ir.actions.act_window,name:upgrade_analysis.action_upgrade_generate_record_wizard
#: model:ir.ui.menu,name:upgrade_analysis.menu_upgrade_generate_record
msgid "Generate Records Wizard"
-msgstr ""
+msgstr "Asistente de Generación de Registros"
#. module: upgrade_analysis
#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_analysis__id
@@ -195,28 +200,28 @@ msgstr ""
#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_install_wizard__id
#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_record__id
msgid "ID"
-msgstr ""
+msgstr "ID"
#. module: upgrade_analysis
#: model_terms:ir.ui.view,arch_db:upgrade_analysis.view_upgrade_install_wizard_form
msgid "Install Modules"
-msgstr ""
+msgstr "Instalar Módulos"
#. module: upgrade_analysis
#: model:ir.actions.act_window,name:upgrade_analysis.action_upgrade_install_wizard
#: model:ir.ui.menu,name:upgrade_analysis.menu_upgrade_install
msgid "Install Modules Wizard"
-msgstr ""
+msgstr "Asistente de Instalación de Módulos"
#. module: upgrade_analysis
#: model:ir.model.fields,field_description:upgrade_analysis.field_ir_module_module__is_oca_module
msgid "Is Oca Module"
-msgstr ""
+msgstr "Es un Módulo de OCA"
#. module: upgrade_analysis
#: model:ir.model.fields,field_description:upgrade_analysis.field_ir_module_module__is_odoo_module
msgid "Is Odoo Module"
-msgstr ""
+msgstr "Es un Módulo de Odoo"
#. module: upgrade_analysis
#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_analysis____last_update
@@ -226,7 +231,7 @@ msgstr ""
#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_install_wizard____last_update
#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_record____last_update
msgid "Last Modified on"
-msgstr ""
+msgstr "Última modificación en"
#. module: upgrade_analysis
#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_analysis__write_uid
@@ -236,7 +241,7 @@ msgstr ""
#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_install_wizard__write_uid
#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_record__write_uid
msgid "Last Updated by"
-msgstr ""
+msgstr "Última actualización realizada por"
#. module: upgrade_analysis
#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_analysis__write_date
@@ -246,119 +251,119 @@ msgstr ""
#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_install_wizard__write_date
#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_record__write_date
msgid "Last Updated on"
-msgstr ""
+msgstr "Última actualización el"
#. module: upgrade_analysis
#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_analysis__log
#: model_terms:ir.ui.view,arch_db:upgrade_analysis.view_upgrade_analysis_form
msgid "Log"
-msgstr ""
+msgstr "Registro"
#. module: upgrade_analysis
#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_record__mode
msgid "Mode"
-msgstr ""
+msgstr "Modo"
#. module: upgrade_analysis
#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_record__model
#: model:ir.model.fields.selection,name:upgrade_analysis.selection__upgrade_record__type__model
msgid "Model"
-msgstr ""
+msgstr "Modelo"
#. module: upgrade_analysis
#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_record__model_original_module
msgid "Model Original Module"
-msgstr ""
+msgstr "Modelo de Módulo Original"
#. module: upgrade_analysis
#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_record__model_type
msgid "Model Type"
-msgstr ""
+msgstr "Tipo de Modelo"
#. module: upgrade_analysis
#: model:ir.model.fields.selection,name:upgrade_analysis.selection__upgrade_record__mode__modify
msgid "Modify"
-msgstr ""
+msgstr "Modificar"
#. module: upgrade_analysis
#: model_terms:ir.ui.view,arch_db:upgrade_analysis.view_upgrade_record_search
msgid "Modify Mode"
-msgstr ""
+msgstr "Modo de Modificación"
#. module: upgrade_analysis
#: model:ir.model,name:upgrade_analysis.model_ir_module_module
#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_install_wizard__module_ids
#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_record__module
msgid "Module"
-msgstr ""
+msgstr "Módulo"
#. module: upgrade_analysis
#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_install_wizard__module_qty
msgid "Modules Quantity"
-msgstr ""
+msgstr "Cantidad de Módulos"
#. module: upgrade_analysis
#: model_terms:ir.ui.view,arch_db:upgrade_analysis.view_upgrade_generate_record_wizard_form
msgid "Modules initialized and record created"
-msgstr ""
+msgstr "Módulos inicializados y registros creados"
#. module: upgrade_analysis
#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_attribute__name
#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_comparison_config__name
#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_record__name
msgid "Name"
-msgstr ""
+msgstr "Nombre"
#. module: upgrade_analysis
#: model_terms:ir.ui.view,arch_db:upgrade_analysis.view_upgrade_comparison_config_form
msgid "New Analysis"
-msgstr ""
+msgstr "Nuevo Análisis"
#. module: upgrade_analysis
#: code:addons/upgrade_analysis/models/upgrade_record.py:0
#, python-format
msgid "No manifest found in %(addon_dir)s"
-msgstr ""
+msgstr "No se encontró manifiesta en %(addon_dir)s"
#. module: upgrade_analysis
#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_record__noupdate
msgid "Noupdate"
-msgstr ""
+msgstr "Noupdate"
#. module: upgrade_analysis
#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_comparison_config__password
msgid "Password"
-msgstr ""
+msgstr "Contraseña"
#. module: upgrade_analysis
#: model_terms:ir.ui.view,arch_db:upgrade_analysis.view_upgrade_analysis_form
msgid "Perform Analysis"
-msgstr ""
+msgstr "Realizar Análisis"
#. module: upgrade_analysis
#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_comparison_config__port
msgid "Port"
-msgstr ""
+msgstr "Puerto"
#. module: upgrade_analysis
#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_record__prefix
msgid "Prefix"
-msgstr ""
+msgstr "Prefijo"
#. module: upgrade_analysis
#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_attribute__record_id
msgid "Record"
-msgstr ""
+msgstr "Registro"
#. module: upgrade_analysis
#: model:ir.ui.menu,name:upgrade_analysis.menu_upgrade_records
msgid "Records"
-msgstr ""
+msgstr "Registros"
#. module: upgrade_analysis
#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_comparison_config__server
msgid "Server"
-msgstr ""
+msgstr "Servidor"
#. module: upgrade_analysis
#: model:ir.model.fields,help:upgrade_analysis.field_upgrade_record__mode
@@ -366,23 +371,26 @@ msgid ""
"Set to Create if a field is newly created in this module. If this module "
"modifies an attribute of an existing field, set to Modify."
msgstr ""
+"Establézcalo en Crear si se crea un campo recientemente en este módulo. Si "
+"este módulo modifica un atributo de un campo existente, configúrelo en "
+"Modificar."
#. module: upgrade_analysis
#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_analysis__state
#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_generate_record_wizard__state
#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_install_wizard__state
msgid "State"
-msgstr ""
+msgstr "Estado"
#. module: upgrade_analysis
#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_record__suffix
msgid "Suffix"
-msgstr ""
+msgstr "Sufijo"
#. module: upgrade_analysis
#: model_terms:ir.ui.view,arch_db:upgrade_analysis.view_upgrade_comparison_config_form
msgid "Test Connection"
-msgstr ""
+msgstr "Prueba de Conexión"
#. module: upgrade_analysis
#: model:ir.model.fields,help:upgrade_analysis.field_upgrade_analysis__upgrade_path
@@ -391,11 +399,14 @@ msgid ""
"Odoo's --upgrade-path command line option or the 'scripts' subdirectory in "
"the openupgrade_scripts addon."
msgstr ""
+"La ruta del archivo base para guardar los archivos de análisis de los "
+"módulos de Odoo. Tomado de la opción de línea de comando --upgrade-path de "
+"Odoo o del subdirectorio 'scripts' en el complemento openupgrade_scripts."
#. module: upgrade_analysis
#: model_terms:ir.ui.view,arch_db:upgrade_analysis.view_upgrade_install_wizard_form
msgid "The modules have been installed successfuly"
-msgstr ""
+msgstr "Los módulos han sido instalados correctamente"
#. module: upgrade_analysis
#: model_terms:ir.ui.view,arch_db:upgrade_analysis.view_upgrade_install_wizard_form
@@ -403,6 +414,8 @@ msgid ""
"This will install the selected modules on the database. Do not continue if "
"you use this database in production."
msgstr ""
+"Esto instalará los módulos seleccionados en la base de datos. No continúe si "
+"utiliza esta base de datos en producción."
#. module: upgrade_analysis
#: model_terms:ir.ui.view,arch_db:upgrade_analysis.view_upgrade_generate_record_wizard_form
@@ -410,89 +423,91 @@ msgid ""
"This will reinitialize all the modules installed on this database. Do not "
"continue if you use this database in production."
msgstr ""
+"Esto reiniciará todos los módulos instalados en esta base de datos. No "
+"continúe si utiliza esta base de datos en producción."
#. module: upgrade_analysis
#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_record__type
msgid "Type"
-msgstr ""
+msgstr "Tipo"
#. module: upgrade_analysis
#: code:addons/upgrade_analysis/models/upgrade_analysis.py:0
#, python-format
msgid "Unexpected root Element: %(root)s in file: %(file)s"
-msgstr ""
+msgstr "Elemento root Inesperado: %(root)s en el archivo: %(file)s"
#. module: upgrade_analysis
#: model:ir.actions.act_window,name:upgrade_analysis.action_upgrade_analysis_tree
#: model:ir.model,name:upgrade_analysis.model_upgrade_analysis
#: model:ir.ui.menu,name:upgrade_analysis.menu_upgrade_analysis
msgid "Upgrade Analyses"
-msgstr ""
+msgstr "Análisis de Actualización"
#. module: upgrade_analysis
#: model:ir.ui.menu,name:upgrade_analysis.menu_upgrade
msgid "Upgrade Analysis"
-msgstr ""
+msgstr "Análisis de Actualización"
#. module: upgrade_analysis
#: model:ir.model,name:upgrade_analysis.model_upgrade_attribute
msgid "Upgrade Attribute"
-msgstr ""
+msgstr "Atributo de Actualización"
#. module: upgrade_analysis
#: model:ir.model,name:upgrade_analysis.model_upgrade_comparison_config
msgid "Upgrade Comparison Configuration"
-msgstr ""
+msgstr "Configuración de Comparación de Actualizaciones"
#. module: upgrade_analysis
#: model:ir.model,name:upgrade_analysis.model_upgrade_generate_record_wizard
msgid "Upgrade Generate Record Wizard"
-msgstr ""
+msgstr "Actualización del Asistente de Generación de Registros"
#. module: upgrade_analysis
#: model:ir.model,name:upgrade_analysis.model_upgrade_install_wizard
msgid "Upgrade Install Wizard"
-msgstr ""
+msgstr "Asistente de Instalación de Actualización"
#. module: upgrade_analysis
#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_analysis__upgrade_path
msgid "Upgrade Path"
-msgstr ""
+msgstr "Ruta de Actualización"
#. module: upgrade_analysis
#: model:ir.model,name:upgrade_analysis.model_upgrade_record
msgid "Upgrade Record"
-msgstr ""
+msgstr "Registro de Actualización"
#. module: upgrade_analysis
#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_comparison_config__username
msgid "Username"
-msgstr ""
+msgstr "Nombre de usuario"
#. module: upgrade_analysis
#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_attribute__value
msgid "Value"
-msgstr ""
+msgstr "Valor"
#. module: upgrade_analysis
#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_comparison_config__version
msgid "Version"
-msgstr ""
+msgstr "Versión"
#. module: upgrade_analysis
#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_analysis__write_files
msgid "Write Files"
-msgstr ""
+msgstr "Escribir Archivos"
#. module: upgrade_analysis
#: model:ir.model.fields,help:upgrade_analysis.field_upgrade_analysis__write_files
msgid "Write analysis files to the module directories"
-msgstr ""
+msgstr "Escribir archivos de análisis en los directorios del módulo"
#. module: upgrade_analysis
#: model:ir.model.fields.selection,name:upgrade_analysis.selection__upgrade_record__type__xmlid
msgid "XML ID"
-msgstr ""
+msgstr "XML ID"
#. module: upgrade_analysis
#: code:addons/upgrade_analysis/models/upgrade_comparison_config.py:0
@@ -501,18 +516,20 @@ msgid ""
"You are correctly connected to the server %(server)s (version %(version)s) "
"with the user %(user_name)s"
msgstr ""
+"Está correctamente conectado al servidor %(server)s (versión %(version)s) "
+"con el usuario %(user_name)s"
#. module: upgrade_analysis
#: model:ir.model.fields.selection,name:upgrade_analysis.selection__upgrade_analysis__state__draft
msgid "draft"
-msgstr ""
+msgstr "borrador"
#. module: upgrade_analysis
#: model:ir.actions.act_window,name:upgrade_analysis.action_upgrade_comparison_config_tree
msgid "upgrade Comparison Configs"
-msgstr ""
+msgstr "actualizar configuraciones de comparación"
#. module: upgrade_analysis
#: model:ir.actions.act_window,name:upgrade_analysis.action_upgrade_record_tree
msgid "upgrade Records"
-msgstr ""
+msgstr "actualizar Registros"
From ab996ca93a25c0f56ad61bba424ae04692072a05 Mon Sep 17 00:00:00 2001
From: OCA-git-bot
Date: Wed, 5 Oct 2022 00:55:38 +0000
Subject: [PATCH 64/67] upgrade_analysis 15.0.2.0.1
---
upgrade_analysis/__manifest__.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/upgrade_analysis/__manifest__.py b/upgrade_analysis/__manifest__.py
index 39ef860d0..87d67f1d5 100644
--- a/upgrade_analysis/__manifest__.py
+++ b/upgrade_analysis/__manifest__.py
@@ -5,7 +5,7 @@
"name": "Upgrade Analysis",
"summary": "Performs a difference analysis between modules"
" installed on two different Odoo instances",
- "version": "15.0.2.0.0",
+ "version": "15.0.2.0.1",
"category": "Migration",
"author": "Therp BV, Opener B.V., GRAP, Odoo Community Association (OCA)",
"maintainers": ["StefanRijnhart", "legalsylvain"],
From 3cbb201c3aaea5fe4b8f9d2acde4e1e12f5ca3b3 Mon Sep 17 00:00:00 2001
From: Stefan Rijnhart
Date: Wed, 5 Oct 2022 16:22:33 +0200
Subject: [PATCH 65/67] [IMP] upgrade_analysis: black, isort, prettier
---
requirements.txt | 5 +++++
setup/upgrade_analysis/odoo/addons/upgrade_analysis | 1 +
setup/upgrade_analysis/setup.py | 6 ++++++
3 files changed, 12 insertions(+)
create mode 100644 requirements.txt
create mode 120000 setup/upgrade_analysis/odoo/addons/upgrade_analysis
create mode 100644 setup/upgrade_analysis/setup.py
diff --git a/requirements.txt b/requirements.txt
new file mode 100644
index 000000000..7a9599183
--- /dev/null
+++ b/requirements.txt
@@ -0,0 +1,5 @@
+# generated from manifests external_dependencies
+dataclasses
+mako
+odoorpc
+openupgradelib
diff --git a/setup/upgrade_analysis/odoo/addons/upgrade_analysis b/setup/upgrade_analysis/odoo/addons/upgrade_analysis
new file mode 120000
index 000000000..363ae3c1e
--- /dev/null
+++ b/setup/upgrade_analysis/odoo/addons/upgrade_analysis
@@ -0,0 +1 @@
+../../../../upgrade_analysis
\ No newline at end of file
diff --git a/setup/upgrade_analysis/setup.py b/setup/upgrade_analysis/setup.py
new file mode 100644
index 000000000..28c57bb64
--- /dev/null
+++ b/setup/upgrade_analysis/setup.py
@@ -0,0 +1,6 @@
+import setuptools
+
+setuptools.setup(
+ setup_requires=['setuptools-odoo'],
+ odoo_addon=True,
+)
From 60d4f51c358a43826479fd47fd4da4b8bcebdf15 Mon Sep 17 00:00:00 2001
From: Stefan Rijnhart
Date: Wed, 5 Oct 2022 16:23:50 +0200
Subject: [PATCH 66/67] [MIG] upgrade_analysis: Migration to 16.0
---
upgrade_analysis/README.rst | 10 +++++-----
upgrade_analysis/__manifest__.py | 2 +-
upgrade_analysis/static/description/index.html | 8 ++++----
upgrade_analysis/wizards/upgrade_install_wizard.py | 10 ++++++++--
4 files changed, 18 insertions(+), 12 deletions(-)
diff --git a/upgrade_analysis/README.rst b/upgrade_analysis/README.rst
index 2b543ab74..62b7497d6 100644
--- a/upgrade_analysis/README.rst
+++ b/upgrade_analysis/README.rst
@@ -14,13 +14,13 @@ Upgrade Analysis
:target: http://www.gnu.org/licenses/agpl-3.0-standalone.html
:alt: License: AGPL-3
.. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fserver--tools-lightgray.png?logo=github
- :target: https://github.com/OCA/server-tools/tree/15.0/upgrade_analysis
+ :target: https://github.com/OCA/server-tools/tree/16.0/upgrade_analysis
:alt: OCA/server-tools
.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png
- :target: https://translation.odoo-community.org/projects/server-tools-15-0/server-tools-15-0-upgrade_analysis
+ :target: https://translation.odoo-community.org/projects/server-tools-16-0/server-tools-16-0-upgrade_analysis
:alt: Translate me on Weblate
.. |badge5| image:: https://img.shields.io/badge/runbot-Try%20me-875A7B.png
- :target: https://runbot.odoo-community.org/runbot/149/15.0
+ :target: https://runbot.odoo-community.org/runbot/149/16.0
:alt: Try me on Runbot
|badge1| |badge2| |badge3| |badge4| |badge5|
@@ -52,7 +52,7 @@ Bug Tracker
Bugs are tracked on `GitHub Issues `_.
In case of trouble, please check there if your issue has already been reported.
If you spotted it first, help us smashing it by providing a detailed and welcomed
-`feedback `_.
+`feedback `_.
Do not contact contributors directly about support or help with technical issues.
@@ -101,6 +101,6 @@ Current `maintainers `__:
|maintainer-StefanRijnhart| |maintainer-legalsylvain|
-This module is part of the `OCA/server-tools `_ project on GitHub.
+This module is part of the `OCA/server-tools `_ project on GitHub.
You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.
diff --git a/upgrade_analysis/__manifest__.py b/upgrade_analysis/__manifest__.py
index 87d67f1d5..3aeecb5ef 100644
--- a/upgrade_analysis/__manifest__.py
+++ b/upgrade_analysis/__manifest__.py
@@ -5,7 +5,7 @@
"name": "Upgrade Analysis",
"summary": "Performs a difference analysis between modules"
" installed on two different Odoo instances",
- "version": "15.0.2.0.1",
+ "version": "16.0.1.0.0",
"category": "Migration",
"author": "Therp BV, Opener B.V., GRAP, Odoo Community Association (OCA)",
"maintainers": ["StefanRijnhart", "legalsylvain"],
diff --git a/upgrade_analysis/static/description/index.html b/upgrade_analysis/static/description/index.html
index 1f0de603c..89fee6a45 100644
--- a/upgrade_analysis/static/description/index.html
+++ b/upgrade_analysis/static/description/index.html
@@ -3,7 +3,7 @@
-
+
Upgrade Analysis