[REF] rename files, apply OCA convention, remove obsolete 6.1 syntax, make the module installable, add readme folders

pull/2826/head
Sylvain LE GAL 2020-11-06 22:44:54 +01:00 committed by Stefan Rijnhart
parent ed44832568
commit f29ff2daa7
24 changed files with 441 additions and 498 deletions

View File

@ -1,59 +1,8 @@
.. image:: https://img.shields.io/badge/license-AGPL--3-blue.png ================
:target: https://www.gnu.org/licenses/agpl Upgrade Analysis
:alt: License: AGPL-3 ================
=============================== .. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
OpenUpgrade Database Comparison !! 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
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
<https://github.com/OCA/openupgrade/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 <https://odoo-community.org/logo.png>`_.
Contributors
------------
* Stefan Rijnhart <stefan@opener.amsterdam>
* Holger Brunn <hbrunn@therp.nl>
* 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>
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.

View File

@ -1,2 +1,5 @@
from . import models from . import models
from . import wizards
from . import blacklist from . import blacklist
from . import apriori
from . import compare

View File

@ -2,18 +2,21 @@
# Copyright 2016 Opener B.V. <https://opener.am> # Copyright 2016 Opener B.V. <https://opener.am>
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). # 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", "version": "14.0.1.0.0",
"category": "Migration", "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", "website": "https://github.com/OCA/server-tools",
"data": [ "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", "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, "installable": True,
"external_dependencies": { "external_dependencies": {

View File

@ -2,97 +2,12 @@
to help the matching process to help the matching process
""" """
renamed_modules = { 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 = { 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: # only used here for upgrade_analysis
renamed_models = { 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: # only used here for upgrade_analysis
merged_models = { 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/...
}

View File

@ -1,7 +1,7 @@
# coding: utf-8
# Copyright 2011-2015 Therp BV <https://therp.nl> # Copyright 2011-2015 Therp BV <https://therp.nl>
# Copyright 2015-2016 Opener B.V. <https://opener.am> # Copyright 2015-2016 Opener B.V. <https://opener.am>
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
# flake8: noqa: C901
##################################################################### #####################################################################
# library providing a function to analyse two progressive database # library providing a function to analyse two progressive database
@ -11,12 +11,13 @@
import collections import collections
import copy import copy
from odoo.addons.openupgrade_records.lib import apriori from . import apriori
def module_map(module): def module_map(module):
return apriori.renamed_modules.get( return apriori.renamed_modules.get(
module, apriori.merged_modules.get(module, module)) module, apriori.merged_modules.get(module, module)
)
def model_rename_map(model): def model_rename_map(model):
@ -24,8 +25,7 @@ def model_rename_map(model):
def model_map(model): def model_map(model):
return apriori.renamed_models.get( return apriori.renamed_models.get(model, apriori.merged_models.get(model, model))
model, apriori.merged_models.get(model, model))
def inv_model_map(model): def inv_model_map(model):
@ -34,12 +34,12 @@ def inv_model_map(model):
IGNORE_FIELDS = [ IGNORE_FIELDS = [
'create_date', "create_date",
'create_uid', "create_uid",
'id', "id",
'write_date', "write_date",
'write_uid', "write_uid",
] ]
def compare_records(dict_old, dict_new, fields): def compare_records(dict_old, dict_new, fields):
@ -51,17 +51,19 @@ def compare_records(dict_old, dict_new, fields):
Return True of False. Return True of False.
""" """
for field in fields: for field in fields:
if field == 'module': if field == "module":
if module_map(dict_old['module']) != dict_new['module']: if module_map(dict_old["module"]) != dict_new["module"]:
return False return False
elif field == 'model': elif field == "model":
if model_rename_map(dict_old['model']) != dict_new['model']: if model_rename_map(dict_old["model"]) != dict_new["model"]:
return False return False
elif field == 'other_prefix': elif field == "other_prefix":
if dict_old['module'] != dict_old['prefix'] or \ if (
dict_new['module'] != dict_new['prefix']: dict_old["module"] != dict_old["prefix"]
or dict_new["module"] != dict_new["prefix"]
):
return False return False
if dict_old['model'] == 'ir.ui.view': if dict_old["model"] == "ir.ui.view":
# basically, to avoid the assets_backend case # basically, to avoid the assets_backend case
return False return False
elif dict_old[field] != dict_new[field]: elif dict_old[field] != dict_new[field]:
@ -80,71 +82,69 @@ def search(item, item_list, fields):
continue continue
return other return other
# search for renamed fields # search for renamed fields
if 'field' in fields: if "field" in fields:
for other in item_list: for other in item_list:
if not item['field'] or item['field'] is not None or \ if not item["field"] or item["field"] is not None or item["isproperty"]:
item['isproperty']:
continue continue
if compare_records( if compare_records(dict(item, field=other["field"]), other, fields):
dict(item, field=other['field']), other, fields):
return other return other
return None return None
def fieldprint(old, new, field, text, reprs): def fieldprint(old, new, field, text, reprs):
fieldrepr = "%s (%s)" % (old['field'], old['type']) fieldrepr = "{} ({})".format(old["field"], old["type"])
fullrepr = '%-12s / %-24s / %-30s' % ( fullrepr = "{:<12} / {:<24} / {:<30}".format(old["module"], old["model"], fieldrepr)
old['module'], old['model'], fieldrepr)
if not text: if not text:
text = "%s is now '%s' ('%s')" % (field, new[field], old[field]) text = "{} is now '{}' ('{}')".format(field, new[field], old[field])
if field == 'relation': if field == "relation":
text += ' [nothing to do]' text += " [nothing to do]"
reprs[module_map(old['module'])].append("%s: %s" % (fullrepr, text)) reprs[module_map(old["module"])].append("{}: {}".format(fullrepr, text))
if field == 'module': if field == "module":
text = "previously in module %s" % old[field] text = "previously in module %s" % old[field]
fullrepr = '%-12s / %-24s / %-30s' % ( fullrepr = "{:<12} / {:<24} / {:<30}".format(
new['module'], old['model'], fieldrepr) new["module"], old["model"], fieldrepr
reprs[module_map(new['module'])].append("%s: %s" % (fullrepr, text)) )
reprs[module_map(new["module"])].append("{}: {}".format(fullrepr, text))
def report_generic(new, old, attrs, reprs): def report_generic(new, old, attrs, reprs):
for attr in attrs: for attr in attrs:
if attr == 'required': if attr == "required":
if old[attr] != new['required'] and new['required']: if old[attr] != new["required"] and new["required"]:
text = "now required" text = "now required"
if new['req_default']: if new["req_default"]:
text += ', req_default: %s' % new['req_default'] text += ", req_default: %s" % new["req_default"]
fieldprint(old, new, '', text, reprs) fieldprint(old, new, "", text, reprs)
elif attr == 'stored': elif attr == "stored":
if old[attr] != new[attr]: if old[attr] != new[attr]:
if new['stored']: if new["stored"]:
text = "is now stored" text = "is now stored"
else: else:
text = "not stored anymore" text = "not stored anymore"
fieldprint(old, new, '', text, reprs) fieldprint(old, new, "", text, reprs)
elif attr == 'isfunction': elif attr == "isfunction":
if old[attr] != new[attr]: if old[attr] != new[attr]:
if new['isfunction']: if new["isfunction"]:
text = "now a function" text = "now a function"
else: else:
text = "not a function anymore" text = "not a function anymore"
fieldprint(old, new, '', text, reprs) fieldprint(old, new, "", text, reprs)
elif attr == 'isproperty': elif attr == "isproperty":
if old[attr] != new[attr]: if old[attr] != new[attr]:
if new[attr]: if new[attr]:
text = "now a property" text = "now a property"
else: else:
text = "not a property anymore" text = "not a property anymore"
fieldprint(old, new, '', text, reprs) fieldprint(old, new, "", text, reprs)
elif attr == 'isrelated': elif attr == "isrelated":
if old[attr] != new[attr]: if old[attr] != new[attr]:
if new[attr]: if new[attr]:
text = "now related" text = "now related"
else: else:
text = "not related anymore" text = "not related anymore"
fieldprint(old, new, '', text, reprs) fieldprint(old, new, "", text, reprs)
elif old[attr] != new[attr]: elif old[attr] != new[attr]:
fieldprint(old, new, attr, '', reprs) fieldprint(old, new, attr, "", reprs)
def compare_sets(old_records, new_records): def compare_sets(old_records, new_records):
@ -160,7 +160,7 @@ def compare_sets(old_records, new_records):
def clean_records(records): def clean_records(records):
result = [] result = []
for record in records: for record in records:
if record['field'] not in IGNORE_FIELDS: if record["field"] not in IGNORE_FIELDS:
result.append(record) result.append(record)
return result return result
@ -168,8 +168,8 @@ def compare_sets(old_records, new_records):
new_records = clean_records(new_records) new_records = clean_records(new_records)
origlen = len(old_records) origlen = len(old_records)
new_models = set([column['model'] for column in new_records]) new_models = {column["model"] for column in new_records}
old_models = set([column['model'] for column in old_records]) old_models = {column["model"] for column in old_records}
matched_direct = 0 matched_direct = 0
matched_other_module = 0 matched_other_module = 0
@ -184,7 +184,7 @@ def compare_sets(old_records, new_records):
non_obsolete_old_records = [] non_obsolete_old_records = []
for column in copy.copy(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 in_obsolete_models += 1
else: else:
non_obsolete_old_records.append(column) non_obsolete_old_records.append(column)
@ -205,152 +205,193 @@ def compare_sets(old_records, new_records):
return count return count
matched_direct = match( matched_direct = match(
['module', 'mode', 'model', 'field'], ["module", "mode", "model", "field"],
['relation', 'type', 'selection_keys', 'inherits', 'stored', [
'isfunction', 'isrelated', 'required', 'table']) "relation",
"type",
"selection_keys",
"inherits",
"stored",
"isfunction",
"isrelated",
"required",
"table",
],
)
# other module, same type and operation # other module, same type and operation
matched_other_module = match( matched_other_module = match(
['mode', 'model', 'field', 'type'], ["mode", "model", "field", "type"],
['module', 'relation', 'selection_keys', 'inherits', 'stored', [
'isfunction', 'isrelated', 'required', 'table']) "module",
"relation",
"selection_keys",
"inherits",
"stored",
"isfunction",
"isrelated",
"required",
"table",
],
)
# other module, same operation, other type # other module, same operation, other type
matched_other_type = match( matched_other_type = match(
['mode', 'model', 'field'], ["mode", "model", "field"],
['relation', 'type', 'selection_keys', 'inherits', 'stored', [
'isfunction', 'isrelated', 'required', 'table']) "relation",
"type",
"selection_keys",
"inherits",
"stored",
"isfunction",
"isrelated",
"required",
"table",
],
)
printkeys = [ printkeys = [
'relation', 'required', 'selection_keys', "relation",
'req_default', 'inherits', 'mode', 'attachment', "required",
] "selection_keys",
"req_default",
"inherits",
"mode",
"attachment",
]
for column in old_records: for column in old_records:
# we do not care about removed non stored function fields # we do not care about removed non stored function fields
if not column['stored'] and ( if not column["stored"] and (column["isfunction"] or column["isrelated"]):
column['isfunction'] or column['isrelated']):
continue continue
if column['mode'] == 'create': if column["mode"] == "create":
column['mode'] = '' column["mode"] = ""
extra_message = ", ".join( 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: if extra_message:
extra_message = " " + extra_message extra_message = " " + extra_message
fieldprint( fieldprint(column, "", "", "DEL" + extra_message, reprs)
column, '', '', "DEL" + extra_message, reprs)
printkeys.extend([ printkeys.extend(
'hasdefault', [
]) "hasdefault",
]
)
for column in new_records: for column in new_records:
# we do not care about newly added non stored function fields # we do not care about newly added non stored function fields
if not column['stored'] and ( if not column["stored"] and (column["isfunction"] or column["isrelated"]):
column['isfunction'] or column['isrelated']):
continue continue
if column['mode'] == 'create': if column["mode"] == "create":
column['mode'] = '' column["mode"] = ""
printkeys_plus = printkeys.copy() printkeys_plus = printkeys.copy()
if column['isfunction'] or column['isrelated']: if column["isfunction"] or column["isrelated"]:
printkeys_plus.extend(['isfunction', 'isrelated', 'stored']) printkeys_plus.extend(["isfunction", "isrelated", "stored"])
extra_message = ", ".join( 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: if extra_message:
extra_message = " " + extra_message extra_message = " " + extra_message
fieldprint( fieldprint(column, "", "", "NEW" + extra_message, reprs)
column, '', '', "NEW" + extra_message, reprs)
for line in [ for line in [
"# %d fields matched," % (origlen - len(old_records)), "# %d fields matched," % (origlen - len(old_records)),
"# Direct match: %d" % matched_direct, "# Direct match: %d" % matched_direct,
"# Found in other module: %d" % matched_other_module, "# Found in other module: %d" % matched_other_module,
"# Found with different type: %d" % matched_other_type, "# Found with different type: %d" % matched_other_type,
"# In obsolete models: %d" % in_obsolete_models, "# In obsolete models: %d" % in_obsolete_models,
"# Not matched: %d" % len(old_records), "# Not matched: %d" % len(old_records),
"# New columns: %d" % len(new_records) "# New columns: %d" % len(new_records),
]: ]:
reprs['general'].append(line) reprs["general"].append(line)
return reprs return reprs
def compare_xml_sets(old_records, new_records): def compare_xml_sets(old_records, new_records):
reprs = collections.defaultdict(list) reprs = collections.defaultdict(list)
def match(match_fields, match_type='direct'): def match(match_fields, match_type="direct"):
matched_records = [] matched_records = []
for column in copy.copy(old_records): for column in copy.copy(old_records):
found = search(column, new_records, match_fields) found = search(column, new_records, match_fields)
if found: if found:
old_records.remove(column) old_records.remove(column)
new_records.remove(found) new_records.remove(found)
if match_type != 'direct': if match_type != "direct":
column['old'] = True column["old"] = True
found['new'] = True found["new"] = True
column[match_type] = found['module'] column[match_type] = found["module"]
found[match_type] = column['module'] found[match_type] = column["module"]
found['domain'] = column['domain'] != found['domain'] and \ found["domain"] = (
column['domain'] != '[]' and found['domain'] is False column["domain"] != found["domain"]
column['domain'] = False and column["domain"] != "[]"
column['noupdate_switched'] = False and found["domain"] is False
found['noupdate_switched'] = \ )
column['noupdate'] != found['noupdate'] column["domain"] = False
if match_type != 'direct': column["noupdate_switched"] = False
found["noupdate_switched"] = column["noupdate"] != found["noupdate"]
if match_type != "direct":
matched_records.append(column) matched_records.append(column)
matched_records.append(found) matched_records.append(found)
elif (match_type == 'direct' and found['domain']) or \ elif (match_type == "direct" and found["domain"]) or found[
found['noupdate_switched']: "noupdate_switched"
]:
matched_records.append(found) matched_records.append(found)
return matched_records return matched_records
# direct match # direct match
modified_records = match(['module', 'model', 'name']) modified_records = match(["module", "model", "name"])
# other module, same full xmlid # other module, same full xmlid
moved_records = match(['model', 'name'], 'moved') moved_records = match(["model", "name"], "moved")
# other module, same suffix, other prefix # 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: for record in old_records:
record['old'] = True record["old"] = True
record['domain'] = False record["domain"] = False
record['noupdate_switched'] = False record["noupdate_switched"] = False
for record in new_records: for record in new_records:
record['new'] = True record["new"] = True
record['domain'] = False record["domain"] = False
record['noupdate_switched'] = False record["noupdate_switched"] = False
sorted_records = sorted( sorted_records = sorted(
old_records + new_records + moved_records + renamed_records + old_records + new_records + moved_records + renamed_records + modified_records,
modified_records, key=lambda k: (k["model"], "old" in k, k["name"]),
key=lambda k: (k['model'], 'old' in k, k['name'])
) )
for entry in sorted_records: for entry in sorted_records:
content = '' content = ""
if 'old' in entry: if "old" in entry:
content = 'DEL %(model)s: %(name)s' % entry content = "DEL %(model)s: %(name)s" % entry
if 'moved' in entry: if "moved" in entry:
content += ' [potentially moved to %(moved)s module]' % entry content += " [potentially moved to %(moved)s module]" % entry
elif 'renamed' in entry: elif "renamed" in entry:
content += ' [renamed to %(renamed)s module]' % entry content += " [renamed to %(renamed)s module]" % entry
elif 'new' in entry: elif "new" in entry:
content = 'NEW %(model)s: %(name)s' % entry content = "NEW %(model)s: %(name)s" % entry
if 'moved' in entry: if "moved" in entry:
content += ' [potentially moved from %(moved)s module]' % entry content += " [potentially moved from %(moved)s module]" % entry
elif 'renamed' in entry: elif "renamed" in entry:
content += ' [renamed from %(renamed)s module]' % entry content += " [renamed from %(renamed)s module]" % entry
if 'old' not in entry and 'new' not in entry: if "old" not in entry and "new" not in entry:
content = '%(model)s: %(name)s' % entry content = "%(model)s: %(name)s" % entry
if entry['domain']: if entry["domain"]:
content += ' (deleted domain)' content += " (deleted domain)"
if entry['noupdate']: if entry["noupdate"]:
content += ' (noupdate)' content += " (noupdate)"
if entry['noupdate_switched']: if entry["noupdate_switched"]:
content += ' (noupdate switched)' content += " (noupdate switched)"
reprs[module_map(entry['module'])].append(content) reprs[module_map(entry["module"])].append(content)
return reprs return reprs
@ -360,79 +401,84 @@ def compare_model_sets(old_records, new_records):
""" """
reprs = collections.defaultdict(list) reprs = collections.defaultdict(list)
new_models = {column['model']: column['module'] for column in new_records} new_models = {column["model"]: column["module"] for column in new_records}
old_models = {column['model']: column['module'] for column in old_records} old_models = {column["model"]: column["module"] for column in old_records}
obsolete_models = [] obsolete_models = []
for column in copy.copy(old_records): for column in copy.copy(old_records):
model = column['model'] model = column["model"]
if model in old_models: if model in old_models:
if model not in new_models: if model not in new_models:
if model_map(model) not in new_models: if model_map(model) not in new_models:
obsolete_models.append(model) obsolete_models.append(model)
text = 'obsolete model %s' % model text = "obsolete model %s" % model
if column['model_type']: if column["model_type"]:
text += " [%s]" % column['model_type'] text += " [%s]" % column["model_type"]
reprs[module_map(column['module'])].append(text) reprs[module_map(column["module"])].append(text)
reprs['general'].append('obsolete model %s [module %s]' % ( reprs["general"].append(
model, module_map(column['module']))) "obsolete model %s [module %s]"
% (model, module_map(column["module"]))
)
else: else:
moved_module = '' moved_module = ""
if module_map(column['module']) != new_models[model_map( if module_map(column["module"]) != new_models[model_map(model)]:
model)]: moved_module = " in module %s" % new_models[model_map(model)]
moved_module = ' in module %s' % new_models[model_map( text = "obsolete model {} (renamed to {}{})".format(
model)] model,
text = 'obsolete model %s (renamed to %s%s)' % ( model_map(model),
model, model_map(model), moved_module) moved_module,
if column['model_type']: )
text += " [%s]" % column['model_type'] if column["model_type"]:
reprs[module_map(column['module'])].append(text) text += " [%s]" % column["model_type"]
reprs['general'].append( reprs[module_map(column["module"])].append(text)
'obsolete model %s (renamed to %s) [module %s]' % ( reprs["general"].append(
model, model_map(model), "obsolete model %s (renamed to %s) [module %s]"
module_map(column['module']))) % (model, model_map(model), module_map(column["module"]))
)
else: else:
if module_map(column['module']) != new_models[model]: if module_map(column["module"]) != new_models[model]:
text = 'model %s (moved to %s)' % ( text = "model {} (moved to {})".format(model, new_models[model])
model, new_models[model]) if column["model_type"]:
if column['model_type']: text += " [%s]" % column["model_type"]
text += " [%s]" % column['model_type'] reprs[module_map(column["module"])].append(text)
reprs[module_map(column['module'])].append(text) text = "model {} (moved from {})".format(model, old_models[model])
text = 'model %s (moved from %s)' % ( if column["model_type"]:
model, old_models[model]) text += " [%s]" % column["model_type"]
if column['model_type']:
text += " [%s]" % column['model_type']
for column in copy.copy(new_records): for column in copy.copy(new_records):
model = column['model'] model = column["model"]
if model in new_models: if model in new_models:
if model not in old_models: if model not in old_models:
if inv_model_map(model) not in old_models: if inv_model_map(model) not in old_models:
text = 'new model %s' % model text = "new model %s" % model
if column['model_type']: if column["model_type"]:
text += " [%s]" % column['model_type'] text += " [%s]" % column["model_type"]
reprs[column['module']].append(text) reprs[column["module"]].append(text)
reprs['general'].append('new model %s [module %s]' % ( reprs["general"].append(
model, column['module'])) "new model {} [module {}]".format(model, column["module"])
)
else: else:
moved_module = '' moved_module = ""
if column['module'] != module_map(old_models[inv_model_map( if column["module"] != module_map(old_models[inv_model_map(model)]):
model)]): moved_module = (
moved_module = ' in module %s' % old_models[ " in module %s" % old_models[inv_model_map(model)]
inv_model_map(model)] )
text = 'new model %s (renamed from %s%s)' % ( text = "new model {} (renamed from {}{})".format(
model, inv_model_map(model), moved_module) model,
if column['model_type']: inv_model_map(model),
text += " [%s]" % column['model_type'] moved_module,
reprs[column['module']].append(text) )
reprs['general'].append( if column["model_type"]:
'new model %s (renamed from %s) [module %s]' % ( text += " [%s]" % column["model_type"]
model, inv_model_map(model), column['module'])) reprs[column["module"]].append(text)
reprs["general"].append(
"new model %s (renamed from %s) [module %s]"
% (model, inv_model_map(model), column["module"])
)
else: else:
if column['module'] != module_map(old_models[model]): if column["module"] != module_map(old_models[model]):
text = 'model %s (moved from %s)' % ( text = "model {} (moved from {})".format(model, old_models[model])
model, old_models[model]) if column["model_type"]:
if column['model_type']: text += " [%s]" % column["model_type"]
text += " [%s]" % column['model_type'] reprs[column["module"]].append(text)
reprs[column['module']].append(text)
return reprs return reprs

View File

@ -1,5 +1,3 @@
from . import openupgrade_record from . import upgrade_comparison_config
from . import comparison_config from . import upgrade_attribute
from . import analysis_wizard from . import upgrade_record
from . import generate_records_wizard
from . import install_all_wizard

View File

@ -0,0 +1,20 @@
# Copyright 2011-2015 Therp BV <https://therp.nl>
# Copyright 2016 Opener B.V. <https://opener.am>
# 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,
)

View File

@ -8,25 +8,25 @@ from odoo import fields, models
from odoo.exceptions import UserError from odoo.exceptions import UserError
from odoo.tools.translate import _ from odoo.tools.translate import _
from ..lib import apriori from .. import apriori
class OpenupgradeComparisonConfig(models.Model): class UpgradeComparisonConfig(models.Model):
_name = "openupgrade.comparison.config" _name = "upgrade.comparison.config"
_description = "OpenUpgrade Comparison Configuration" _description = "Upgrade Comparison Configuration"
name = fields.Char() name = fields.Char()
server = fields.Char(required=True)
server = fields.Char(required=True, default="localhost")
port = fields.Integer(required=True, default=8069) 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) 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() last_log = fields.Text()
def get_connection(self): def get_connection(self):
@ -51,8 +51,8 @@ class OpenupgradeComparisonConfig(models.Model):
def analyze(self): def analyze(self):
""" Run the analysis wizard """ """ Run the analysis wizard """
self.ensure_one() self.ensure_one()
wizard = self.env["openupgrade.analysis.wizard"].create( wizard = self.env["upgrade.analysis.wizard"].create(
{"server_config": self.id} {"server_config_id": self.id}
) )
return { return {
"name": wizard._description, "name": wizard._description,

View File

@ -5,27 +5,18 @@
from odoo import api, fields, models from odoo import api, fields, models
class Attribute(models.Model): class UpgradeRecord(models.Model):
_name = "openupgrade.attribute" _name = "upgrade.record"
_description = "OpenUpgrade Attribute" _description = "Upgrade Record"
name = fields.Char(readonly=True) 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) module = fields.Char(readonly=True)
model = fields.Char(readonly=True) model = fields.Char(readonly=True)
field = fields.Char(readonly=True) field = fields.Char(readonly=True)
mode = fields.Selection( mode = fields.Selection(
[("create", "Create"), ("modify", "Modify")], [("create", "Create"), ("modify", "Modify")],
help="Set to Create if a field is newly created " help="Set to Create if a field is newly created "
@ -33,16 +24,26 @@ class Record(models.Model):
"existing field, set to Modify.", "existing field, set to Modify.",
readonly=True, readonly=True,
) )
type = fields.Selection( # Uh oh, reserved keyword
type = fields.Selection(
[("field", "Field"), ("xmlid", "XML ID"), ("model", "Model")], [("field", "Field"), ("xmlid", "XML ID"), ("model", "Model")],
readonly=True, 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) noupdate = fields.Boolean(readonly=True)
domain = fields.Char(readonly=True) domain = fields.Char(readonly=True)
prefix = fields.Char(compute="_compute_prefix_and_suffix") prefix = fields.Char(compute="_compute_prefix_and_suffix")
suffix = 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_original_module = fields.Char(compute="_compute_model_original_module")
model_type = fields.Char(compute="_compute_model_type") model_type = fields.Char(compute="_compute_model_type")
@api.depends("name") @api.depends("name")

View File

@ -0,0 +1,7 @@
* Stefan Rijnhart <stefan@opener.amsterdam>
* Holger Brunn <hbrunn@therp.nl>
* 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>
* Sylvain LE GAL <https://twitter.com/legalsylvain>

View File

@ -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

View File

@ -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)

View File

View File

@ -1,4 +1,7 @@
"id","name","model_id:id","group_id:id","perm_read","perm_write","perm_create","perm_unlink" 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_upgrade_record,upgrade.record all,model_upgrade_record,,1,0,0,0
"access_openupgrade_attribute","openupgrade.attribute all","model_openupgrade_attribute",,1,0,0,0 access_upgrade_attribute,upgrade.attribute all,model_upgrade_attribute,,1,0,0,0
"access_openupgrade_comparison_config","openupgrade.comparison.config","model_openupgrade_comparison_config",base.group_system,1,1,1,1 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

1 id name model_id:id group_id:id perm_read perm_write perm_create perm_unlink
2 access_openupgrade_record access_upgrade_record openupgrade.record all upgrade.record all model_openupgrade_record model_upgrade_record 1 0 0 0
3 access_openupgrade_attribute access_upgrade_attribute openupgrade.attribute all upgrade.attribute all model_openupgrade_attribute model_upgrade_attribute 1 0 0 0
4 access_openupgrade_comparison_config access_upgrade_comparison_config openupgrade.comparison.config upgrade.comparison.config model_openupgrade_comparison_config model_upgrade_comparison_config base.group_system 1 1 1 1
5 access_upgrade_analysis_wizard access_upgrade_analysis_wizard model_upgrade_analysis_wizard base.group_system 1 1 1 1
6 access_upgrade_generate_record_wizard access_upgrade_generate_record_wizard model_upgrade_generate_record_wizard base.group_system 1 1 1 1
7 access_upgrade_install_wizard access_upgrade_install_wizard model_upgrade_install_wizard base.group_system 1 1 1 1

View File

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="utf-8" ?>
<odoo>
<!-- Top level menu under 'Database structure' -->
<menuitem
id="menu_upgrade"
name="upgrade Development"
parent="base.menu_administration"
sequence="99"
/>
</odoo>

View File

@ -1,13 +1,11 @@
<?xml version="1.0" encoding="utf-8" ?> <?xml version="1.0" encoding="utf-8" ?>
<odoo> <odoo>
<record id="view_openupgrade_comparison_config_tree" model="ir.ui.view"> <record id="view_upgrade_comparison_config_tree" model="ir.ui.view">
<field name="name">view.openupgrade.comparison_config.tree</field> <field name="model">upgrade.comparison.config</field>
<field name="model">openupgrade.comparison.config</field>
<field name="arch" type="xml"> <field name="arch" type="xml">
<tree string="OpenUpgrade Comparison Config"> <tree>
<field name="name" /> <field name="name" />
<field name="protocol" />
<field name="server" /> <field name="server" />
<field name="port" /> <field name="port" />
<field name="database" /> <field name="database" />
@ -15,14 +13,12 @@
</field> </field>
</record> </record>
<record id="view_openupgrade_comparison_config_form" model="ir.ui.view"> <record id="view_upgrade_comparison_config_form" model="ir.ui.view">
<field name="name">view.openupgrade.comparison_config.form</field> <field name="model">upgrade.comparison.config</field>
<field name="model">openupgrade.comparison.config</field>
<field name="arch" type="xml"> <field name="arch" type="xml">
<form string="OpenUpgrade Comparison Config" version="6.1"> <form>
<group> <group>
<field name="name" /> <field name="name" />
<field name="protocol" />
<field name="server" /> <field name="server" />
<field name="port" /> <field name="port" />
<field name="database" /> <field name="database" />
@ -57,21 +53,18 @@
</form> </form>
</field> </field>
</record> </record>
)
<record <record id="action_upgrade_comparison_config_tree" model="ir.actions.act_window">
id="action_openupgrade_comparison_config_tree" <field name="name">upgrade Comparison Configs</field>
model="ir.actions.act_window"
>
<field name="name">OpenUpgrade Comparison Configs</field>
<field name="type">ir.actions.act_window</field> <field name="type">ir.actions.act_window</field>
<field name="res_model">openupgrade.comparison.config</field> <field name="res_model">upgrade.comparison.config</field>
</record> </record>
<menuitem <menuitem
action="action_openupgrade_comparison_config_tree" action="action_upgrade_comparison_config_tree"
id="menu_openupgrade_comparison_config" id="menu_upgrade_comparison_config"
name="Comparison Configurations" name="Comparison Configurations"
parent="menu_openupgrade" parent="menu_upgrade"
/> />
</odoo> </odoo>

View File

@ -1,17 +1,8 @@
<?xml version="1.0" encoding="utf-8" ?> <?xml version="1.0" encoding="utf-8" ?>
<odoo> <odoo>
<!-- Top level menu under 'Database structure' --> <record id="view_upgrade_record_search" model="ir.ui.view">
<menuitem <field name="model">upgrade.record</field>
id="menu_openupgrade"
name="OpenUpgrade Development"
parent="base.menu_administration"
sequence="99"
/>
<record id="view_openupgrade_record_search" model="ir.ui.view">
<field name="name">Search view for openupgrade records</field>
<field name="model">openupgrade.record</field>
<field name="arch" type="xml"> <field name="arch" type="xml">
<search> <search>
<field name="module" /> <field name="module" />
@ -39,11 +30,10 @@
</field> </field>
</record> </record>
<record id="view_openupgrade_record_tree" model="ir.ui.view"> <record id="view_upgrade_record_tree" model="ir.ui.view">
<field name="name">view.openupgrade.record.tree</field> <field name="model">upgrade.record</field>
<field name="model">openupgrade.record</field>
<field name="arch" type="xml"> <field name="arch" type="xml">
<tree string="OpenUpgrade Records"> <tree>
<field name="module" /> <field name="module" />
<field name="model" /> <field name="model" />
<field name="field" /> <field name="field" />
@ -54,11 +44,10 @@
</field> </field>
</record> </record>
<record id="view_openupgrade_record_form" model="ir.ui.view"> <record id="view_upgrade_record_form" model="ir.ui.view">
<field name="name">view.openupgrade.record.form</field> <field name="model">upgrade.record</field>
<field name="model">openupgrade.record</field>
<field name="arch" type="xml"> <field name="arch" type="xml">
<form string="OpenUpgrade Record" version="6.1"> <form>
<field name="module" /> <field name="module" />
<field name="model" /> <field name="model" />
<field name="field" /> <field name="field" />
@ -80,17 +69,17 @@
</field> </field>
</record> </record>
<record id="action_openupgrade_record_tree" model="ir.actions.act_window"> <record id="action_upgrade_record_tree" model="ir.actions.act_window">
<field name="name">OpenUpgrade Records</field> <field name="name">upgrade Records</field>
<field name="type">ir.actions.act_window</field> <field name="type">ir.actions.act_window</field>
<field name="res_model">openupgrade.record</field> <field name="res_model">upgrade.record</field>
</record> </record>
<menuitem <menuitem
action="action_openupgrade_record_tree" action="action_upgrade_record_tree"
id="menu_openupgrade_records" id="menu_upgrade_records"
name="Records" name="Records"
parent="menu_openupgrade" parent="menu_upgrade"
/> />
</odoo> </odoo>

View File

@ -0,0 +1,3 @@
from . import upgrade_analysis_wizard
from . import upgrade_generate_record_wizard
from . import upgrade_install_wizard

View File

@ -8,15 +8,15 @@ import os
from odoo import fields, models from odoo import fields, models
from odoo.modules import get_module_path from odoo.modules import get_module_path
from ..lib import compare from .. import compare
class AnalysisWizard(models.TransientModel): class UpgradeAnalysisWizard(models.TransientModel):
_name = "openupgrade.analysis.wizard" _name = "upgrade.analysis.wizard"
_description = "OpenUpgrade Analysis Wizard" _description = "upgrade Analysis Wizard"
server_config = fields.Many2one( server_config_id = fields.Many2one(
"openupgrade.comparison.config", "Configuration", required=True "upgrade.comparison.config", "Configuration", required=True
) )
state = fields.Selection( state = fields.Selection(
[("init", "Init"), ("ready", "Ready")], readonly=True, default="init" [("init", "Init"), ("ready", "Ready")], readonly=True, default="init"
@ -33,7 +33,7 @@ class AnalysisWizard(models.TransientModel):
change set 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) module_path = get_module_path(module)
if not module_path: if not module_path:
return "ERROR: could not find module path:\n" return "ERROR: could not find module path:\n"
@ -53,9 +53,9 @@ class AnalysisWizard(models.TransientModel):
return None return None
self.ensure_one() self.ensure_one()
connection = self.server_config.get_connection() connection = self.server_config_id.get_connection()
remote_record_obj = connection.env["openupgrade.record"] remote_record_obj = connection.env["upgrade.record"]
local_record_obj = self.env["openupgrade.record"] local_record_obj = self.env["upgrade.record"]
# Retrieve field representations and compare # Retrieve field representations and compare
remote_records = remote_record_obj.field_dump() remote_records = remote_record_obj.field_dump()
@ -168,9 +168,9 @@ class AnalysisWizard(models.TransientModel):
"base", "base",
modules["base"].installed_version, modules["base"].installed_version,
general, 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}) self.write({"state": "ready", "log": general})
return { return {

View File

@ -10,8 +10,8 @@ from odoo.modules.registry import Registry
class GenerateWizard(models.TransientModel): class GenerateWizard(models.TransientModel):
_name = "openupgrade.generate.records.wizard" _name = "upgrade.generate.record.wizard"
_description = "OpenUpgrade Generate Records Wizard" _description = "Upgrade Generate Record Wizard"
_rec_name = "state" _rec_name = "state"
state = fields.Selection([("init", "init"), ("ready", "ready")], default="init") state = fields.Selection([("init", "init"), ("ready", "ready")], default="init")
@ -35,9 +35,9 @@ class GenerateWizard(models.TransientModel):
TODO: update module list and versions, then update all modules?""" TODO: update module list and versions, then update all modules?"""
# Truncate the records table # Truncate the records table
if openupgrade_tools.table_exists( if openupgrade_tools.table_exists(
self.env.cr, "openupgrade_attribute" self.env.cr, "upgrade_attribute"
) and openupgrade_tools.table_exists(self.env.cr, "openupgrade_record"): ) and openupgrade_tools.table_exists(self.env.cr, "upgrade_record"):
self.env.cr.execute("TRUNCATE openupgrade_attribute, openupgrade_record;") self.env.cr.execute("TRUNCATE upgrade_attribute, upgrade_record;")
# Run any quirks # Run any quirks
self.quirk_standard_calendar_attendances() self.quirk_standard_calendar_attendances()
@ -67,7 +67,7 @@ class GenerateWizard(models.TransientModel):
# Set domain property # Set domain property
self.env.cr.execute( self.env.cr.execute(
""" UPDATE openupgrade_record our """ UPDATE upgrade_record our
SET domain = iaw.domain SET domain = iaw.domain
FROM ir_model_data imd FROM ir_model_data imd
JOIN ir_act_window iaw ON imd.res_id = iaw.id JOIN ir_act_window iaw ON imd.res_id = iaw.id
@ -79,13 +79,13 @@ class GenerateWizard(models.TransientModel):
) )
self.env.cache.invalidate( self.env.cache.invalidate(
[ [
(self.env["openupgrade.record"]._fields["domain"], None), (self.env["upgrade.record"]._fields["domain"], None),
] ]
) )
# Set noupdate property from ir_model_data # Set noupdate property from ir_model_data
self.env.cr.execute( self.env.cr.execute(
""" UPDATE openupgrade_record our """ UPDATE upgrade_record our
SET noupdate = imd.noupdate SET noupdate = imd.noupdate
FROM ir_model_data imd FROM ir_model_data imd
WHERE our.type = 'xmlid' WHERE our.type = 'xmlid'
@ -101,7 +101,7 @@ class GenerateWizard(models.TransientModel):
# Log model records # Log model records
self.env.cr.execute( self.env.cr.execute(
"""INSERT INTO openupgrade_record """INSERT INTO upgrade_record
(module, name, model, type) (module, name, model, type)
SELECT imd2.module, imd2.module || '.' || imd.name AS name, SELECT imd2.module, imd2.module || '.' || imd.name AS name,
im.model, 'model' AS type im.model, 'model' AS type

View File

@ -9,9 +9,9 @@ from odoo.osv.expression import AND
from ..blacklist import BLACKLIST_MODULES from ..blacklist import BLACKLIST_MODULES
class InstallAll(models.TransientModel): class UpgradeInstallWizard(models.TransientModel):
_name = "openupgrade.install.all.wizard" _name = "upgrade.install.wizard"
_description = "OpenUpgrade Install All Wizard" _description = "Upgrade Install Wizard"
state = fields.Selection( state = fields.Selection(
[("init", "init"), ("ready", "ready")], readonly=True, default="init" [("init", "init"), ("ready", "ready")], readonly=True, default="init"
@ -22,7 +22,7 @@ class InstallAll(models.TransientModel):
def default_get(self, fields): def default_get(self, fields):
"""Update module list and retrieve the number """Update module list and retrieve the number
of installable modules""" of installable modules"""
res = super(InstallAll, self).default_get(fields) res = super().default_get(fields)
update, add = self.env["ir.module.module"].update_list() update, add = self.env["ir.module.module"].update_list()
modules = self.env["ir.module.module"].search( modules = self.env["ir.module.module"].search(
[("state", "not in", ["uninstallable", "unknown"])] [("state", "not in", ["uninstallable", "unknown"])]

View File

@ -1,13 +1,12 @@
<?xml version="1.0" encoding="utf-8" ?> <?xml version="1.0" encoding="utf-8" ?>
<odoo> <odoo>
<record id="view_openupgrade_analysis_wizard_form" model="ir.ui.view"> <record id="view_upgrade_analysis_wizard_form" model="ir.ui.view">
<field name="name">view.openupgrade.analysis_wizard.form</field> <field name="model">upgrade.analysis.wizard</field>
<field name="model">openupgrade.analysis.wizard</field>
<field name="arch" type="xml"> <field name="arch" type="xml">
<form string="OpenUpgrade Analysis Wizard"> <form>
<group> <group>
<field name="server_config" readonly="1" /> <field name="server_config_id" readonly="1" />
<field name="state" /> <field name="state" />
<field <field
name="log" name="log"

View File

@ -1,18 +1,17 @@
<?xml version="1.0" encoding="utf-8" ?> <?xml version="1.0" encoding="utf-8" ?>
<odoo> <odoo>
<record id="view_openupgrade_generate_records_wizard_form" model="ir.ui.view"> <record id="view_upgrade_generate_record_wizard_form" model="ir.ui.view">
<field name="name">view.openupgrade.generate_records_wizard.form</field> <field name="model">upgrade.generate.record.wizard</field>
<field name="model">openupgrade.generate.records.wizard</field>
<field name="arch" type="xml"> <field name="arch" type="xml">
<form string="OpenUpgrade Generate Records Wizard"> <form string="upgrade Generate Record Wizard">
<field name="state" invisible="1" /> <field name="state" invisible="1" />
<group states="init" colspan="4"> <group states="init" colspan="4">
<p <p
>This will reinitialize all the modules installed on this database. Do not continue if you use this database in production.</p> >This will reinitialize all the modules installed on this database. Do not continue if you use this database in production.</p>
</group> </group>
<group states="ready" colspan="4"> <group states="ready" colspan="4">
<p>Modules initialized and records created</p> <p>Modules initialized and record created</p>
</group> </group>
<footer> <footer>
<button <button
@ -28,19 +27,19 @@
</field> </field>
</record> </record>
<record id="action_generate_records" model="ir.actions.act_window"> <record id="action_upgrade_generate_record_wizard" model="ir.actions.act_window">
<field name="name">Generate Records</field> <field name="name">Generate Records</field>
<field name="type">ir.actions.act_window</field> <field name="type">ir.actions.act_window</field>
<field name="res_model">openupgrade.generate.records.wizard</field> <field name="res_model">upgrade.generate.record.wizard</field>
<field name="view_mode">form,tree</field> <field name="view_mode">form,tree</field>
<field name="target">new</field> <field name="target">new</field>
</record> </record>
<menuitem <menuitem
name="Generate Records" name="Generate Records"
id="menu_openupgrade_generate_records" id="menu_upgrade_generate_record"
parent="menu_openupgrade" parent="menu_upgrade"
action="action_generate_records" action="action_upgrade_generate_record_wizard"
sequence="15" sequence="15"
/> />

View File

@ -1,11 +1,10 @@
<?xml version="1.0" encoding="utf-8" ?> <?xml version="1.0" encoding="utf-8" ?>
<odoo> <odoo>
<record id="view_openupgrade_install_all_wizard_form" model="ir.ui.view"> <record id="view_upgrade_install_wizard_form" model="ir.ui.view">
<field name="name">view.openupgrade.install_all_wizard.form</field> <field name="model">upgrade.install.wizard</field>
<field name="model">openupgrade.install.all.wizard</field>
<field name="arch" type="xml"> <field name="arch" type="xml">
<form string="OpenUpgrade Install All Modules Wizard"> <form>
<field name="state" invisible="1" /> <field name="state" invisible="1" />
<group states="init" colspan="4"> <group states="init" colspan="4">
<p <p
@ -29,19 +28,19 @@
</field> </field>
</record> </record>
<record id="action_install_all" model="ir.actions.act_window"> <record id="action_upgrade_install_wizard" model="ir.actions.act_window">
<field name="name">Install All Modules</field> <field name="name">Install Modules</field>
<field name="type">ir.actions.act_window</field> <field name="type">ir.actions.act_window</field>
<field name="res_model">openupgrade.install.all.wizard</field> <field name="res_model">upgrade.install.wizard</field>
<field name="view_mode">form,tree</field> <field name="view_mode">form,tree</field>
<field name="target">new</field> <field name="target">new</field>
</record> </record>
<menuitem <menuitem
name="Install All Modules" name="Install Modules"
id="menu_openupgrade_install_all" id="menu_upgrade_install"
parent="menu_openupgrade" parent="menu_upgrade"
action="action_install_all" action="action_upgrade_install_wizard"
sequence="14" sequence="14"
/> />