diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 00000000000..4694712cf5f --- /dev/null +++ b/requirements.txt @@ -0,0 +1,4 @@ +# generated from manifests external_dependencies +dataclasses +odoorpc +openupgradelib diff --git a/upgrade_analysis/README.rst b/upgrade_analysis/README.rst new file mode 100644 index 00000000000..29b4c06814c --- /dev/null +++ b/upgrade_analysis/README.rst @@ -0,0 +1,133 @@ +.. image:: https://odoo-community.org/readme-banner-image + :target: https://odoo-community.org/get-involved?utm_source=readme + :alt: Odoo Community Association + +================ +Upgrade Analysis +================ + +.. + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! This file is generated by oca-gen-addon-readme !! + !! changes will be overwritten. !! + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! source digest: sha256:7d83347c5c453bd132f25afe4f88b33bab0a7eb4f4b94796a52e6e9b57d311cc + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +.. |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/license-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/19.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-19-0/server-tools-19-0-upgrade_analysis + :alt: Translate me on Weblate +.. |badge5| image:: https://img.shields.io/badge/runboat-Try%20me-875A7B.png + :target: https://runboat.odoo-community.org/builds?repo=OCA/server-tools&target_branch=19.0 + :alt: Try me on Runboat + +|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 + +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:: + :local: + +Usage +===== + +`Usage instructions `__ + +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 +=========== + +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 to smash 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 + +- Ferdinand Gassauer + +- Florent Xicluna + +- Miquel Raïch + +- Sylvain LE GAL + +- `Tecnativa `__: + + - Pedro M. Baeza + - Sergio Teruel + +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. + +.. |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/__init__.py b/upgrade_analysis/__init__.py new file mode 100644 index 00000000000..172ae9a2543 --- /dev/null +++ b/upgrade_analysis/__init__.py @@ -0,0 +1,6 @@ +from . import odoo_patch +from . import models +from . import wizards +from . import blacklist +from . import compare +from . import upgrade_log diff --git a/upgrade_analysis/__manifest__.py b/upgrade_analysis/__manifest__.py new file mode 100644 index 00000000000..916fd0d9a93 --- /dev/null +++ b/upgrade_analysis/__manifest__.py @@ -0,0 +1,29 @@ +# Copyright 2011-2015 Therp BV +# Copyright 2016 Opener B.V. +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). +{ + "name": "Upgrade Analysis", + "summary": "Performs a difference analysis between modules" + " installed on two different Odoo instances", + "version": "19.0.1.0.0", + "category": "Migration", + "author": "Therp BV, Opener B.V., GRAP, Odoo Community Association (OCA)", + "maintainers": ["StefanRijnhart", "legalsylvain"], + "website": "https://github.com/OCA/server-tools", + "data": [ + "templates/module_coverage_template.xml", + "security/ir.model.access.csv", + "views/menu.xml", + "views/view_upgrade_comparison_config.xml", + "views/view_upgrade_analysis.xml", + "views/view_upgrade_record.xml", + "wizards/view_upgrade_generate_record_wizard.xml", + "wizards/view_upgrade_install_wizard.xml", + ], + "installable": True, + "depends": ["base"], + "external_dependencies": { + "python": ["dataclasses", "odoorpc", "openupgradelib"], + }, + "license": "AGPL-3", +} diff --git a/upgrade_analysis/blacklist.py b/upgrade_analysis/blacklist.py new file mode 100644 index 00000000000..b280aac2405 --- /dev/null +++ b/upgrade_analysis/blacklist.py @@ -0,0 +1,15 @@ +BLACKLIST_MODULES = [ + "payment_alipay", + "payment_ogone", + "payment_payulatam", + "payment_payumoney", +] + +# 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 continuously. + +# 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/compare.py b/upgrade_analysis/compare.py new file mode 100644 index 00000000000..044e4a959ec --- /dev/null +++ b/upgrade_analysis/compare.py @@ -0,0 +1,637 @@ +# 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 +# layouts from the OpenUpgrade server. +##################################################################### + +import collections +import copy +from ast import literal_eval + +try: + from odoo.addons.openupgrade_scripts import apriori +except ImportError: + from dataclasses import dataclass + from dataclasses import field as dc_field + + @dataclass + class NullApriori: + 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() + + +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_merge_map(model): + return apriori.merged_models.get(model, model) + + +def model_map(model): + return apriori.renamed_models.get(model, model_merge_map(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 or 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 == "relation": + if model_map(dict_old["relation"]) != dict_new["relation"]: + 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, 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 + 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: + 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 = "{}".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 = f"{field} is now '{new[field]}' ('{old[field]}')" + if field in ("column1", "column2"): + text += f" [{old['table']}]" + if field == "relation": + text += " [nothing to do]" + if field == "selection_keys": + old_selection_keys = old.get("selection_keys") or "" + new_selection_keys = new.get("selection_keys") or "" + try: + old_selection_keys = literal_eval(old_selection_keys) + new_selection_keys = literal_eval(new_selection_keys) + except Exception: # pylint: disable=except-pass + pass + if isinstance(old_selection_keys, tuple | list) and isinstance( + new_selection_keys, tuple | list + ): + removed = sorted(set(old_selection_keys) - set(new_selection_keys)) + added = sorted(set(new_selection_keys) - set(old_selection_keys)) + text = ( + f"{field} {added and ('added: [' + ', '.join(added) + ']') or ''}" + f"{added and removed and ', ' or ''}" + f"{removed and ('removed: [' + ', '.join(removed) + ']') or ''}" + ) + if added and not removed: + text += " (most likely nothing to do)" + if field != "module": + reprs[module_map(new["module"])].append(f"{fullrepr}: {text}") + if field == "module": + reprs[module_map(old["module"])].append(f"{fullrepr}: {text}") + text = f"previously in module {old[field]}" + fullrepr = "{:<12} / {:<24} / {:<30}".format( + new["module"], old["model"], fieldrepr + ) + reprs[module_map(new["module"])].append(f"{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" + fieldprint(old, new, "", text, reprs) + elif attr == "stored": + if old[attr] != new[attr]: + if new["stored"]: + if new.get("isproperty") and old.get("isproperty"): + text = "needs conversion to v18-style company dependent" + else: + 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 attr == "translate": + if old[attr] != new[attr]: + if new[attr]: + text = "now translatable" + else: + text = "not translatable 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) + + +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 = {column["model"] for column in new_records} + old_models = {column["model"] for column in old_records} + + 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", "type"], + [ + "relation", + "type", + "selection_keys", + "_inherits", + "stored", + "isfunction", + "isrelated", + "translate", + "required", + "table", + "_order", + ], + ) + + # same module, other type + matched_other_type = match( + ["module", "mode", "model", "field"], + [ + "relation", + "type", + "selection_keys", + "_inherits", + "stored", + "isfunction", + "isrelated", + "translate", + "required", + "table", + "_order", + ], + ) + + # other module, same type + matched_other_module = match( + ["mode", "model", "field", "type"], + [ + "module", + "relation", + "selection_keys", + "_inherits", + "stored", + "isfunction", + "isrelated", + "translate", + "required", + "table", + "_order", + ], + ) + + # same module, other type + matched_other_type += match( + ["module", "model", "field"], + [ + "relation", + "type", + "selection_keys", + "_inherits", + "stored", + "isfunction", + "isrelated", + "required", + "table", + "_order", + ], + ) + + # other module, other type + matched_other_module_other_type = match( + ["mode", "model", "field"], + [ + "module", + "relation", + "type", + "selection_keys", + "_inherits", + "stored", + "isfunction", + "isrelated", + "required", + "table", + "_order", + ], + ) + + # Info that is displayed for deleted fields + printkeys_old = [ + "relation", + "required", + "selection_keys", + "_inherits", + "mode", + "attachment", + ] + # Info that is displayed for new fields + printkeys_new = printkeys_old + [ + "hasdefault", + "translate", + ] + for column in old_records: + if column["field"] == "_order": + continue + # we do not care about removed non stored function/related fields + if not column["stored"] and (column["isfunction"] or column["isrelated"]): + continue + if column["mode"] == "create": + column["mode"] = "" + printkeys = printkeys_old.copy() + if not column["stored"] and not column["mode"]: + printkeys.extend(["stored"]) + extra_message = ", ".join( + [ + k + ": " + str(column[k] or False) if k != str(column[k]) else k + for k in printkeys + if k == "stored" or column[k] + ] + ) + if extra_message: + extra_message = " " + extra_message + fieldprint(column, column, "", "DEL" + extra_message, reprs) + + for column in new_records: + if column["field"] == "_order": + continue + # we do not care about newly added non stored function/related fields + if not column["stored"] and (column["isfunction"] or column["isrelated"]): + continue + if column["mode"] == "create": + column["mode"] = "" + printkeys = printkeys_new.copy() + if column["isfunction"] or column["isrelated"]: + printkeys.extend(["isfunction", "isrelated", "stored"]) + if not column["stored"] and not column["mode"]: + printkeys.extend(["stored"]) + extra_message = ", ".join( + [ + k + ": " + str(column[k] or False) if k != str(column[k]) else k + for k in printkeys + if k == "stored" or column[k] + ] + ) + if extra_message: + extra_message = " " + extra_message + fieldprint(column, column, "", "NEW" + extra_message, reprs) + + for line in [ + f"# {origlen - len(old_records)} fields matched,", + f"# Direct match: {matched_direct}", + f"# Found in other module: {matched_other_module}", + f"# Found with different type: {matched_other_type}", + "# Found in other module with different type: " + f"{matched_other_module_other_type}", + f"# In obsolete models: {in_obsolete_models}", + f"# Not matched: {len(old_records)}", + f"# New columns: {len(new_records)}", + ]: + reprs["general"].append(line) + return reprs + + +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): + 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 + found["definition"] = ( + column["definition"] + and str(column["definition"]).lower().replace(" ", "") + != str(found["definition"]).lower().replace(" ", "") + 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["definition"]) + ) or found["noupdate_switched"]: + matched_records.append(found) + return matched_records + + # direct match + modified_records = match(["module", "model", "name"]) + + # updated records (will be excluded) + match_updates(["model", "name"]) + + # other module, same full xmlid + moved_records = match(["model", "name"], "moved") + + # 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["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( + 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 = f"DEL {entry['model']}: {entry['name']}" + if "moved" in entry: + content += f" [moved to {entry['moved']} module]" + elif "renamed" in entry: + content += f" [renamed to {entry['renamed']} module]" + elif "new" in entry: + content = f"NEW {entry['model']}: {entry['name']}" + if "moved" in entry: + content += f" [moved from {entry['moved']} module]" + elif "renamed" in entry: + content += f" [renamed from {entry['renamed']} module]" + if "old" not in entry and "new" not in entry: + content = f"{entry['model']}: {entry['name']}" + if entry["domain"]: + content += " (deleted domain)" + if entry["definition"]: + content += f" (changed definition: {entry['definition']})" + 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 = f"obsolete model {model}" + if column["model_type"]: + text += f" [{column['model_type']}]" + reprs[module_map(column["module"])].append(text) + reprs["general"].append( + f"obsolete model {model} " + f"[module {module_map(column['module'])}]" + ) + elif model_merge_map(model) in new_models: + text = f"obsolete model {model} (merged to {model_map(model)})" + if column["model_type"]: + text += f" [{column['model_type']}]" + reprs[module_map(column["module"])].append(text) + reprs["general"].append( + f"obsolete model {model} (merged to {model_map(model)}) " + f"[module {module_map(column['module'])}]" + ) + else: + moved_module = "" + if module_map(column["module"]) != new_models[model_map(model)]: + moved_module = f" in module {new_models[model_map(model)]}" + text = ( + f"obsolete model {model}" + f" (renamed to {model_map(model)}{moved_module})" + ) + if column["model_type"]: + text += f" [{column['model_type']}]" + reprs[module_map(column["module"])].append(text) + reprs["general"].append( + f"obsolete model {model} (renamed to {model_map(model)}) " + f"[module {module_map(column['module'])}]" + ) + else: + if module_map(column["module"]) != new_models[model]: + text = f"model {model} (moved to {new_models[model]})" + if column["model_type"]: + text += f" [{column['model_type']}]" + reprs[module_map(column["module"])].append(text) + text = f"model {model} (moved from {old_models[model]})" + if column["model_type"]: + text += f" [{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 = f"new model {model}" + if column["model_type"]: + text += f" [{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 = f" in module {old_models[inv_model_map(model)]}" + text = ( + f"new model {model} " + f"(renamed from {inv_model_map(model)}{moved_module})" + ) + if column["model_type"]: + text += f" [{column['model_type']}]" + reprs[column["module"]].append(text) + reprs["general"].append( + f"new model {model} (renamed from {inv_model_map(model)}) " + f"[module {column['module']}]" + ) + else: + if column["module"] != module_map(old_models[model]): + text = f"model {model} (moved from {old_models[model]})" + if column["model_type"]: + text += f" [{column['model_type']}]" + reprs[column["module"]].append(text) + return reprs diff --git a/upgrade_analysis/i18n/es_AR.po b/upgrade_analysis/i18n/es_AR.po new file mode 100644 index 00000000000..0937af9cf04 --- /dev/null +++ b/upgrade_analysis/i18n/es_AR.po @@ -0,0 +1,567 @@ +# 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" +"PO-Revision-Date: 2024-09-17 02:06+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 5.6.2\n" + +#. module: upgrade_analysis +#: model_terms:ir.ui.view,arch_db:upgrade_analysis.module_coverage +msgid "->" +msgstr "" + +#. module: upgrade_analysis +#: model_terms:ir.ui.view,arch_db:upgrade_analysis.module_coverage +msgid "" +"============================\n" +"\n" +".. include:: coverage_legend.rst\n" +"\n" +"+---------------------------------------------------+----------------------" +"+-------------------------------------------------+\n" +"| Module | Status + " +"Extra Information |\n" +"+===================================================+======================+=================================================+" +msgstr "" + +#. module: upgrade_analysis +#: model_terms:ir.ui.view,arch_db:upgrade_analysis.view_upgrade_install_wizard_form +msgid "All Modules" +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 "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 "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 "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 "Análisis" + +#. module: upgrade_analysis +#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_analysis__analysis_date +msgid "Analysis Date" +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 "Análisis de Cantidad" + +#. module: upgrade_analysis +#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_record__attribute_ids +msgid "Attribute" +msgstr "Atributo" + +#. module: upgrade_analysis +#: model_terms:ir.ui.view,arch_db:upgrade_analysis.view_upgrade_record_form +msgid "Attributes" +msgstr "Atributos" + +#. module: upgrade_analysis +#. odoo-python +#: code:addons/upgrade_analysis/wizards/upgrade_generate_record_wizard.py:0 +msgid "Cannot seem to install or upgrade modules %s" +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 "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 "Cerrar" + +#. module: upgrade_analysis +#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_analysis__config_id +msgid "Comparison Config" +msgstr "Configuración de Comparación" + +#. module: upgrade_analysis +#: model:ir.ui.menu,name:upgrade_analysis.menu_upgrade_comparison_config +msgid "Comparison Configurations" +msgstr "Configuraciones de Comparación" + +#. module: upgrade_analysis +#. odoo-python +#: code:addons/upgrade_analysis/models/upgrade_comparison_config.py:0 +msgid "" +"Connection failed.\n" +"\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 "Continuar" + +#. module: upgrade_analysis +#. odoo-python +#: code:addons/upgrade_analysis/models/upgrade_comparison_config.py:0 +msgid "Could not connect the Odoo server at %(server)s:%(port)s" +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 "Crear" + +#. module: upgrade_analysis +#: model_terms:ir.ui.view,arch_db:upgrade_analysis.view_upgrade_record_search +msgid "Create Mode" +msgstr "Modo de Creación" + +#. 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 "Creado por" + +#. 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 "Creado en" + +#. module: upgrade_analysis +#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_comparison_config__database +msgid "Database" +msgstr "Base de Datos" + +#. module: upgrade_analysis +#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_record__definition +msgid "Definition" +msgstr "Definición" + +#. 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 "Mostrar Nombre" + +#. module: upgrade_analysis +#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_record__domain +msgid "Domain" +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 "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 "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 "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 "Asistente de Generación de Registros" + +#. 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 "ID" + +#. module: upgrade_analysis +#: model_terms:ir.ui.view,arch_db:upgrade_analysis.view_upgrade_install_wizard_form +msgid "Install Modules" +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 "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 "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 "Es un Módulo de Odoo" + +#. 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 "Última actualización realizada por" + +#. 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 "Ú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 "Registro" + +#. module: upgrade_analysis +#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_record__mode +msgid "Mode" +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 "Modelo" + +#. module: upgrade_analysis +#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_record__model_original_module +msgid "Model Original Module" +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 "Tipo de Modelo" + +#. module: upgrade_analysis +#: model:ir.model.fields.selection,name:upgrade_analysis.selection__upgrade_record__mode__modify +msgid "Modify" +msgstr "Modificar" + +#. module: upgrade_analysis +#: model_terms:ir.ui.view,arch_db:upgrade_analysis.view_upgrade_record_search +msgid "Modify Mode" +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_record__module +msgid "Module" +msgstr "Módulo" + +#. module: upgrade_analysis +#: model_terms:ir.ui.view,arch_db:upgrade_analysis.module_coverage +msgid "Module coverage" +msgstr "" + +#. module: upgrade_analysis +#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_install_wizard__module_ids +msgid "Modules" +msgstr "Módulos" + +#. module: upgrade_analysis +#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_install_wizard__module_qty +msgid "Modules Quantity" +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 "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 "Nombre" + +#. module: upgrade_analysis +#: model_terms:ir.ui.view,arch_db:upgrade_analysis.view_upgrade_comparison_config_form +msgid "New Analysis" +msgstr "Nuevo Análisis" + +#. module: upgrade_analysis +#. odoo-python +#: code:addons/upgrade_analysis/models/upgrade_record.py:0 +msgid "No manifest found in %(addon_dir)s" +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 "Noupdate" + +#. module: upgrade_analysis +#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_comparison_config__password +msgid "Password" +msgstr "Contraseña" + +#. module: upgrade_analysis +#: model_terms:ir.ui.view,arch_db:upgrade_analysis.view_upgrade_analysis_form +msgid "Perform Analysis" +msgstr "Realizar Análisis" + +#. module: upgrade_analysis +#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_comparison_config__port +msgid "Port" +msgstr "Puerto" + +#. module: upgrade_analysis +#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_record__prefix +msgid "Prefix" +msgstr "Prefijo" + +#. module: upgrade_analysis +#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_attribute__record_id +msgid "Record" +msgstr "Registro" + +#. module: upgrade_analysis +#: model:ir.ui.menu,name:upgrade_analysis.menu_upgrade_records +msgid "Records" +msgstr "Registros" + +#. module: upgrade_analysis +#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_comparison_config__server +msgid "Server" +msgstr "Servidor" + +#. 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 "" +"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_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 "Estado" + +#. module: upgrade_analysis +#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_record__suffix +msgid "Suffix" +msgstr "Sufijo" + +#. module: upgrade_analysis +#: model_terms:ir.ui.view,arch_db:upgrade_analysis.view_upgrade_comparison_config_form +msgid "Test Connection" +msgstr "Prueba de Conexión" + +#. 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 "" +"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 "Los módulos han sido instalados correctamente" + +#. 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 "" +"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 +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 "Tipo" + +#. module: upgrade_analysis +#. odoo-python +#: code:addons/upgrade_analysis/models/upgrade_analysis.py:0 +msgid "Unexpected root Element: %(root)s in file: %(file)s" +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 "Análisis de Actualización" + +#. module: upgrade_analysis +#: model:ir.ui.menu,name:upgrade_analysis.menu_upgrade +msgid "Upgrade Analysis" +msgstr "Análisis de Actualización" + +#. module: upgrade_analysis +#: model:ir.model,name:upgrade_analysis.model_upgrade_attribute +msgid "Upgrade Attribute" +msgstr "Atributo de Actualización" + +#. module: upgrade_analysis +#: model:ir.model,name:upgrade_analysis.model_upgrade_comparison_config +msgid "Upgrade Comparison Configuration" +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 "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 "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 "Ruta de Actualización" + +#. module: upgrade_analysis +#: model:ir.model,name:upgrade_analysis.model_upgrade_record +msgid "Upgrade Record" +msgstr "Registro de Actualización" + +#. module: upgrade_analysis +#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_comparison_config__username +msgid "Username" +msgstr "Nombre de usuario" + +#. module: upgrade_analysis +#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_attribute__value +msgid "Value" +msgstr "Valor" + +#. module: upgrade_analysis +#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_comparison_config__version +msgid "Version" +msgstr "Versión" + +#. module: upgrade_analysis +#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_analysis__write_files +msgid "Write Files" +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 "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 "XML ID" + +#. module: upgrade_analysis +#. odoo-python +#: code:addons/upgrade_analysis/models/upgrade_comparison_config.py:0 +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 "borrador" + +#. module: upgrade_analysis +#: model:ir.actions.act_window,name:upgrade_analysis.action_upgrade_comparison_config_tree +msgid "upgrade Comparison Configs" +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 "actualizar Registros" + +#~ msgid "Last Modified on" +#~ msgstr "Última modificación en" diff --git a/upgrade_analysis/i18n/fr.po b/upgrade_analysis/i18n/fr.po new file mode 100644 index 00000000000..0e731820b64 --- /dev/null +++ b/upgrade_analysis/i18n/fr.po @@ -0,0 +1,549 @@ +# 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" +"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.module_coverage +msgid "->" +msgstr "" + +#. module: upgrade_analysis +#: model_terms:ir.ui.view,arch_db:upgrade_analysis.module_coverage +msgid "" +"============================\n" +"\n" +".. include:: coverage_legend.rst\n" +"\n" +"+---------------------------------------------------+----------------------" +"+-------------------------------------------------+\n" +"| Module | Status + " +"Extra Information |\n" +"+===================================================+======================+=================================================+" +msgstr "" + +#. module: upgrade_analysis +#: model_terms:ir.ui.view,arch_db:upgrade_analysis.view_upgrade_install_wizard_form +msgid "All Modules" +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 "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 "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 "Tous les autres modules" + +#. 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 +#. odoo-python +#: code:addons/upgrade_analysis/wizards/upgrade_generate_record_wizard.py:0 +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 +#. odoo-python +#: code:addons/upgrade_analysis/models/upgrade_comparison_config.py:0 +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 +#. odoo-python +#: code:addons/upgrade_analysis/models/upgrade_comparison_config.py:0 +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__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_record__module +msgid "Module" +msgstr "" + +#. module: upgrade_analysis +#: model_terms:ir.ui.view,arch_db:upgrade_analysis.module_coverage +msgid "Module coverage" +msgstr "" + +#. module: upgrade_analysis +#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_install_wizard__module_ids +msgid "Modules" +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 +#. odoo-python +#: code:addons/upgrade_analysis/models/upgrade_record.py:0 +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_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 +#. odoo-python +#: code:addons/upgrade_analysis/models/upgrade_analysis.py:0 +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 +#. odoo-python +#: code:addons/upgrade_analysis/models/upgrade_comparison_config.py:0 +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 "" diff --git a/upgrade_analysis/i18n/it.po b/upgrade_analysis/i18n/it.po new file mode 100644 index 00000000000..fec4c755fb5 --- /dev/null +++ b/upgrade_analysis/i18n/it.po @@ -0,0 +1,572 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * upgrade_analysis +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 17.0\n" +"Report-Msgid-Bugs-To: \n" +"PO-Revision-Date: 2025-03-18 10:38+0000\n" +"Last-Translator: mymage \n" +"Language-Team: none\n" +"Language: it\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 5.10.2\n" + +#. module: upgrade_analysis +#: model_terms:ir.ui.view,arch_db:upgrade_analysis.module_coverage +msgid "->" +msgstr "->" + +#. module: upgrade_analysis +#: model_terms:ir.ui.view,arch_db:upgrade_analysis.module_coverage +msgid "" +"============================\n" +"\n" +".. include:: coverage_legend.rst\n" +"\n" +"+---------------------------------------------------+----------------------" +"+-------------------------------------------------+\n" +"| Module | Status + " +"Extra Information |\n" +"+===================================================+======================+=================================================+" +msgstr "" +"============================\n" +"\n" +".. include:: coverage_legend.rst\n" +"\n" +"+---------------------------------------------------+----------------------" +"+-------------------------------------------------+\n" +"| Modulo | Stato + " +"Informazioni extra |\n" +"+===================================================+======================+=================================================+" + +#. module: upgrade_analysis +#: model_terms:ir.ui.view,arch_db:upgrade_analysis.view_upgrade_install_wizard_form +msgid "All Modules" +msgstr "Tutti i moduli" + +#. module: upgrade_analysis +#: model_terms:ir.ui.view,arch_db:upgrade_analysis.view_upgrade_install_wizard_form +msgid "All OCA Modules" +msgstr "Tutti i moduli OCA" + +#. module: upgrade_analysis +#: model_terms:ir.ui.view,arch_db:upgrade_analysis.view_upgrade_install_wizard_form +msgid "All Odoo SA Modules" +msgstr "Tutti i moduli Odoo SA" + +#. module: upgrade_analysis +#: model_terms:ir.ui.view,arch_db:upgrade_analysis.view_upgrade_install_wizard_form +msgid "All Other Modules" +msgstr "Tutti gli altri moduli" + +#. 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 "Analisi" + +#. module: upgrade_analysis +#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_analysis__analysis_date +msgid "Analysis Date" +msgstr "Data analisi" + +#. module: upgrade_analysis +#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_comparison_config__analysis_qty +msgid "Analysis Qty" +msgstr "Q.tà analisi" + +#. module: upgrade_analysis +#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_record__attribute_ids +msgid "Attribute" +msgstr "Attributo" + +#. module: upgrade_analysis +#: model_terms:ir.ui.view,arch_db:upgrade_analysis.view_upgrade_record_form +msgid "Attributes" +msgstr "Attributi" + +#. module: upgrade_analysis +#. odoo-python +#: code:addons/upgrade_analysis/wizards/upgrade_generate_record_wizard.py:0 +msgid "Cannot seem to install or upgrade modules %s" +msgstr "Cembra che non si possano installae o aggiornare moduli %s" + +#. module: upgrade_analysis +#: model_terms:ir.ui.view,arch_db:upgrade_analysis.view_upgrade_install_wizard_form +msgid "Clear the list" +msgstr "Pulisci 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 "Chiudi" + +#. module: upgrade_analysis +#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_analysis__config_id +msgid "Comparison Config" +msgstr "Configurazione di confronto" + +#. module: upgrade_analysis +#: model:ir.ui.menu,name:upgrade_analysis.menu_upgrade_comparison_config +msgid "Comparison Configurations" +msgstr "Configurazioni di confronto" + +#. module: upgrade_analysis +#. odoo-python +#: code:addons/upgrade_analysis/models/upgrade_comparison_config.py:0 +msgid "" +"Connection failed.\n" +"\n" +"DETAIL: %s" +msgstr "" +"Connessione fallita.\n" +"\n" +"DETTAGLI: %s" + +#. module: upgrade_analysis +#: model_terms:ir.ui.view,arch_db:upgrade_analysis.view_upgrade_generate_record_wizard_form +msgid "Continue" +msgstr "Continua" + +#. module: upgrade_analysis +#. odoo-python +#: code:addons/upgrade_analysis/models/upgrade_comparison_config.py:0 +msgid "Could not connect the Odoo server at %(server)s:%(port)s" +msgstr "Impossibile collegarsi al server Odoo a %(server)s:%(port)s" + +#. module: upgrade_analysis +#: model:ir.model.fields.selection,name:upgrade_analysis.selection__upgrade_record__mode__create +msgid "Create" +msgstr "Crea" + +#. module: upgrade_analysis +#: model_terms:ir.ui.view,arch_db:upgrade_analysis.view_upgrade_record_search +msgid "Create Mode" +msgstr "Crea modo" + +#. 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 "Creato da" + +#. 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 "Creato il" + +#. module: upgrade_analysis +#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_comparison_config__database +msgid "Database" +msgstr "Database" + +#. module: upgrade_analysis +#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_record__definition +msgid "Definition" +msgstr "Definizione" + +#. 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 "Nome visualizzato" + +#. module: upgrade_analysis +#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_record__domain +msgid "Domain" +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 "Completato" + +#. 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 "Bozza" + +#. 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 "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 "Procedura guidata generazione record" + +#. 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 "ID" + +#. module: upgrade_analysis +#: model_terms:ir.ui.view,arch_db:upgrade_analysis.view_upgrade_install_wizard_form +msgid "Install Modules" +msgstr "Installa moduli" + +#. 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 "Procedura guidata installazione moduli" + +#. module: upgrade_analysis +#: model:ir.model.fields,field_description:upgrade_analysis.field_ir_module_module__is_oca_module +msgid "Is Oca Module" +msgstr "È un modulo OCA" + +#. module: upgrade_analysis +#: model:ir.model.fields,field_description:upgrade_analysis.field_ir_module_module__is_odoo_module +msgid "Is Odoo Module" +msgstr "È un modulo Odoo" + +#. 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 "Ultimo aggiornamento di" + +#. 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 "Ultimo aggiornamento il" + +#. 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 "Log" + +#. module: upgrade_analysis +#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_record__mode +msgid "Mode" +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 "Modello" + +#. module: upgrade_analysis +#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_record__model_original_module +msgid "Model Original Module" +msgstr "Modulo originale modello" + +#. module: upgrade_analysis +#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_record__model_type +msgid "Model Type" +msgstr "Tipo modello" + +#. module: upgrade_analysis +#: model:ir.model.fields.selection,name:upgrade_analysis.selection__upgrade_record__mode__modify +msgid "Modify" +msgstr "Modifica" + +#. module: upgrade_analysis +#: model_terms:ir.ui.view,arch_db:upgrade_analysis.view_upgrade_record_search +msgid "Modify Mode" +msgstr "Modifica modo" + +#. module: upgrade_analysis +#: model:ir.model,name:upgrade_analysis.model_ir_module_module +#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_record__module +msgid "Module" +msgstr "Modulo" + +#. module: upgrade_analysis +#: model_terms:ir.ui.view,arch_db:upgrade_analysis.module_coverage +msgid "Module coverage" +msgstr "Copertura modulo" + +#. module: upgrade_analysis +#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_install_wizard__module_ids +msgid "Modules" +msgstr "Moduli" + +#. module: upgrade_analysis +#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_install_wizard__module_qty +msgid "Modules Quantity" +msgstr "Quantità moduli" + +#. 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 "Moduli inizializzati e record creato" + +#. 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 "Nome" + +#. module: upgrade_analysis +#: model_terms:ir.ui.view,arch_db:upgrade_analysis.view_upgrade_comparison_config_form +msgid "New Analysis" +msgstr "Nuonva analisi" + +#. module: upgrade_analysis +#. odoo-python +#: code:addons/upgrade_analysis/models/upgrade_record.py:0 +msgid "No manifest found in %(addon_dir)s" +msgstr "Manifest non trovato in %(addon_dir)s" + +#. module: upgrade_analysis +#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_record__noupdate +msgid "Noupdate" +msgstr "Non aggiornare" + +#. module: upgrade_analysis +#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_comparison_config__password +msgid "Password" +msgstr "Password" + +#. module: upgrade_analysis +#: model_terms:ir.ui.view,arch_db:upgrade_analysis.view_upgrade_analysis_form +msgid "Perform Analysis" +msgstr "Elabora analisi" + +#. module: upgrade_analysis +#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_comparison_config__port +msgid "Port" +msgstr "Porta" + +#. module: upgrade_analysis +#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_record__prefix +msgid "Prefix" +msgstr "Prefisso" + +#. module: upgrade_analysis +#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_attribute__record_id +msgid "Record" +msgstr "Record" + +#. module: upgrade_analysis +#: model:ir.ui.menu,name:upgrade_analysis.menu_upgrade_records +msgid "Records" +msgstr "Record" + +#. module: upgrade_analysis +#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_comparison_config__server +msgid "Server" +msgstr "Server" + +#. 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 "" +"Imposta a Crea se c'è un campo nuovo in questo modulo. Se questo modulo " +"modifica l'attributo di un campo esistente, impostare a Modifica." + +#. 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 "Ricerca intelligente" + +#. 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 "Stato" + +#. module: upgrade_analysis +#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_record__suffix +msgid "Suffix" +msgstr "Suffisso" + +#. module: upgrade_analysis +#: model_terms:ir.ui.view,arch_db:upgrade_analysis.view_upgrade_comparison_config_form +msgid "Test Connection" +msgstr "Prova connessione" + +#. 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 "" +"Il percorso del file base per falvare il file analisi dei moduli Odoo. Preso " +"dall'opzione riga di comando --upgrade-path o dalla sotto cartella 'scripts' " +"nell'addon 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 "I moduli sono stati installati correttamente" + +#. 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 "" +"Questo installerà i moduli selezionati nel database. Non procedere se si " +"utilizza questo database in produzione." + +#. 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 "" +"Questo reinizializzerà tutti i moduli installati nel database. Non procedere " +"se si utilizza questo database in produzione." + +#. module: upgrade_analysis +#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_record__type +msgid "Type" +msgstr "Tipo" + +#. module: upgrade_analysis +#. odoo-python +#: code:addons/upgrade_analysis/models/upgrade_analysis.py:0 +msgid "Unexpected root Element: %(root)s in file: %(file)s" +msgstr "Elemento radice inatteso: %(root)s nel file: %(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 "Aggiorna analisi" + +#. module: upgrade_analysis +#: model:ir.ui.menu,name:upgrade_analysis.menu_upgrade +msgid "Upgrade Analysis" +msgstr "Aggiorna analisi" + +#. module: upgrade_analysis +#: model:ir.model,name:upgrade_analysis.model_upgrade_attribute +msgid "Upgrade Attribute" +msgstr "Aggiorna attributo" + +#. module: upgrade_analysis +#: model:ir.model,name:upgrade_analysis.model_upgrade_comparison_config +msgid "Upgrade Comparison Configuration" +msgstr "Aggiorna configurazione di confronto" + +#. module: upgrade_analysis +#: model:ir.model,name:upgrade_analysis.model_upgrade_generate_record_wizard +msgid "Upgrade Generate Record Wizard" +msgstr "Procedura guidata aggiornamento generazione record" + +#. module: upgrade_analysis +#: model:ir.model,name:upgrade_analysis.model_upgrade_install_wizard +msgid "Upgrade Install Wizard" +msgstr "Procedura guidata aggiornamento installazione" + +#. module: upgrade_analysis +#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_analysis__upgrade_path +msgid "Upgrade Path" +msgstr "Aggiorna percorso" + +#. module: upgrade_analysis +#: model:ir.model,name:upgrade_analysis.model_upgrade_record +msgid "Upgrade Record" +msgstr "Aggiorna record" + +#. module: upgrade_analysis +#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_comparison_config__username +msgid "Username" +msgstr "Nome utente" + +#. module: upgrade_analysis +#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_attribute__value +msgid "Value" +msgstr "Valore" + +#. module: upgrade_analysis +#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_comparison_config__version +msgid "Version" +msgstr "Versione" + +#. module: upgrade_analysis +#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_analysis__write_files +msgid "Write Files" +msgstr "Scrivi file" + +#. module: upgrade_analysis +#: model:ir.model.fields,help:upgrade_analysis.field_upgrade_analysis__write_files +msgid "Write analysis files to the module directories" +msgstr "Scrivi i file analisi nelle cartelle del modulo" + +#. module: upgrade_analysis +#: model:ir.model.fields.selection,name:upgrade_analysis.selection__upgrade_record__type__xmlid +msgid "XML ID" +msgstr "ID XML" + +#. module: upgrade_analysis +#. odoo-python +#: code:addons/upgrade_analysis/models/upgrade_comparison_config.py:0 +msgid "" +"You are correctly connected to the server %(server)s (version %(version)s) " +"with the user %(user_name)s" +msgstr "" +"Si è correttamente collegati al server %(server)s (versione %(version)s) con " +"l'utente %(user_name)s" + +#. module: upgrade_analysis +#: model:ir.model.fields.selection,name:upgrade_analysis.selection__upgrade_analysis__state__draft +msgid "draft" +msgstr "Bozza" + +#. module: upgrade_analysis +#: model:ir.actions.act_window,name:upgrade_analysis.action_upgrade_comparison_config_tree +msgid "upgrade Comparison Configs" +msgstr "aggiorna configurazione di confronto" + +#. module: upgrade_analysis +#: model:ir.actions.act_window,name:upgrade_analysis.action_upgrade_record_tree +msgid "upgrade Records" +msgstr "aggiorna record" diff --git a/upgrade_analysis/i18n/upgrade_analysis.pot b/upgrade_analysis/i18n/upgrade_analysis.pot new file mode 100644 index 00000000000..cd38c7f2217 --- /dev/null +++ b/upgrade_analysis/i18n/upgrade_analysis.pot @@ -0,0 +1,544 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * upgrade_analysis +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 18.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.module_coverage +msgid "->" +msgstr "" + +#. module: upgrade_analysis +#: model_terms:ir.ui.view,arch_db:upgrade_analysis.module_coverage +msgid "" +"============================\n" +"\n" +".. include:: coverage_legend.rst\n" +"\n" +"+---------------------------------------------------+----------------------+-------------------------------------------------+\n" +"| Module | Status + Extra Information |\n" +"+===================================================+======================+=================================================+" +msgstr "" + +#. 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 +#. odoo-python +#: code:addons/upgrade_analysis/wizards/upgrade_generate_record_wizard.py:0 +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 +#. odoo-python +#: code:addons/upgrade_analysis/models/upgrade_comparison_config.py:0 +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 +#. odoo-python +#: code:addons/upgrade_analysis/models/upgrade_comparison_config.py:0 +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__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_record__module +msgid "Module" +msgstr "" + +#. module: upgrade_analysis +#: model_terms:ir.ui.view,arch_db:upgrade_analysis.module_coverage +msgid "Module coverage" +msgstr "" + +#. module: upgrade_analysis +#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_install_wizard__module_ids +msgid "Modules" +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 +#. odoo-python +#: code:addons/upgrade_analysis/models/upgrade_record.py:0 +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_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 +#. odoo-python +#: code:addons/upgrade_analysis/models/upgrade_analysis.py:0 +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 +#. odoo-python +#: code:addons/upgrade_analysis/models/upgrade_comparison_config.py:0 +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 "" diff --git a/upgrade_analysis/i18n/zh_CN.po b/upgrade_analysis/i18n/zh_CN.po new file mode 100644 index 00000000000..127138048e2 --- /dev/null +++ b/upgrade_analysis/i18n/zh_CN.po @@ -0,0 +1,558 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * upgrade_analysis +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 17.0\n" +"Report-Msgid-Bugs-To: \n" +"PO-Revision-Date: 2024-06-16 13:44+0000\n" +"Last-Translator: xtanuiha \n" +"Language-Team: none\n" +"Language: zh_CN\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: nplurals=1; plural=0;\n" +"X-Generator: Weblate 4.17\n" + +#. module: upgrade_analysis +#: model_terms:ir.ui.view,arch_db:upgrade_analysis.module_coverage +msgid "->" +msgstr "" + +#. module: upgrade_analysis +#: model_terms:ir.ui.view,arch_db:upgrade_analysis.module_coverage +msgid "" +"============================\n" +"\n" +".. include:: coverage_legend.rst\n" +"\n" +"+---------------------------------------------------+----------------------" +"+-------------------------------------------------+\n" +"| Module | Status + " +"Extra Information |\n" +"+===================================================+======================+=================================================+" +msgstr "" + +#. 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 "所有OCA模块" + +#. module: upgrade_analysis +#: model_terms:ir.ui.view,arch_db:upgrade_analysis.view_upgrade_install_wizard_form +msgid "All Odoo SA Modules" +msgstr "所有Odoo SA模块" + +#. 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 +#. odoo-python +#: code:addons/upgrade_analysis/wizards/upgrade_generate_record_wizard.py:0 +msgid "Cannot seem to install or upgrade modules %s" +msgstr "似乎无法安装或更新模块 %s" + +#. 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 +#. odoo-python +#: code:addons/upgrade_analysis/models/upgrade_comparison_config.py:0 +msgid "" +"Connection failed.\n" +"\n" +"DETAIL: %s" +msgstr "" +"连接失败。\n" +"\n" +"详细信息: %s" + +#. module: upgrade_analysis +#: model_terms:ir.ui.view,arch_db:upgrade_analysis.view_upgrade_generate_record_wizard_form +msgid "Continue" +msgstr "继续" + +#. module: upgrade_analysis +#. odoo-python +#: code:addons/upgrade_analysis/models/upgrade_comparison_config.py:0 +msgid "Could not connect the Odoo server at %(server)s:%(port)s" +msgstr "无法连接到位于 %(server)s:%(port)s 的 Odoo 服务器" + +#. 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 "ID" + +#. 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 "是OCA模块" + +#. module: upgrade_analysis +#: model:ir.model.fields,field_description:upgrade_analysis.field_ir_module_module__is_odoo_module +msgid "Is Odoo Module" +msgstr "是Odoo模块" + +#. 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_record__module +msgid "Module" +msgstr "模块" + +#. module: upgrade_analysis +#: model_terms:ir.ui.view,arch_db:upgrade_analysis.module_coverage +msgid "Module coverage" +msgstr "" + +#. module: upgrade_analysis +#: model:ir.model.fields,field_description:upgrade_analysis.field_upgrade_install_wizard__module_ids +msgid "Modules" +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 +#. odoo-python +#: code:addons/upgrade_analysis/models/upgrade_record.py:0 +msgid "No manifest found in %(addon_dir)s" +msgstr "在目录 %(addon_dir)s 中未找到清单文件" + +#. 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 "" +"保存Odoo模块分析文件的基本文件路径。该路径取自Odoo命令行选项`--upgrade-path`" +"或`openupgrade_scripts`附加组件中的`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 "模块已成功安装" + +#. 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 +#. odoo-python +#: code:addons/upgrade_analysis/models/upgrade_analysis.py:0 +msgid "Unexpected root Element: %(root)s in file: %(file)s" +msgstr "文件: %(file)s 中意外的根元素: %(root)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 "升级分析" + +#. 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 "外部ID" + +#. module: upgrade_analysis +#. odoo-python +#: code:addons/upgrade_analysis/models/upgrade_comparison_config.py:0 +msgid "" +"You are correctly connected to the server %(server)s (version %(version)s) " +"with the user %(user_name)s" +msgstr "" +"您已成功通过用户 %(user_name)s连接到服务器 %(server)s(版本 %(version)s)" + +#. 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 "升级记录" diff --git a/upgrade_analysis/models/__init__.py b/upgrade_analysis/models/__init__.py new file mode 100644 index 00000000000..7a9c9233d7e --- /dev/null +++ b/upgrade_analysis/models/__init__.py @@ -0,0 +1,5 @@ +from . import ir_module_module +from . import upgrade_comparison_config +from . import upgrade_analysis +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..38edbbac890 --- /dev/null +++ b/upgrade_analysis/models/ir_module_module.py @@ -0,0 +1,32 @@ +# 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 IrModuleModule(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: + 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) + 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 new file mode 100644 index 00000000000..d4ea3722227 --- /dev/null +++ b/upgrade_analysis/models/upgrade_analysis.py @@ -0,0 +1,608 @@ +# Copyright 2011-2015 Therp BV +# Copyright 2016-2020 Opener B.V. +# Copyright 2019 ForgeFlow +# 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, release +from odoo.exceptions import ValidationError +from odoo.modules import get_module_path +from odoo.tools import config +from odoo.tools.convert import nodeattr2bool + +try: + from odoo.addons.openupgrade_scripts.apriori import merged_modules, renamed_modules +except ImportError: + renamed_modules = {} + merged_modules = {} + +from .. import compare + +_logger = logging.getLogger(__name__) +_IGNORE_MODULES = ["openupgrade_records", "upgrade_analysis"] + + +class UpgradeAnalysis(models.Model): + _name = "upgrade.analysis" + _description = "Upgrade Analyses" + _rec_name = "analysis_date" + + analysis_date = fields.Datetime(readonly=True) + + state = fields.Selection( + [("draft", "draft"), ("done", "Done")], readonly=True, default="draft" + ) + config_id = fields.Many2one( + string="Comparison Config", + comodel_name="upgrade.comparison.config", + readonly=True, + required=True, + ) + + log = fields.Text(readonly=True) + upgrade_path = fields.Char( + compute="_compute_upgrade_path", + readonly=False, + store=True, + help=( + "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." + ), + ) + write_files = fields.Boolean( + help="Write analysis files to the module directories", default=True + ) + + def _compute_upgrade_path(self): + """Return the --upgrade-path configuration option or the `scripts` + directory in `openupgrade_scripts` if available + """ + res = False + upgrade_path = config.get("upgrade_path", []) + if not upgrade_path: + module_path = get_module_path("openupgrade_scripts", display_warning=False) + if module_path: + res = os.path.join(module_path, "scripts") + else: + res = upgrade_path[0] + self.upgrade_path = res + + def _get_remote_model(self, connection, model): + self.ensure_one() + if model == "record": + if float(self.config_id.version) < 14.0: + return connection.env["openupgrade.record"] + else: + return connection.env["upgrade.record"] + return False + + def _write_file( + self, module_name, version, content, filename="upgrade_analysis.txt" + ): + module = self.env["ir.module.module"].search([("name", "=", module_name)])[0] + if module.is_odoo_module: + if not self.upgrade_path: + self._compute_upgrade_path() + if not self.upgrade_path: + return ( + f"ERROR: no upgrade_path set when writing analysis of " + f"{module_name}\n" + ) + full_path = os.path.join(self.upgrade_path, module_name, version) + else: + full_path = os.path.join( + get_module_path(module_name), "migrations", version + ) + if not os.path.exists(full_path): + try: + os.makedirs(full_path) + except OSError: + return f"ERROR: could not create migrations directory {full_path}:\n" + logfile = os.path.join(full_path, filename) + try: + f = open(logfile, "w") + except Exception: + return f"ERROR: could not open file {logfile} for writing:\n" + _logger.debug(f"Writing analysis to {logfile}") + f.write(content) + f.close() + return None + + def analyze(self): + """ + Retrieve both sets of database representations, + perform the comparison and register the resulting + change set + """ + self.ensure_one() + self.write( + { + "analysis_date": fields.Datetime.now(), + } + ) + + connection = self.config_id.get_connection() + RemoteRecord = self._get_remote_model(connection, "record") + LocalRecord = self.env["upgrade.record"] + + # Retrieve field representations and compare + remote_records = RemoteRecord.field_dump() + local_records = LocalRecord.field_dump() + res = compare.compare_sets(remote_records, local_records) + + # Retrieve xml id representations and compare + flds = [ + "module", + "model", + "name", + "noupdate", + "prefix", + "suffix", + "domain", + "definition", + ] + local_xml_records = [ + {field: record[field] for field in flds} + for record in LocalRecord.search([("type", "=", "xmlid")]) + ] + remote_xml_record_ids = RemoteRecord.search([("type", "=", "xmlid")]) + remote_xml_records = [ + {field: record[field] for field in flds} + for record in RemoteRecord.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 LocalRecord.search([("type", "=", "model")]) + ] + remote_model_record_ids = RemoteRecord.search([("type", "=", "model")]) + remote_model_records = [ + {field: record[field] for field in flds} + for record in RemoteRecord.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 + } + ) + if "base" in affected_modules: + try: + pass + 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 + modules = { + module["name"]: module + for module in self.env["ir.module.module"].search( + [("state", "=", "installed")] + ) + } + general_log = "" + + no_changes_modules = [] + + for ignore_module in _IGNORE_MODULES: + if ignore_module in keys: + keys.remove(ignore_module) + + for key in keys: + contents = f"---Models in module '{key}'---\n" + if key in res_model: + contents += "\n".join([str(line) for line in res_model[key]]) + if res_model[key]: + contents += "\n" + contents += f"---Fields in module '{key}'---\n" + if key in res: + contents += "\n".join([str(line) for line in sorted(res[key])]) + if res[key]: + contents += "\n" + contents += f"---XML records in module '{key}'---\n" + 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" + no_changes_modules.append(key) + if key == "general": + general_log += contents + continue + if compare.module_map(key) not in modules: + general_log += f"---Probably obsolete module {key}---\n" + contents + continue + if key not in modules: + # no need to log in full log the merged/renamed modules + continue + if self.write_files: + error = self._write_file(key, modules[key].installed_version, contents) + if error: + general_log += error + general_log += contents + else: + general_log += contents + + # Store the full log + if self.write_files and "base" in modules: + self._write_file( + "base", + modules["base"].installed_version, + general_log, + "upgrade_general_log.txt", + ) + + try: + self.generate_noupdate_changes() + except Exception as e: + _logger.exception(f"Error generating noupdate changes: {e}") + general_log += "ERROR: error when generating noupdate changes: {e}\n" + try: + self.generate_module_coverage_file(no_changes_modules) + except Exception as e: + _logger.exception(f"Error generating module coverage file: {e}") + general_log += f"ERROR: error when generating module coverage file: {e}\n" + + self.write( + { + "state": "done", + "log": general_log, + } + ) + 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 + + 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"] + ) + # 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 = "./{}".format(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") + data_node.xpath("./template"): + 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( + self.env._( + "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": + 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() + all_remote_modules = remote_record_obj.list_modules() + for local_module in local_modules: + 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_files.extend( + remote_record_obj.get_xml_records(remote_module) + ) + remote_modules.append(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_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 + ) + 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 + + def generate_module_coverage_file(self, no_changes_modules): + self.ensure_one() + + module_coverage_file_folder = config.get("module_coverage_file_folder", False) + + if not module_coverage_file_folder: + return + + module_domain = [ + ("state", "=", "installed"), + ( + "name", + "not in", + [ + "upgrade_analysis", + "openupgrade_records", + "openupgrade_scripts", + "openupgrade_framework", + ], + ), + ] + + connection = self.config_id.get_connection() + all_local_modules = ( + self.env["ir.module.module"].search(module_domain).mapped("name") + ) + + all_remote_modules = [ + x["name"] + for x in connection.env["ir.module.module"].search_read( + module_domain, ["name"] + ) + ] + + start_version = connection.version + end_version = release.major_version + module_width = 51 + description_width = 49 + + all_modules = sorted(list(set(all_remote_modules + all_local_modules))) + module_descriptions = {} + for module in all_modules: + status = "" + is_new = False + if module in all_local_modules and module in all_remote_modules: + module_description = f" {module}" + elif module in all_local_modules: + module_description = f" |new| {module}" + is_new = True + else: + module_description = f" |del| {module}" + + # new modules cannot be merged/renamed in same version + if not is_new and module in compare.apriori.merged_modules: + status = f"Merged into {compare.apriori.merged_modules[module]}. " + elif not is_new and module in compare.apriori.renamed_modules: + status = f"Renamed to {compare.apriori.renamed_modules[module]}. " + elif module in compare.apriori.renamed_modules.values(): + status = "Renamed from {}. ".format( + [ + x + for x in compare.apriori.renamed_modules + if compare.apriori.renamed_modules[x] == module + ][0] + ) + elif module in no_changes_modules: + status += "No DB layout changes. " + module_descriptions[ + module_description.ljust(module_width, " ")[0 : module_width - 1] + " " + ] = status.ljust(description_width, " ")[0 : description_width - 1] + " " + + rendered_text = self.env["ir.qweb"]._render( + "upgrade_analysis.module_coverage", + values=dict( + 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() + return True diff --git a/upgrade_analysis/models/upgrade_attribute.py b/upgrade_analysis/models/upgrade_attribute.py new file mode 100644 index 00000000000..15c93446657 --- /dev/null +++ b/upgrade_analysis/models/upgrade_attribute.py @@ -0,0 +1,21 @@ +# 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", + index=True, + ondelete="CASCADE", + readonly=True, + ) diff --git a/upgrade_analysis/models/upgrade_comparison_config.py b/upgrade_analysis/models/upgrade_comparison_config.py new file mode 100644 index 00000000000..7c84c38dc5c --- /dev/null +++ b/upgrade_analysis/models/upgrade_comparison_config.py @@ -0,0 +1,102 @@ +# Copyright 2011-2015 Therp BV +# 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 +from odoo.exceptions import UserError + + +class UpgradeComparisonConfig(models.Model): + _name = "upgrade.comparison.config" + _description = "Upgrade Comparison Configuration" + + name = fields.Char() + + server = fields.Char(required=True, default="localhost") + + port = fields.Integer(required=True, default=8069) + + database = fields.Char(required=True) + + username = fields.Char(required=True, default="admin") + + password = fields.Char(required=True, default="admin") + + version = fields.Char() + + analysis_ids = fields.One2many( + string="Analyses", comodel_name="upgrade.analysis", inverse_name="config_id" + ) + analysis_qty = fields.Integer(compute="_compute_analysis_qty") + + @api.depends("analysis_ids") + def _compute_analysis_qty(self): + for config in self: + config.analysis_qty = len(config.analysis_ids) + + def get_connection(self): + self.ensure_one() + try: + remote = odoorpc.ODOO(self.server, port=self.port) + except URLError as exc: + raise UserError( + self.env._( + "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 + + 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(self.env._("Connection failed.\n\nDETAIL: %s", e)) from e + return { + "type": "ir.actions.client", + "tag": "display_notification", + "params": { + "type": "info", + "message": self.env._( + "You are correctly connected to the server %(server)s" + " (version %(version)s) with the user %(user_name)s", + server=self.server, + version=self.version, + user_name=user_info["name"], + ), + }, + } + + def new_analysis(self): + self.ensure_one() + analysis = self.env["upgrade.analysis"].create({"config_id": self.id}) + return { + "name": analysis._description, + "view_mode": "form", + "res_model": analysis._name, + "type": "ir.actions.act_window", + # "target": "new", + "res_id": analysis.id, + # "nodestroy": True, + } + + def action_show_analysis(self): + self.ensure_one() + return { + "type": "ir.actions.act_window", + "name": "Analyses", + "res_model": "upgrade.analysis", + "view_mode": "list,form", + "domain": [("id", "in", self.analysis_ids.ids)], + } diff --git a/upgrade_analysis/models/upgrade_record.py b/upgrade_analysis/models/upgrade_record.py new file mode 100644 index 00000000000..0c9c0c8d8ea --- /dev/null +++ b/upgrade_analysis/models/upgrade_record.py @@ -0,0 +1,186 @@ +# Copyright 2011-2015 Therp BV +# Copyright 2016-2020 Opener B.V. +# Copyright 2019 ForgeFlow +# Copyright 2020 GRAP +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +import ast +import logging +import os + +from odoo import api, fields, models +from odoo.exceptions import ValidationError +from odoo.modules.module import MANIFEST_NAMES, get_module_path + +_logger = logging.getLogger(__name__) + + +class UpgradeRecord(models.Model): + _name = "upgrade.record" + _description = "Upgrade 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( + [("field", "Field"), ("xmlid", "XML ID"), ("model", "Model")], + 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) + + definition = 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", + "translate", + "relation", + "required", + "stored", + "selection_keys", + "hasdefault", + "table", + "_inherits", + "_order", + ] + + 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}) + 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 + + @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()] + + @api.model + def _read_manifest(self, 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)) as f: + manifest_string = f.read() + return ast.literal_eval(manifest_string) + raise ValidationError( + # pylint: disable=prefer-env-translation + self.env._("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""" + 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("/") + try: + with open(os.path.join(addon_dir, *parts)) 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 diff --git a/upgrade_analysis/odoo_patch/__init__.py b/upgrade_analysis/odoo_patch/__init__.py new file mode 100644 index 00000000000..4a183795658 --- /dev/null +++ b/upgrade_analysis/odoo_patch/__init__.py @@ -0,0 +1,3 @@ +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 new file mode 100644 index 00000000000..5710e749763 --- /dev/null +++ b/upgrade_analysis/odoo_patch/addons/__init__.py @@ -0,0 +1,2 @@ +from . import mrp +from . import stock diff --git a/upgrade_analysis/odoo_patch/addons/mrp/__init__.py b/upgrade_analysis/odoo_patch/addons/mrp/__init__.py new file mode 100644 index 00000000000..e795cbc3313 --- /dev/null +++ b/upgrade_analysis/odoo_patch/addons/mrp/__init__.py @@ -0,0 +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"] + + def _pre_init_mrp(cr): + """Don't try to create an existing column on reinstall""" diff --git a/upgrade_analysis/odoo_patch/addons/stock/__init__.py b/upgrade_analysis/odoo_patch/addons/stock/__init__.py new file mode 100644 index 00000000000..3ff1cb0a26e --- /dev/null +++ b/upgrade_analysis/odoo_patch/addons/stock/__init__.py @@ -0,0 +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"] + + 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 new file mode 100644 index 00000000000..14cd7916eb9 --- /dev/null +++ b/upgrade_analysis/odoo_patch/odoo/__init__.py @@ -0,0 +1,3 @@ +from . import addons +from . import orm +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..48dbeedfee5 --- /dev/null +++ b/upgrade_analysis/odoo_patch/odoo/addons/base/models/ir_model.py @@ -0,0 +1,39 @@ +# ruff: noqa +from odoo import models + +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 _table_objects of the given model.""" + data_list = [] + for conname, cons in model._table_objects.items(): + module = cons._module + if not conname or not module: + _logger.warning("Missing module or constraint name for %s", cons) + continue + definition = cons.get_definition(model.pool) + message = cons.message + if not isinstance(message, str) or not message: + message = None + typ = "i" if isinstance(cons, models.Index) else "u" + record = self._reflect_constraint( + model, conname, typ, definition, module, message + ) + xml_id = "%s.constraint_%s" % (module, conname) + if record: + data_list.append(dict(xml_id=xml_id, record=record)) + else: + self.env["ir.model.data"]._load_xmlid(xml_id) + # Begin OpenUpgrade addition + upgrade_log.log_xml_id(self.env.cr, module, xml_id) + # End OpenUpgrade addition + if data_list: + self.env["ir.model.data"]._update_xmlids(data_list) diff --git a/upgrade_analysis/odoo_patch/odoo/orm/__init__.py b/upgrade_analysis/odoo_patch/odoo/orm/__init__.py new file mode 100644 index 00000000000..7d9d7dd18dd --- /dev/null +++ b/upgrade_analysis/odoo_patch/odoo/orm/__init__.py @@ -0,0 +1,2 @@ +from . import models +from . import registry diff --git a/upgrade_analysis/odoo_patch/odoo/orm/models.py b/upgrade_analysis/odoo_patch/odoo/orm/models.py new file mode 100644 index 00000000000..7230e0af40f --- /dev/null +++ b/upgrade_analysis/odoo_patch/odoo/orm/models.py @@ -0,0 +1,24 @@ +# noqa +from odoo import api, models + +from .... import upgrade_log +from ...odoo_patch import OdooPatch + + +class BaseModelPatch(OdooPatch): + target = models.BaseModel + method_names = ["_convert_records"] + + @api.model + def _convert_records(self, records, *, log=lambda a: None, savepoint): + """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, savepoint=savepoint + ): + _id, xid, _record, _info = res + if xid: + xid = xid if "." in xid else f"{current_module}.{xid}" + upgrade_log.log_xml_id(self.env.cr, current_module, xid) + + yield res diff --git a/upgrade_analysis/odoo_patch/odoo/orm/registry.py b/upgrade_analysis/odoo_patch/odoo/orm/registry.py new file mode 100644 index 00000000000..6bb96a300ad --- /dev/null +++ b/upgrade_analysis/odoo_patch/odoo/orm/registry.py @@ -0,0 +1,35 @@ +# noqa +import logging +from threading import current_thread + +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"] + + def init_models(self, cr, model_names, context, install=True): + if "module" in context: + 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/tools/__init__.py b/upgrade_analysis/odoo_patch/odoo/tools/__init__.py new file mode 100644 index 00000000000..99a9527ec5a --- /dev/null +++ b/upgrade_analysis/odoo_patch/odoo/tools/__init__.py @@ -0,0 +1 @@ +from . import convert diff --git a/upgrade_analysis/odoo_patch/odoo/tools/convert.py b/upgrade_analysis/odoo_patch/odoo/tools/convert.py new file mode 100644 index 00000000000..93b4aa2c495 --- /dev/null +++ b/upgrade_analysis/odoo_patch/odoo/tools/convert.py @@ -0,0 +1,15 @@ +# noqa +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"] + + 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) + return res diff --git a/upgrade_analysis/odoo_patch/odoo_patch.py b/upgrade_analysis/odoo_patch/odoo_patch.py new file mode 100644 index 00000000000..82d43b96666 --- /dev/null +++ b/upgrade_analysis/odoo_patch/odoo_patch.py @@ -0,0 +1,61 @@ +import logging + +_logger = logging.getLogger(__name__) + + +class OdooPatch: + """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) + 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.warning( + "_original_method not found on method %s of class %s", + method_name, + cls.target, + ) diff --git a/upgrade_analysis/pyproject.toml b/upgrade_analysis/pyproject.toml new file mode 100644 index 00000000000..4231d0cccb3 --- /dev/null +++ b/upgrade_analysis/pyproject.toml @@ -0,0 +1,3 @@ +[build-system] +requires = ["whool"] +build-backend = "whool.buildapi" diff --git a/upgrade_analysis/readme/CONTRIBUTORS.md b/upgrade_analysis/readme/CONTRIBUTORS.md new file mode 100644 index 00000000000..706a73dc8b5 --- /dev/null +++ b/upgrade_analysis/readme/CONTRIBUTORS.md @@ -0,0 +1,10 @@ +- Stefan Rijnhart \<\> +- Holger Brunn \<\> +- Ferdinand Gassauer \<\> +- Florent Xicluna \<\> +- Miquel Raïch \<\> +- Sylvain LE GAL \<\> +- [Tecnativa](https://www.tecnativa.com): + + > - Pedro M. Baeza + > - Sergio Teruel diff --git a/upgrade_analysis/readme/DESCRIPTION.md b/upgrade_analysis/readme/DESCRIPTION.md new file mode 100644 index 00000000000..ace8cc31b4f --- /dev/null +++ b/upgrade_analysis/readme/DESCRIPTION.md @@ -0,0 +1,12 @@ +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: + + +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. diff --git a/upgrade_analysis/readme/ROADMAP.md b/upgrade_analysis/readme/ROADMAP.md new file mode 100644 index 00000000000..8b6ba6ece2c --- /dev/null +++ b/upgrade_analysis/readme/ROADMAP.md @@ -0,0 +1,5 @@ +- 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: + ) diff --git a/upgrade_analysis/readme/USAGE.md b/upgrade_analysis/readme/USAGE.md new file mode 100644 index 00000000000..34452556f22 --- /dev/null +++ b/upgrade_analysis/readme/USAGE.md @@ -0,0 +1 @@ +[Usage instructions](https://oca.github.io/OpenUpgrade/analyse.html) diff --git a/upgrade_analysis/security/ir.model.access.csv b/upgrade_analysis/security/ir.model.access.csv new file mode 100644 index 00000000000..1bae29a1ead --- /dev/null +++ b/upgrade_analysis/security/ir.model.access.csv @@ -0,0 +1,7 @@ +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,base.group_system,1,0,0,0 +access_upgrade_attribute,upgrade.attribute all,model_upgrade_attribute,base.group_system,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,access_upgrade_analysis,model_upgrade_analysis,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/static/description/icon.png b/upgrade_analysis/static/description/icon.png new file mode 100644 index 00000000000..3a0328b516c Binary files /dev/null and b/upgrade_analysis/static/description/icon.png differ diff --git a/upgrade_analysis/static/description/index.html b/upgrade_analysis/static/description/index.html new file mode 100644 index 00000000000..0321b1362c1 --- /dev/null +++ b/upgrade_analysis/static/description/index.html @@ -0,0 +1,478 @@ + + + + + +README.rst + + + +
+ + + +Odoo Community Association + +
+

