From 6a5feb5d7ef9f047c4b7521ed6020bce4ad2f8fc Mon Sep 17 00:00:00 2001
From: Sylvain LE GAL
Date: Fri, 6 Nov 2020 21:39:26 +0100
Subject: [PATCH 01/81] [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 00000000000..973300fa0fe
--- /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 00000000000..52ac7bbe891
--- /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 ed44832568f2ebab7e7b85cece54bbe01231585d Mon Sep 17 00:00:00 2001
From: Sylvain LE GAL
Date: Fri, 6 Nov 2020 22:24:04 +0100
Subject: [PATCH 02/81] [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 00000000000..f3d1c48de1d
--- /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 00000000000..c102a8ca668
--- /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 00000000000..79ebfc939b6
--- /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 00000000000..814396ad692
--- /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 00000000000..6e445842447
--- /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 00000000000..61a5e208203
--- /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 00000000000..0e5274bdf8a
--- /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 00000000000..b09f6839e6e
--- /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 00000000000..c1085418e6d
--- /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 00000000000..80b5a8a3a36
--- /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 00000000000..2ab5e67c18b
--- /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 00000000000..efaa5294f17
--- /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 00000000000..db0ae777052
--- /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 00000000000..18dd598122e
--- /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 00000000000..73188afb2c8
--- /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 00000000000..a8d683d9538
--- /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 f29ff2daa78455044160b6adfa99ef29a2290cd9 Mon Sep 17 00:00:00 2001
From: Sylvain LE GAL
Date: Fri, 6 Nov 2020 22:44:54 +0100
Subject: [PATCH 03/81] [REF] rename files, apply OCA convention, remove
obsolete 6.1 syntax, make the module installable, add readme folders
---
upgrade_analysis/README.rst | 67 +--
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, 442 insertions(+), 499 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 f3d1c48de1d..2b99745a85a 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
-
-===============================
-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.
+================
+Upgrade Analysis
+================
+
+.. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+ !! 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 c102a8ca668..abe0f8c3cd8 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 79ebfc939b6..1a83113a1d2 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 973300fa0fe..2e588319118 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 52ac7bbe891..6af14263d9b 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 clean_records(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 clean_records(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 match(match_fields, report_fields, warn=False):
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 6e445842447..748d5aee081 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 00000000000..ce6ef46e37f
--- /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 0e5274bdf8a..17d60e61f82 100644
--- a/upgrade_analysis/models/comparison_config.py
+++ b/upgrade_analysis/models/upgrade_comparison_config.py
@@ -8,25 +8,25 @@
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 @@ def test_connection(self):
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 80b5a8a3a36..89426c308ce 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 00000000000..5de0e93e545
--- /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 00000000000..ff1a57292d4
--- /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 00000000000..734c2244406
--- /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 00000000000..e69de29bb2d
diff --git a/upgrade_analysis/security/ir.model.access.csv b/upgrade_analysis/security/ir.model.access.csv
index 2ab5e67c18b..5d835a8a960 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 00000000000..12d44779d87
--- /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 db0ae777052..9d98c47a278 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 a8d683d9538..8fbd3c5c469 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 00000000000..dffe83f417f
--- /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 61a5e208203..82cbaab7702 100644
--- a/upgrade_analysis/models/analysis_wizard.py
+++ b/upgrade_analysis/wizards/upgrade_analysis_wizard.py
@@ -8,15 +8,15 @@
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 @@ def get_communication(self):
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 @@ def write_file(module, version, content, filename="openupgrade_analysis.txt"):
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 @@ def write_file(module, version, content, filename="openupgrade_analysis.txt"):
"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 b09f6839e6e..fc7f6c02f62 100644
--- a/upgrade_analysis/models/generate_records_wizard.py
+++ b/upgrade_analysis/wizards/upgrade_generate_record_wizard.py
@@ -10,8 +10,8 @@
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 @@ def generate(self):
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 @@ def generate(self):
# 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 @@ def generate(self):
)
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 @@ def generate(self):
# 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 c1085418e6d..4ea1d36b997 100644
--- a/upgrade_analysis/models/install_all_wizard.py
+++ b/upgrade_analysis/wizards/upgrade_install_wizard.py
@@ -9,9 +9,9 @@
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 efaa5294f17..d988c503d0d 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 73188afb2c8..a6d21e5372c 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 dd66ff47888255cfd881b6f160d31e0b079e86eb Mon Sep 17 00:00:00 2001
From: Sylvain LE GAL
Date: Sat, 7 Nov 2020 00:35:37 +0100
Subject: [PATCH 04/81] [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 abe0f8c3cd8..338ffe995fd 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 814396ad692..41943d6fbee 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 748d5aee081..e0245a18470 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 00000000000..9456af708ec
--- /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 00000000000..d9b96c4fa5a
--- /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 00000000000..85a66d9b747
--- /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 12d44779d87..e12c752369b 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 fc7f6c02f62..439f6b2c22c 100644
--- a/upgrade_analysis/wizards/upgrade_generate_record_wizard.py
+++ b/upgrade_analysis/wizards/upgrade_generate_record_wizard.py
@@ -95,7 +95,7 @@ def generate(self):
)
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 4ea1d36b997..d91232867d9 100644
--- a/upgrade_analysis/wizards/upgrade_install_wizard.py
+++ b/upgrade_analysis/wizards/upgrade_install_wizard.py
@@ -6,7 +6,11 @@
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 86c62017968..a0a310e7450 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 dffe83f417f..95d2893326e 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 439f6b2c22c..7a5747719d5 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 @@
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 @@ def generate(self):
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 d988c503d0d..00000000000
--- 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 a0a310e7450..4a4cd019303 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 0c079b94fc7..7c9ac1cebfe 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/81] [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 | 4 +-
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 | 87 +--
.../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, 328 insertions(+), 1583 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 7fc3dd81d5c..ca02278dfe6 100644
--- a/upgrade_analysis/__init__.py
+++ b/upgrade_analysis/__init__.py
@@ -4,5 +4,4 @@
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 a579696fa1b..52eff5d85af 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 .. 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 @@ def _write_file(
):
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 @@ def _write_file(
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 56a70dbc176..4a183795658 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 e5aa886bacb..3247dc7b6b5 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 925f56ed264..94f30010f58 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 0650744f6bc..00000000000
--- 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 db8634ade1f..00000000000
--- 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 ac0f5dc5a49..00000000000
--- 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 b66d7f484cb..a28a083cea8 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 5629ec98c48..4541924d99f 100644
--- a/upgrade_analysis/odoo_patch/odoo/__init__.py
+++ b/upgrade_analysis/odoo_patch/odoo/__init__.py
@@ -1,5 +1,3 @@
+from . import models
from . import modules
-from . import service
from . import tools
-from . import http
-from . import models
diff --git a/upgrade_analysis/odoo_patch/odoo/http.py b/upgrade_analysis/odoo_patch/odoo/http.py
deleted file mode 100644
index e11c558fb90..00000000000
--- 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 201f3f4fe63..09c10c41836 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.
-
- 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
+class BaseModelPatch(OdooPatch):
+ target = models.BaseModel
+ method_names = ['_convert_records']
- 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 90de5b4ff4e..7246323f930 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 b0bedef3ea6..00000000000
--- 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 4194fdc626d..00000000000
--- 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 0346c2b8c55..00000000000
--- 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 4c5f50d4e71..3d0981a001e 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
-
-from collections import deque
-from contextlib import closing
-import odoo
-from odoo.tools.lru import LRU
-
-from odoo.modules import registry
-
-
-if True:
-
- 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)
-
- # 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
+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
+
+_logger = logging.getLogger(__name__)
+
+
+class RegistryPatch(OdooPatch):
+ target = Registry
+ 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)
+ 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)
+
+ 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 a96314d0f68..00000000000
--- 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 a2a998e69df..00000000000
--- 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 6ad156515dc..99a9527ec5a 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 8c1f710a52e..7130859d628 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 e6c8243241a..00000000000
--- 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 00000000000..ac9f02fee2e
--- /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 1187a5900f4..00000000000
--- 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 2563ecbc637..10c28596b60 100644
--- a/upgrade_analysis/upgrade_log.py
+++ b/upgrade_analysis/upgrade_log.py
@@ -6,9 +6,161 @@
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 375253ce9b0..c2ce39170b3 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 @@ def generate(self):
{"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 d91232867d9..94cc3a7fece 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 @@ def _compute_module_qty(self):
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 aed60746e386382d14c2313ed44b261a08291928 Mon Sep 17 00:00:00 2001
From: Stefan Rijnhart
Date: Sun, 6 Dec 2020 12:23:12 +0100
Subject: [PATCH 08/81] [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 52eff5d85af..39320ba0f3d 100644
--- a/upgrade_analysis/models/upgrade_analysis.py
+++ b/upgrade_analysis/models/upgrade_analysis.py
@@ -62,11 +62,12 @@ def _write_file(
% 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 10c28596b60..345b1d77212 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 84dd36622ec..ace540646f8 100644
--- a/upgrade_analysis/wizards/upgrade_generate_record_wizard.py
+++ b/upgrade_analysis/wizards/upgrade_generate_record_wizard.py
@@ -88,8 +88,9 @@ def generate(self):
# 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 827d506b167ae77fad57e7a9e47c1a56483c95c0 Mon Sep 17 00:00:00 2001
From: Stefan Rijnhart
Date: Mon, 7 Dec 2020 10:59:40 +0100
Subject: [PATCH 09/81] [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 39320ba0f3d..8f490e727fc 100644
--- a/upgrade_analysis/models/upgrade_analysis.py
+++ b/upgrade_analysis/models/upgrade_analysis.py
@@ -7,8 +7,10 @@
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 @@ def _write_file(
):
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 @@ def analyze(self):
}
)
+ 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 6bce297ce7e..90553ccf741 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 @@ def _compute_analysis_qty(self):
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 3247dc7b6b5..5710e749763 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 f80a5bca6a509620ad53f5d63bbdf53f4ac99405 Mon Sep 17 00:00:00 2001
From: Sylvain LE GAL
Date: Mon, 7 Dec 2020 12:15:01 +0100
Subject: [PATCH 10/81] [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 9456af708ec..a9a5695176b 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 ce6ef46e37f..15c93446657 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 90553ccf741..95317bf7e01 100644
--- a/upgrade_analysis/models/upgrade_comparison_config.py
+++ b/upgrade_analysis/models/upgrade_comparison_config.py
@@ -67,9 +67,9 @@ def test_connection(self):
"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 85a66d9b747..fbb54e50592 100644
--- a/upgrade_analysis/tests/test_module.py
+++ b/upgrade_analysis/tests/test_module.py
@@ -29,8 +29,8 @@ def test_upgrade_install_wizard(self):
)
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 4f53a6557481588681d16ebed09df1b74578d19d Mon Sep 17 00:00:00 2001
From: Sylvain LE GAL
Date: Mon, 7 Dec 2020 12:42:45 +0100
Subject: [PATCH 11/81] [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 2e588319118..4c06538e2e1 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 8f490e727fc..b0463e9f246 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 @@
_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 @@ def analyze(self):
"log": general_log,
}
)
+ return True
diff --git a/upgrade_analysis/models/upgrade_comparison_config.py b/upgrade_analysis/models/upgrade_comparison_config.py
index 95317bf7e01..35fcd500578 100644
--- a/upgrade_analysis/models/upgrade_comparison_config.py
+++ b/upgrade_analysis/models/upgrade_comparison_config.py
@@ -69,7 +69,8 @@ def test_connection(self):
"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 5710e749763..3247dc7b6b5 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 00000000000..a67563f42d4
--- /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 e69de29bb2d..00000000000
From 285f75ac9dc52ca9e092a444bee2043713da34dd Mon Sep 17 00:00:00 2001
From: Stefan Rijnhart
Date: Tue, 8 Dec 2020 11:26:15 +0100
Subject: [PATCH 12/81] [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 ca02278dfe6..172ae9a2543 100644
--- a/upgrade_analysis/__init__.py
+++ b/upgrade_analysis/__init__.py
@@ -2,6 +2,5 @@
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 4c06538e2e1..00000000000
--- 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 6af14263d9b..bc817d9e08d 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 a9a5695176b..bff4265b33d 100644
--- a/upgrade_analysis/models/ir_module_module.py
+++ b/upgrade_analysis/models/ir_module_module.py
@@ -24,6 +24,9 @@ def _compute_is_oca_module(self):
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 b0463e9f246..f42ffdff1ca 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 @@
_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 @@ def _write_file(
):
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 @@ def analyze(self):
}
)
- 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 @@ def analyze(self):
+ 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 c2ce39170b3..c664fa70d43 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/81] [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 f42ffdff1ca..e9eca7b59a5 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 @@ def analyze(self):
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 @@ def analyze(self):
}
)
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 89426c308ce..6aa07cab63c 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 @@ def field_dump(self):
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 fdedffae773751f14ea6a248fb14c1ce00067962 Mon Sep 17 00:00:00 2001
From: Stefan Rijnhart
Date: Fri, 11 Dec 2020 21:11:44 +0100
Subject: [PATCH 14/81] [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 a7d9de82bcf..44c755efba3 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 0ab6f677912015cc1f8766142c3286d50831cbb4 Mon Sep 17 00:00:00 2001
From: Sylvain LE GAL
Date: Wed, 20 Jan 2021 12:22:38 +0100
Subject: [PATCH 15/81] 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 bff4265b33d..38edbbac890 100644
--- a/upgrade_analysis/models/ir_module_module.py
+++ b/upgrade_analysis/models/ir_module_module.py
@@ -8,7 +8,7 @@
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 507a888abf66213bbae872b79ac47f1e09e4e419 Mon Sep 17 00:00:00 2001
From: Sylvain LE GAL
Date: Wed, 24 Feb 2021 09:13:12 +0100
Subject: [PATCH 16/81] [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 734c2244406..79e8c593905 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 dbe36f4d077ee40e09b45aee9b7b636efbbf8593 Mon Sep 17 00:00:00 2001
From: Sylvain LE GAL
Date: Wed, 24 Feb 2021 09:20:42 +0100
Subject: [PATCH 17/81] [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 94f30010f58..09caee64cb1 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 a67563f42d4..66f003c1787 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 @@
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 a28a083cea8..206795b42db 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 09c10c41836..431fc9635c8 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 3d0981a001e..017da063fd2 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 @@ def init_models(self, cr, model_names, context, install=True):
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 7130859d628..0912c6d2674 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 ac9f02fee2e..c1956f51f46 100644
--- a/upgrade_analysis/odoo_patch/odoo_patch.py
+++ b/upgrade_analysis/odoo_patch/odoo_patch.py
@@ -4,7 +4,7 @@
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 @@ def do_something(self):
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 3678090b56e36051a20ba510950afad4d196dcc5 Mon Sep 17 00:00:00 2001
From: oca-travis
Date: Fri, 26 Feb 2021 19:28:26 +0000
Subject: [PATCH 18/81] [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 00000000000..63f58e38aaa
--- /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 0bdffde19847e5da83a4071aa6496947ecfc3b42 Mon Sep 17 00:00:00 2001
From: OCA-git-bot
Date: Fri, 26 Feb 2021 19:32:00 +0000
Subject: [PATCH 19/81] [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 2b99745a85a..82b5e950e66 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 00000000000..0da55055a1b
--- /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 05a722b30c5574373bae91b07d4b1a6561267ae7 Mon Sep 17 00:00:00 2001
From: OCA-git-bot
Date: Fri, 26 Feb 2021 19:32:01 +0000
Subject: [PATCH 20/81] [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 06228ef133e1cd22bc08c63f0f0e54304de02470 Mon Sep 17 00:00:00 2001
From: mreficent
Date: Tue, 23 Mar 2021 18:03:08 +0100
Subject: [PATCH 21/81] [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 bc817d9e08d..bc505bd6fe7 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 match(match_fields, report_fields, warn=False):
# other module, same operation, other type
matched_other_type = match(
- ["mode", "model", "field"],
+ ["module", "mode", "model", "field"],
[
"relation",
"type",
@@ -330,6 +336,20 @@ def match(match_fields, report_fields, warn=False):
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 match(match_fields, match_type="direct"):
# 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 match(match_fields, match_type="direct"):
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 44d5f6afacc2eaf9ac1fea9bcf7865aae7233c0d Mon Sep 17 00:00:00 2001
From: mreficent
Date: Tue, 23 Mar 2021 18:06:43 +0100
Subject: [PATCH 22/81] [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 bc505bd6fe7..0b3496d9383 100644
--- a/upgrade_analysis/compare.py
+++ b/upgrade_analysis/compare.py
@@ -228,7 +228,7 @@ def match(match_fields, report_fields, warn=False):
"relation",
"type",
"selection_keys",
- "inherits",
+ "_inherits",
"stored",
"isfunction",
"isrelated",
@@ -244,7 +244,7 @@ def match(match_fields, report_fields, warn=False):
"module",
"relation",
"selection_keys",
- "inherits",
+ "_inherits",
"stored",
"isfunction",
"isrelated",
@@ -260,7 +260,7 @@ def match(match_fields, report_fields, warn=False):
"relation",
"type",
"selection_keys",
- "inherits",
+ "_inherits",
"stored",
"isfunction",
"isrelated",
@@ -274,7 +274,7 @@ def match(match_fields, report_fields, warn=False):
"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 6aa07cab63c..2e93cf0304c 100644
--- a/upgrade_analysis/models/upgrade_record.py
+++ b/upgrade_analysis/models/upgrade_record.py
@@ -102,7 +102,7 @@ def field_dump(self):
"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 345b1d77212..84547402f1a 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 f69a221addcbb40c580bed0b17562fdb23a2e0ca Mon Sep 17 00:00:00 2001
From: mreficent
Date: Tue, 23 Mar 2021 18:10:00 +0100
Subject: [PATCH 23/81] [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 0b3496d9383..1300f90b951 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 2e93cf0304c..445a90c9730 100644
--- a/upgrade_analysis/models/upgrade_record.py
+++ b/upgrade_analysis/models/upgrade_record.py
@@ -118,6 +118,17 @@ def field_dump(self):
}
)
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 f83a940db8764ece313ae970fbd387208f27a41f Mon Sep 17 00:00:00 2001
From: mreficent
Date: Tue, 23 Mar 2021 18:18:17 +0100
Subject: [PATCH 24/81] [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 1300f90b951..3222bcd1a68 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 match(match_fields, report_fields, warn=False):
"isrelated",
"required",
"table",
+ "_order",
],
)
@@ -260,6 +263,7 @@ def match(match_fields, report_fields, warn=False):
"isrelated",
"required",
"table",
+ "_order",
],
)
@@ -276,6 +280,7 @@ def match(match_fields, report_fields, warn=False):
"isrelated",
"required",
"table",
+ "_order",
],
)
@@ -289,6 +294,8 @@ def match(match_fields, report_fields, warn=False):
"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 match(match_fields, report_fields, warn=False):
]
)
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 445a90c9730..c31b453ea6a 100644
--- a/upgrade_analysis/models/upgrade_record.py
+++ b/upgrade_analysis/models/upgrade_record.py
@@ -103,6 +103,7 @@ def field_dump(self):
"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 84547402f1a..b102d3afa02 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 58204c1c4c6d006f573793d5a5027b2c65aadd19 Mon Sep 17 00:00:00 2001
From: mreficent
Date: Tue, 23 Mar 2021 17:30:49 +0100
Subject: [PATCH 25/81] [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 41943d6fbee..ea5007219a3 100644
--- a/upgrade_analysis/blacklist.py
+++ b/upgrade_analysis/blacklist.py
@@ -2,7 +2,7 @@
# 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 3222bcd1a68..864277310e8 100644
--- a/upgrade_analysis/compare.py
+++ b/upgrade_analysis/compare.py
@@ -14,14 +14,14 @@
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 e9eca7b59a5..15e08e7ca02 100644
--- a/upgrade_analysis/models/upgrade_analysis.py
+++ b/upgrade_analysis/models/upgrade_analysis.py
@@ -430,7 +430,7 @@ def _parse_files(self, xml_files, module_name):
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 c1956f51f46..f2ad6f73cfb 100644
--- a/upgrade_analysis/odoo_patch/odoo_patch.py
+++ b/upgrade_analysis/odoo_patch/odoo_patch.py
@@ -54,7 +54,7 @@ def __exit__(self, exc_type, exc_value, tb):
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 94cc3a7fece..da28996fab6 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 @@ def return_same_form_view(self):
"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 116807cdebafd9bbe9b8cdc410a8e03e8cd0e766 Mon Sep 17 00:00:00 2001
From: OCA-git-bot
Date: Thu, 25 Mar 2021 16:36:56 +0000
Subject: [PATCH 26/81] 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 44c755efba3..21705c6b866 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 2fd9e9bf49733ae3c6abbc5d86b85e149b5968ec Mon Sep 17 00:00:00 2001
From: mreficent
Date: Thu, 25 Mar 2021 02:58:29 +0100
Subject: [PATCH 27/81] [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 00000000000..ee9409ec47e
--- /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 ff1a57292d4..1b12e675fe0 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 aab974b9893e4b1c01f751c882ebaf72082ea684 Mon Sep 17 00:00:00 2001
From: OCA-git-bot
Date: Thu, 25 Mar 2021 18:21:03 +0000
Subject: [PATCH 28/81] [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 82b5e950e66..c42ee173655 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 0da55055a1b..9d40422de73 100644
--- a/upgrade_analysis/static/description/index.html
+++ b/upgrade_analysis/static/description/index.html
@@ -369,6 +369,7 @@ 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
From 36bc2e0e4463d1e14336d2e92aec77ccbe5b595e Mon Sep 17 00:00:00 2001
From: oca-travis
Date: Thu, 25 Mar 2021 18:41:29 +0000
Subject: [PATCH 29/81] [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 63f58e38aaa..a892cf2e900 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 0044dc09ca69573aa1a6dd341bcfaad2f0c4bb46 Mon Sep 17 00:00:00 2001
From: OCA-git-bot
Date: Thu, 25 Mar 2021 18:49:31 +0000
Subject: [PATCH 30/81] 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 21705c6b866..62d019b3915 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 8f3d6def3572650e1aa6f77888f4d0cd13974bb8 Mon Sep 17 00:00:00 2001
From: mreficent
Date: Sat, 27 Mar 2021 00:44:50 +0100
Subject: [PATCH 31/81] [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 62d019b3915..ee70913e19a 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 15e08e7ca02..26038249f4c 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.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 @@ def _compute_upgrade_path(self):
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 @@ def _process_record_node(
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 @@ def generate_noupdate_changes(self):
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 c31b453ea6a..fdcd0e707e4 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 @@ def get_xml_records(self, module):
# 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 @@ def get_xml_records(self, module):
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 5de0e93e545..b8c8505e947 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 9d40422de73..6a1087c8f0e 100644
--- a/upgrade_analysis/static/description/index.html
+++ b/upgrade_analysis/static/description/index.html
@@ -416,7 +416,7 @@
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 32f04922f23f0c9cdb0cb2400087c484c0bb26c0 Mon Sep 17 00:00:00 2001
From: mreficent
Date: Sun, 28 Mar 2021 12:51:41 +0200
Subject: [PATCH 32/81] [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 ace540646f8..3a766b1b1c8 100644
--- a/upgrade_analysis/wizards/upgrade_generate_record_wizard.py
+++ b/upgrade_analysis/wizards/upgrade_generate_record_wizard.py
@@ -25,6 +25,9 @@ def generate(self):
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 3459eb6c1f2529273d474737aeddf3591764a9ea Mon Sep 17 00:00:00 2001
From: OCA-git-bot
Date: Mon, 29 Mar 2021 11:47:58 +0000
Subject: [PATCH 33/81] [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 c42ee173655..4fcf7f0cf22 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 799a138a3aabcc071b8dbc37d687272237a480bf Mon Sep 17 00:00:00 2001
From: OCA-git-bot
Date: Mon, 29 Mar 2021 11:47:58 +0000
Subject: [PATCH 34/81] 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 ee70913e19a..5c3aa344483 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 0e7460bdd81c3ab8a5a0876d219cfaf7ecbe3247 Mon Sep 17 00:00:00 2001
From: mreficent
Date: Wed, 21 Apr 2021 17:40:16 +0200
Subject: [PATCH 35/81] [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 26038249f4c..2c67ac05186 100644
--- a/upgrade_analysis/models/upgrade_analysis.py
+++ b/upgrade_analysis/models/upgrade_analysis.py
@@ -368,7 +368,7 @@ def _update_node(target, source):
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 @@ def generate_noupdate_changes(self):
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 2b1454144a12d42423b57e9832cd09ecf2047aaf Mon Sep 17 00:00:00 2001
From: mreficent
Date: Wed, 21 Apr 2021 18:37:36 +0200
Subject: [PATCH 36/81] [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 2c67ac05186..fcdd4877404 100644
--- a/upgrade_analysis/models/upgrade_analysis.py
+++ b/upgrade_analysis/models/upgrade_analysis.py
@@ -408,31 +408,30 @@ def _process_record_node(
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 @@ def generate_noupdate_changes(self):
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 fdcd0e707e4..f62c7ca3ee1 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.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 @@ def get_xml_records(self, module):
# 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 @@ def get_xml_records(self, module):
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 c87211113c112ec67aaae20c8decc2367ebf6375 Mon Sep 17 00:00:00 2001
From: oca-travis
Date: Fri, 30 Apr 2021 17:45:58 +0000
Subject: [PATCH 37/81] [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 a892cf2e900..fb0550c0a90 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 4bf5825e7c861592e2dbccb5a1ff41d411bb5edb Mon Sep 17 00:00:00 2001
From: Yves Le Doeuff
Date: Fri, 14 May 2021 17:03:50 +0000
Subject: [PATCH 38/81] 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 00000000000..6ab2f70f675
--- /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 2d2a2af51d5bf563999f050abb932e640c58ea7f Mon Sep 17 00:00:00 2001
From: oca-git-bot
Date: Fri, 14 May 2021 19:30:51 +0200
Subject: [PATCH 39/81] [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 fcdd4877404..43a29a1b2e3 100644
--- a/upgrade_analysis/models/upgrade_analysis.py
+++ b/upgrade_analysis/models/upgrade_analysis.py
@@ -12,7 +12,7 @@
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 @@ def analyze(self):
)
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 390441f39e0d9543923910d947471fc087041121 Mon Sep 17 00:00:00 2001
From: Yves Le Doeuff
Date: Fri, 14 May 2021 17:04:35 +0000
Subject: [PATCH 40/81] 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 6ab2f70f675..234427e4a8d 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 ceb26b0db97696016c5bf166ffa3815f70dc3418 Mon Sep 17 00:00:00 2001
From: Payam Yasaie
Date: Tue, 12 Oct 2021 09:04:28 +0330
Subject: [PATCH 41/81] [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 43a29a1b2e3..932ce80f0d3 100644
--- a/upgrade_analysis/models/upgrade_analysis.py
+++ b/upgrade_analysis/models/upgrade_analysis.py
@@ -93,7 +93,7 @@ def _write_file(
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 2de03145de4e4933ab21b6032d74f84ec62f98ad Mon Sep 17 00:00:00 2001
From: OCA-git-bot
Date: Wed, 13 Oct 2021 10:47:04 +0000
Subject: [PATCH 42/81] 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 5c3aa344483..c3d5e6f1b18 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 1375211149d963bb68959d09b9155bb6c1dcda3d Mon Sep 17 00:00:00 2001
From: Sylvain LE GAL
Date: Thu, 21 Oct 2021 00:20:36 +0200
Subject: [PATCH 43/81] [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 c3d5e6f1b18..d07930884e4 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 ee9409ec47e..00000000000
--- 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 932ce80f0d3..2a6046e54dc 100644
--- a/upgrade_analysis/models/upgrade_analysis.py
+++ b/upgrade_analysis/models/upgrade_analysis.py
@@ -429,10 +429,8 @@ def _parse_files(self, xml_files, module_name):
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 35fcd500578..649866379af 100644
--- a/upgrade_analysis/models/upgrade_comparison_config.py
+++ b/upgrade_analysis/models/upgrade_comparison_config.py
@@ -43,11 +43,11 @@ def get_connection(self):
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 @@ def test_connection(self):
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 f62c7ca3ee1..2f0db382726 100644
--- a/upgrade_analysis/models/upgrade_record.py
+++ b/upgrade_analysis/models/upgrade_record.py
@@ -138,7 +138,7 @@ def field_dump(self):
@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 @@ def _read_manifest(addon_dir):
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 09caee64cb1..e795cbc3313 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 66f003c1787..f363b810609 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 206795b42db..3ff1cb0a26e 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 431fc9635c8..51de8037bd3 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 b102d3afa02..3a8d1312739 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 8c54d4f59ba4dd3656c6f41c50e12f3b964f33d3 Mon Sep 17 00:00:00 2001
From: oca-ci
Date: Wed, 10 Nov 2021 20:11:18 +0000
Subject: [PATCH 44/81] [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 fb0550c0a90..2b4f5e0519f 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 428363d95e880b05436456bfbbcf3177637579fd Mon Sep 17 00:00:00 2001
From: OCA-git-bot
Date: Wed, 10 Nov 2021 20:13:40 +0000
Subject: [PATCH 45/81] [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 4fcf7f0cf22..13b346f3f42 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 6a1087c8f0e..fc5151a8e33 100644
--- a/upgrade_analysis/static/description/index.html
+++ b/upgrade_analysis/static/description/index.html
@@ -367,7 +367,7 @@ Upgrade Analysis
!! 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 @@
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 @@
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 19938fc9800ec6b6c74a6a833484e0b733627e6f Mon Sep 17 00:00:00 2001
From: Sylvain LE GAL
Date: Thu, 11 Nov 2021 11:52:16 +0100
Subject: [PATCH 46/81] [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 d07930884e4..47e9fdff1a1 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 2a6046e54dc..e9037765cca 100644
--- a/upgrade_analysis/models/upgrade_analysis.py
+++ b/upgrade_analysis/models/upgrade_analysis.py
@@ -10,8 +10,9 @@
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 @@ def analyze(self):
_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 @@ def generate_noupdate_changes(self):
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 00000000000..a9b5f059985
--- /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 19c9feca335958284de2877400a4775672f4d2d7 Mon Sep 17 00:00:00 2001
From: Sylvain LE GAL
Date: Sun, 14 Nov 2021 09:11:58 +0100
Subject: [PATCH 47/81] [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 e9037765cca..3cbfcd127f8 100644
--- a/upgrade_analysis/models/upgrade_analysis.py
+++ b/upgrade_analysis/models/upgrade_analysis.py
@@ -210,6 +210,8 @@ def analyze(self):
}
general_log = ""
+ no_changes_modules = []
+
for ignore_module in _IGNORE_MODULES:
if ignore_module in keys:
keys.remove(ignore_module)
@@ -232,6 +234,7 @@ def analyze(self):
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 @@ def analyze(self):
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 @@ def generate_noupdate_changes(self):
)
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 @@ def generate_module_coverage_file(self):
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 @@ def generate_module_coverage_file(self):
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 a9b5f059985..f5d532e5b08 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 c19ed725f0f2d5df096b172d1d386f4b8625d5f0 Mon Sep 17 00:00:00 2001
From: Sylvain LE GAL
Date: Mon, 15 Nov 2021 11:23:15 +0100
Subject: [PATCH 48/81] [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 3cbfcd127f8..f717b5c861a 100644
--- a/upgrade_analysis/models/upgrade_analysis.py
+++ b/upgrade_analysis/models/upgrade_analysis.py
@@ -564,8 +564,8 @@ def generate_module_coverage_file(self, no_changes_modules):
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 f5d532e5b08..ab598ae4ddd 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 921de7a0c2f84df629f9da3e33f4cb07ea7f1ecc Mon Sep 17 00:00:00 2001
From: OCA-git-bot
Date: Mon, 15 Nov 2021 20:20:10 +0000
Subject: [PATCH 49/81] 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 47e9fdff1a1..e5e4cdd10ee 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 c104892db6aeee9aa0121758963b066897a1fd4f Mon Sep 17 00:00:00 2001
From: Jean-Charles Drubay
Date: Tue, 10 May 2022 22:41:28 +0700
Subject: [PATCH 50/81] [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 00000000000..bd341e59dc0
--- /dev/null
+++ b/upgrade_analysis/readme/USAGE.rst
@@ -0,0 +1 @@
+`Usage instructions `_
From 2bb60d043f20b9d92191c40ddeb017965979392e Mon Sep 17 00:00:00 2001
From: OCA-git-bot
Date: Tue, 10 May 2022 21:01:36 +0000
Subject: [PATCH 51/81] [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 13b346f3f42..7756c266618 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 fc5151a8e33..80d2368355c 100644
--- a/upgrade_analysis/static/description/index.html
+++ b/upgrade_analysis/static/description/index.html
@@ -373,25 +373,30 @@ Upgrade Analysis
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 @@
Do not contact contributors directly about support or help with technical issues.
-
+
-
+
Therp BV
Opener B.V.
@@ -409,7 +414,7 @@
-
+
This module is maintained by the OCA.
OCA, or the Odoo Community Association, is a nonprofit organization whose
From c3077c5141104a57e37ee3dbe3451b0286acfb65 Mon Sep 17 00:00:00 2001
From: OCA-git-bot
Date: Tue, 10 May 2022 21:01:36 +0000
Subject: [PATCH 52/81] 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 e5e4cdd10ee..2cafcde86c8 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 695056b9e9538b3d7f8e389753b837429b2e7e6c Mon Sep 17 00:00:00 2001
From: Sylvain LE GAL
Date: Thu, 16 Jun 2022 12:15:04 +0200
Subject: [PATCH 53/81] [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 79e8c593905..48d1f8d9453 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 618bd8d9ac3fa9a659d48518ff4e4b47d6d6d5f9 Mon Sep 17 00:00:00 2001
From: Sylvain LE GAL
Date: Thu, 16 Jun 2022 12:42:07 +0200
Subject: [PATCH 54/81] [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 2cafcde86c8..251af030e18 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 067064a329a6ff06b1806dfee563c6742b156d6f Mon Sep 17 00:00:00 2001
From: OCA-git-bot
Date: Thu, 16 Jun 2022 10:53:15 +0000
Subject: [PATCH 55/81] [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 7756c266618..2b543ab74c7 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 80d2368355c..1f0de603c5e 100644
--- a/upgrade_analysis/static/description/index.html
+++ b/upgrade_analysis/static/description/index.html
@@ -393,6 +393,7 @@
@@ -432,6 +433,8 @@
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 0f790ca336e23d2d60890a42c3263f12e3b5898e Mon Sep 17 00:00:00 2001
From: OCA-git-bot
Date: Thu, 16 Jun 2022 10:53:15 +0000
Subject: [PATCH 56/81] 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 251af030e18..017ab77ab2a 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 c69be433ca96ca25686dffbc0a2d70452279fa9c Mon Sep 17 00:00:00 2001
From: Roy Le
Date: Tue, 5 Jul 2022 16:27:37 +0700
Subject: [PATCH 57/81] [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 f717b5c861a..dc52d47616e 100644
--- a/upgrade_analysis/models/upgrade_analysis.py
+++ b/upgrade_analysis/models/upgrade_analysis.py
@@ -324,6 +324,13 @@ def _get_xml_diff(
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 @@ 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"):
+ for record in data_node.xpath("./record") + data_node.xpath("./template"):
self._process_record_node(
record, noupdate, records_update, records_noupdate, module_name
)
From f07177c64b85494a614091a6e783b15665962880 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/81] [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 864277310e8..0a6f9ebb9e9 100644
--- a/upgrade_analysis/compare.py
+++ b/upgrade_analysis/compare.py
@@ -387,14 +387,22 @@ def match(match_fields, match_type="direct"):
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 match(match_fields, match_type="direct"):
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 match(match_fields, match_type="direct"):
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 dc52d47616e..8d0e53aa5d9 100644
--- a/upgrade_analysis/models/upgrade_analysis.py
+++ b/upgrade_analysis/models/upgrade_analysis.py
@@ -144,6 +144,7 @@ def analyze(self):
"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 2f0db382726..b8886fc6146 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 4541924d99f..42c35ff23d9 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 00000000000..0e44449338c
--- /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 00000000000..0650744f6bc
--- /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 00000000000..413bb238014
--- /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 00000000000..68cab246ada
--- /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 3a8d1312739..bfab4e55baf 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 3a766b1b1c8..0fd0464d664 100644
--- a/upgrade_analysis/wizards/upgrade_generate_record_wizard.py
+++ b/upgrade_analysis/wizards/upgrade_generate_record_wizard.py
@@ -72,6 +72,24 @@ def generate(self):
]
)
+ # 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 b152612812005c345a72cbc608e470d08ac88f94 Mon Sep 17 00:00:00 2001
From: oca-ci
Date: Mon, 18 Jul 2022 10:37:38 +0000
Subject: [PATCH 59/81] [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 2b4f5e0519f..0fdfaae71ef 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 e00d86d2918412d3dd9f4651b43788f6a05f2259 Mon Sep 17 00:00:00 2001
From: OCA-git-bot
Date: Mon, 18 Jul 2022 10:41:22 +0000
Subject: [PATCH 60/81] 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 017ab77ab2a..39ef860d06f 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 d87ced8decacf2c6528969a068b8a2888e40e3c7 Mon Sep 17 00:00:00 2001
From: OCA Transbot
Date: Mon, 18 Jul 2022 10:41:30 +0000
Subject: [PATCH 61/81] 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 234427e4a8d..4bc6821e07f 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 6197f0b924f0ae49d25eeaecb618d3e446be6e7c Mon Sep 17 00:00:00 2001
From: Ignacio Buioli
Date: Sun, 4 Sep 2022 03:50:33 +0000
Subject: [PATCH 62/81] 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 00000000000..44753623323
--- /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 ec03418f994692f5743c9d3c4fd8d12f9ea41dd6 Mon Sep 17 00:00:00 2001
From: Ignacio Buioli
Date: Sun, 4 Sep 2022 04:20:41 +0000
Subject: [PATCH 63/81] 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 44753623323..73cf7b78e5e 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 7b9161a32d262ab7e36c4979a6f9c7a9e2dd9efd Mon Sep 17 00:00:00 2001
From: OCA-git-bot
Date: Wed, 5 Oct 2022 00:55:38 +0000
Subject: [PATCH 64/81] 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 39ef860d06f..87d67f1d5a8 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 2b22a071f4bd805221b1ed4159bf535be2a71357 Mon Sep 17 00:00:00 2001
From: Stefan Rijnhart
Date: Wed, 5 Oct 2022 16:23:50 +0200
Subject: [PATCH 65/81] [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 2b543ab74c7..62b7497d685 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 87d67f1d5a8..3aeecb5efaa 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 1f0de603c5e..89fee6a45c4 100644
--- a/upgrade_analysis/static/description/index.html
+++ b/upgrade_analysis/static/description/index.html
@@ -3,7 +3,7 @@
-
+
Upgrade Analysis