Upgrade Analysis

+ +

Beta License: AGPL-3 OCA/server-tools Translate me on Weblate Try me on Runboat

+

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

+ + +
+

Known issues / Roadmap

+ +
+
+

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 to smash 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

+ +
+
+

Maintainers

+

This module is maintained by the OCA.

+ +Odoo Community Association + +

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:

+

StefanRijnhart 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/templates/module_coverage_template.xml b/upgrade_analysis/templates/module_coverage_template.xml new file mode 100644 index 00000000000..9c4d412ba2f --- /dev/null +++ b/upgrade_analysis/templates/module_coverage_template.xml @@ -0,0 +1,17 @@ + + + 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..0aadda0db48 --- /dev/null +++ b/upgrade_analysis/tests/test_module.py @@ -0,0 +1,119 @@ +from copy import deepcopy + +from odoo.tests import common, tagged + +from .. import compare, upgrade_log +from ..odoo_patch.odoo_patch import OdooPatch + + +@tagged("post_install", "-at_install") +class TestUpgradeAnalysis(common.TransactionCase): + def setUp(self): + super().setUp() + self.IrModuleModule = self.env["ir.module.module"] + self.website_module = self.IrModuleModule.search([("name", "=", "website")]) + 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.website_module.id in wizard.module_ids.ids, + "Select Odoo module should select 'product' module", + ) + # New patch avoids to reinstall already installed modules, so this will fail + # 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.assertFalse( + self.website_module.id 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 + + def test_odoo_patch(self): + """ + Test the patched versions of Odoo's base functions + """ + self.assertFalse( + self.env["upgrade.record"].search( + [ + ("name", "=", "base.constraint_ir_module_module_name_uniq"), + ("type", "=", "xmlid"), + ] + ) + ) + with OdooPatch(): + self.env["ir.model.constraint"]._reflect_model(self.IrModuleModule) + self.assertTrue( + self.env["upgrade.record"].search( + [ + ("name", "=", "base.constraint_ir_module_module_name_uniq"), + ("type", "=", "xmlid"), + ] + ) + ) + + def test_field_comparison(self): + """ + Test we compare fields correctly + """ + registry = {} + upgrade_log.log_model(self.env["upgrade.analysis"], registry) + upgrade_log.compare_registries(self.env.cr, "upgrade_analysis", {}, registry) + old_fields = self.env["upgrade.record"].field_dump() + new_fields = deepcopy(old_fields) + + def assertInFieldComparison(comparison, field, needle): + self.assertIn( + needle, + "".join( + line + for line in comparison["upgrade_analysis"] + if f"/ {field} (" in line + ), + ) + + state_field = [ + field + for field in new_fields + if field["field"] == "state" and field["model"] == "upgrade.analysis" + ][0] + + state_field["selection_keys"] = "['done', 'new']" + comparison = compare.compare_sets(old_fields, new_fields) + assertInFieldComparison(comparison, "state", "added: [new]") + assertInFieldComparison(comparison, "state", "removed: [draft]") + + state_field["selection_keys"] = "['done', 'draft', 'new']" + comparison = compare.compare_sets(old_fields, new_fields) + assertInFieldComparison(comparison, "state", "added: [new]") + assertInFieldComparison(comparison, "state", "most likely nothing to do") + with self.assertRaises(AssertionError): + assertInFieldComparison(comparison, "state", "removed") + + state_field["selection_keys"] = "function" + comparison = compare.compare_sets(old_fields, new_fields) + with self.assertRaises(AssertionError): + assertInFieldComparison(comparison, "state", "added: [new]") + with self.assertRaises(AssertionError): + assertInFieldComparison(comparison, "state", "removed") diff --git a/upgrade_analysis/upgrade_log.py b/upgrade_analysis/upgrade_log.py new file mode 100644 index 00000000000..cfaa343829d --- /dev/null +++ b/upgrade_analysis/upgrade_log.py @@ -0,0 +1,242 @@ +# 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 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 " + "(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( + "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 " + "(create_date, name, value, record_id) " + "VALUES (NOW() AT TIME ZONE 'UTC', %s, %s, %s)", + (key, value, record_id), + ) + old_field[key] = value + + +def hasdefault(field): + """Return a representation of the field's default method. + + The default method is only meaningful if the field is a regular read/write + field with a `default` method or a `compute` method. + + Note that Odoo fields accept a literal value as a `default` attribute + this value is wrapped in a lambda expression in odoo/fields.py: + https://github.com/odoo/odoo/blob/7eeba9d/odoo/fields.py#L484-L487 + """ + if ( + not field.readonly # It's not a proper computed field + and not field.inverse # It's not a field that delegates their data + and not isrelated(field) # It's not an (unstored) related field. + ): + if field.default: + return "default" + if field.compute: + return "compute" + return "" + + +def isfunction(field): + if ( + field.compute + and (field.readonly or field.inverse) + and not field.related + and not field.company_dependent + ): + return "function" + return "" + + +def isproperty(field): + if field.company_dependent: + return "property" + return "" + + +def isrelated(field): + if field.related: + return "related" + return "" + + +def istranslate(field): + if field.translate: + return "translate" + return "" + + +def _get_relation(field): + if field.type in ("many2many", "many2one", "one2many"): + return field.comodel_name + elif field.type == "many2one_reference": + return field.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)} + model_registry["_order"] = {"_order": model._order} + for fieldname, field in model._fields.items(): + properties = { + "type": typemap.get(field.type, field.type), + "isfunction": isfunction(field), + "isproperty": isproperty(field), + "isrelated": isrelated(field), + "translate": istranslate(field), + "relation": _get_relation(field), + "table": field.relation if field.type == "many2many" else "", + "required": field.required and "required" or "", + "stored": field.store and "stored" or "", + "selection_keys": "", + "hasdefault": hasdefault(field), + } + if field.type == "selection": + if isinstance(field.selection, tuple | list): + properties["selection_keys"] = str( + sorted(x[0] for x in field.selection) + ) + else: + properties["selection_keys"] = "function" + elif field.type == "binary": + properties["attachment"] = str(getattr(field, "attachment", False)) + for key, value in properties.items(): + if value: + model_registry.setdefault(fieldname, {})[key] = value + + +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() + - 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 + won't be called. This can be brought about by installing the + module or updating the 'state' field of the module to 'to install' + or call the server with '--init ' and the database argument. + + - Do you get the right results immediately when installing the module? + No, sorry. This method retrieves the model from the ir_model_table, but + when the xml id is encountered for the first time, this method is called + before the item is present in this table. Therefore, you will not + get any meaningful results until the *second* time that you 'init' + the module. + + - The good news is that the upgrade_analysis module that comes + with this distribution allows you to deal with all of this with + one click on the menu item Settings -> Customizations -> + Database Structure -> OpenUpgrade -> Generate Records + + - You cannot reinitialize the modules in your production database + and expect to keep working on it happily ever after. Do not perform + this routine on your production database. + + :param module: The module that contains the xml_id + :param xml_id: the xml_id, with or without 'module.' prefix + """ + if not table_exists(cr, "upgrade_record"): + return + if "." not in xml_id: + xml_id = f"{module}.{xml_id}" + cr.execute( + "SELECT model FROM ir_model_data WHERE module = %s AND name = %s", + xml_id.split("."), + ) + record = cr.fetchone() + if not record: + _logger.warning("Cannot find xml_id %s", xml_id) + return + else: + cr.execute( + "SELECT id FROM upgrade_record " + "WHERE module=%s AND model=%s AND name=%s AND type=%s", + (module, record[0], xml_id, "xmlid"), + ) + if not cr.fetchone(): + cr.execute( + "INSERT INTO upgrade_record " + "(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/views/menu.xml b/upgrade_analysis/views/menu.xml new file mode 100644 index 00000000000..8eb9d861051 --- /dev/null +++ b/upgrade_analysis/views/menu.xml @@ -0,0 +1,9 @@ + + + + diff --git a/upgrade_analysis/views/view_upgrade_analysis.xml b/upgrade_analysis/views/view_upgrade_analysis.xml new file mode 100644 index 00000000000..3b288c653c8 --- /dev/null +++ b/upgrade_analysis/views/view_upgrade_analysis.xml @@ -0,0 +1,60 @@ + + + + upgrade.analysis + + + + + + + + + + + upgrade.analysis + +
+
+ +
+ + + + + + + + + + + +
+
+
+ + + Upgrade Analyses + upgrade.analysis + + + +
diff --git a/upgrade_analysis/views/view_upgrade_comparison_config.xml b/upgrade_analysis/views/view_upgrade_comparison_config.xml new file mode 100644 index 00000000000..cd6b2d2de87 --- /dev/null +++ b/upgrade_analysis/views/view_upgrade_comparison_config.xml @@ -0,0 +1,76 @@ + + + + upgrade.comparison.config + + + + + + + + + + + + upgrade.comparison.config + +
+
+ +
+ +
+ + + + + + + + + +
+