Initial commit: Odoo 18.0-20251222 extra-addons
Some checks failed
pre-commit / pre-commit (push) Has been cancelled
tests / Detect unreleased dependencies (push) Has been cancelled
tests / test with OCB (push) Has been cancelled
tests / test with Odoo (push) Has been cancelled

This commit is contained in:
tocmo0nlord
2026-03-13 20:43:25 +00:00
parent 36e847a7df
commit adbe430761
9472 changed files with 1265727 additions and 0 deletions

133
upgrade_analysis/README.rst Executable file
View File

@@ -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/18.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-18-0/server-tools-18-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=18.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 <https://oca.github.io/OpenUpgrade/analyse.html>`__
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 <https://github.com/OCA/server-tools/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 <https://github.com/OCA/server-tools/issues/new?body=module:%20upgrade_analysis%0Aversion:%2018.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**>`_.
Do not contact contributors directly about support or help with technical issues.
Credits
=======
Authors
-------
* Therp BV
* Opener B.V.
* GRAP
Contributors
------------
- Stefan Rijnhart <stefan@opener.amsterdam>
- Holger Brunn <hbrunn@therp.nl>
- Ferdinand Gassauer <gass@cc-l-12.chircar.at>
- Florent Xicluna <florent.xicluna@gmail.com>
- Miquel Raïch <miquel.raich@forgeflow.com>
- Sylvain LE GAL <https://twitter.com/legalsylvain>
- `Tecnativa <https://www.tecnativa.com>`__:
- 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 <https://odoo-community.org/page/maintainer-role>`__:
|maintainer-StefanRijnhart| |maintainer-legalsylvain|
This module is part of the `OCA/server-tools <https://github.com/OCA/server-tools/tree/18.0/upgrade_analysis>`_ project on GitHub.
You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.

6
upgrade_analysis/__init__.py Executable file
View File

@@ -0,0 +1,6 @@
from . import odoo_patch
from . import models
from . import wizards
from . import blacklist
from . import compare
from . import upgrade_log

View File

@@ -0,0 +1,29 @@
# Copyright 2011-2015 Therp BV <https://therp.nl>
# Copyright 2016 Opener B.V. <https://opener.am>
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
{
"name": "Upgrade Analysis",
"summary": "Performs a difference analysis between modules"
" installed on two different Odoo instances",
"version": "18.0.1.4.3",
"category": "Migration",
"author": "Therp BV, Opener B.V., GRAP, Odoo Community Association (OCA)",
"maintainers": ["StefanRijnhart", "legalsylvain"],
"website": "https://github.com/OCA/server-tools",
"data": [
"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",
}

15
upgrade_analysis/blacklist.py Executable file
View File

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

636
upgrade_analysis/compare.py Executable file
View File

@@ -0,0 +1,636 @@
# Copyright 2011-2015 Therp BV <https://therp.nl>
# Copyright 2015-2016 Opener B.V. <https://opener.am>
# 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",
"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",
"translate",
"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 [
"# %d fields matched," % (origlen - len(old_records)),
"# Direct match: %d" % matched_direct,
"# Found in other module: %d" % matched_other_module,
"# Found with different type: %d" % matched_other_type,
"# Found in other module with different type: %d"
% matched_other_module_other_type,
"# In obsolete models: %d" % in_obsolete_models,
"# Not matched: %d" % len(old_records),
"# New columns: %d" % len(new_records),
]:
reprs["general"].append(line)
return reprs
def compare_xml_sets(old_records, new_records):
reprs = collections.defaultdict(list)
def match_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 column["definition"] != found["definition"]
and "is now '{}' ('{}')".format(
found["definition"], column["definition"]
)
)
column["definition"] = False
column["noupdate_switched"] = False
found["noupdate_switched"] = column["noupdate"] != found["noupdate"]
if match_type != "direct":
matched_records.append(column)
matched_records.append(found)
elif (
match_type == "direct" and (found["domain"] or found["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

567
upgrade_analysis/i18n/es_AR.po Executable file
View File

@@ -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 <ibuioli@gmail.com>\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 "-&gt;"
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"

549
upgrade_analysis/i18n/fr.po Executable file
View File

@@ -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 <yld@alliasys.fr>\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 "-&gt;"
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 ""

572
upgrade_analysis/i18n/it.po Executable file
View File

@@ -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 <stefano.consolaro@mymage.it>\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 "-&gt;"
msgstr "-&gt;"
#. 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"

View File

@@ -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 "-&gt;"
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 ""

558
upgrade_analysis/i18n/zh_CN.po Executable file
View File

@@ -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 <feihu.zhang@live.com>\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 "-&gt;"
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 "升级记录"

View File

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

View File

@@ -0,0 +1,32 @@
# Copyright 2011-2015 Therp BV <https://therp.nl>
# Copyright 2016 Opener B.V. <https://opener.am>
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
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"

View File

@@ -0,0 +1,604 @@
# Copyright 2011-2015 Therp BV <https://therp.nl>
# Copyright 2016-2020 Opener B.V. <https://opener.am>
# Copyright 2019 ForgeFlow <https://forgeflow.com>
# Copyright 2020 GRAP <https://grap.coop>
# 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
from odoo.tools.translate import _
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"
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 = config.get("upgrade_path", False)
if not res:
module_path = get_module_path("openupgrade_scripts", display_warning=False)
if module_path:
res = os.path.join(module_path, "scripts")
self.upgrade_path = res
def _get_remote_model(self, connection, model):
self.ensure_one()
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 += (
"ERROR: module not in list of installed modules:\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
# {<odoo>, <openerp> or —rarely— <data>};
root_node_noupdate = nodeattr2bool(root_node, "noupdate", False)
if root_node.tag not in ("openerp", "odoo", "data"):
raise ValidationError(
_("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

View File

@@ -0,0 +1,21 @@
# Copyright 2011-2015 Therp BV <https://therp.nl>
# Copyright 2016 Opener B.V. <https://opener.am>
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
from odoo import fields, models
class UpgradeAttribute(models.Model):
_name = "upgrade.attribute"
_description = "Upgrade Attribute"
name = fields.Char(readonly=True)
value = fields.Char(readonly=True)
record_id = fields.Many2one(
comodel_name="upgrade.record",
index=True,
ondelete="CASCADE",
readonly=True,
)

View File

@@ -0,0 +1,102 @@
# Copyright 2011-2015 Therp BV <https://therp.nl>
# Copyright 2016 Opener B.V. <https://opener.am>
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
from urllib.error import URLError
import odoorpc
from odoo import api, fields, models
from odoo.exceptions import UserError
from odoo.tools.translate import _
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(
_("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(_("Connection failed.\n\nDETAIL: %s") % e) from e
return {
"type": "ir.actions.client",
"tag": "display_notification",
"params": {
"type": "info",
"message": _(
"You are correctly connected to the server %(server)s"
" (version %(version)s) with the user %(user_name)s"
)
% dict(
server=self.server,
version=self.version,
user_name=user_info["name"],
),
},
}
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)],
}

View File

@@ -0,0 +1,186 @@
# Copyright 2011-2015 Therp BV <https://therp.nl>
# Copyright 2016-2020 Opener B.V. <https://opener.am>
# Copyright 2019 ForgeFlow <https://forgeflow.com>
# Copyright 2020 GRAP <https://grap.coop>
# 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
from odoo.tools.translate import _
_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()]
@staticmethod
def _read_manifest(addon_dir):
for manifest_name in MANIFEST_NAMES:
if os.access(os.path.join(addon_dir, manifest_name), os.R_OK):
with open(os.path.join(addon_dir, manifest_name)) as f:
manifest_string = f.read()
return ast.literal_eval(manifest_string)
raise ValidationError(
_("No manifest found in %(addon_dir)s") % {"addon_dir": addon_dir}
)
@api.model
def get_xml_records(self, module):
"""Return all XML records from the given module"""
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

View File

@@ -0,0 +1,3 @@
from . import addons
from . import odoo
from . import odoo_patch

View File

@@ -0,0 +1,2 @@
from . import mrp
from . import stock

View File

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

View File

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

View File

@@ -0,0 +1,4 @@
from . import addons
from . import models
from . import modules
from . import tools

View File

@@ -0,0 +1 @@
from . import base

View File

@@ -0,0 +1 @@
from . import models

View File

@@ -0,0 +1 @@
from . import ir_model

View File

@@ -0,0 +1,43 @@
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 _sql_constraints of the given model."""
def cons_text(txt):
return txt.lower().replace(", ", ",").replace(" (", "(")
# map each constraint on the name of the module where it is defined
constraint_module = {
constraint[0]: cls._module
for cls in reversed(self.env.registry[model._name].mro())
if models.is_definition_class(cls)
for constraint in getattr(cls, "_local_sql_constraints", ())
}
data_list = []
for key, definition, message in model._sql_constraints:
conname = f"{model._table}_{key}"
module = constraint_module.get(key)
record = self._reflect_constraint(
model, conname, "u", cons_text(definition), module, message
)
xml_id = f"{module}.constraint_{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)

View File

@@ -0,0 +1,23 @@
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):
"""Log data ids that are imported with `load`"""
current_module = self.env.context["module"]
for res in BaseModelPatch._convert_records._original_method(
self, records, log=log
):
_id, xid, _record, _info = res
if xid:
xid = xid if "." in xid else f"{current_module}.{xid}"
upgrade_log.log_xml_id(self.env.cr, current_module, xid)
yield res

View File

@@ -0,0 +1 @@
from . import registry

View File

@@ -0,0 +1,34 @@
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
)

View File

@@ -0,0 +1 @@
from . import convert

View File

@@ -0,0 +1,14 @@
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

View File

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

View File

@@ -0,0 +1,3 @@
[build-system]
requires = ["whool"]
build-backend = "whool.buildapi"

View File

@@ -0,0 +1,10 @@
- Stefan Rijnhart \<<stefan@opener.amsterdam>\>
- Holger Brunn \<<hbrunn@therp.nl>\>
- Ferdinand Gassauer \<<gass@cc-l-12.chircar.at>\>
- Florent Xicluna \<<florent.xicluna@gmail.com>\>
- Miquel Raïch \<<miquel.raich@forgeflow.com>\>
- Sylvain LE GAL \<<https://twitter.com/legalsylvain>\>
- [Tecnativa](https://www.tecnativa.com):
> - Pedro M. Baeza
> - Sergio Teruel

View File

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

View File

@@ -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:
<https://github.com/OCA/OpenUpgrade/pull/3209#issuecomment-1157449981>)

View File

@@ -0,0 +1 @@
[Usage instructions](https://oca.github.io/OpenUpgrade/analyse.html)

View File

@@ -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
1 id name model_id:id group_id:id perm_read perm_write perm_create perm_unlink
2 access_upgrade_record upgrade.record all model_upgrade_record base.group_system 1 0 0 0
3 access_upgrade_attribute upgrade.attribute all model_upgrade_attribute base.group_system 1 0 0 0
4 access_upgrade_comparison_config upgrade.comparison.config model_upgrade_comparison_config base.group_system 1 1 1 1
5 access_upgrade_analysis access_upgrade_analysis model_upgrade_analysis base.group_system 1 1 1 1
6 access_upgrade_generate_record_wizard access_upgrade_generate_record_wizard model_upgrade_generate_record_wizard base.group_system 1 1 1 1
7 access_upgrade_install_wizard access_upgrade_install_wizard model_upgrade_install_wizard base.group_system 1 1 1 1

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.2 KiB

View File

@@ -0,0 +1,478 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="generator" content="Docutils: https://docutils.sourceforge.io/" />
<title>README.rst</title>
<style type="text/css">
/*
:Author: David Goodger (goodger@python.org)
:Id: $Id: html4css1.css 9511 2024-01-13 09:50:07Z milde $
:Copyright: This stylesheet has been placed in the public domain.
Default cascading style sheet for the HTML output of Docutils.
Despite the name, some widely supported CSS2 features are used.
See https://docutils.sourceforge.io/docs/howto/html-stylesheets.html for how to
customize this style sheet.
*/
/* used to remove borders from tables and images */
.borderless, table.borderless td, table.borderless th {
border: 0 }
table.borderless td, table.borderless th {
/* Override padding for "table.docutils td" with "! important".
The right padding separates the table cells. */
padding: 0 0.5em 0 0 ! important }
.first {
/* Override more specific margin styles with "! important". */
margin-top: 0 ! important }
.last, .with-subtitle {
margin-bottom: 0 ! important }
.hidden {
display: none }
.subscript {
vertical-align: sub;
font-size: smaller }
.superscript {
vertical-align: super;
font-size: smaller }
a.toc-backref {
text-decoration: none ;
color: black }
blockquote.epigraph {
margin: 2em 5em ; }
dl.docutils dd {
margin-bottom: 0.5em }
object[type="image/svg+xml"], object[type="application/x-shockwave-flash"] {
overflow: hidden;
}
/* Uncomment (and remove this text!) to get bold-faced definition list terms
dl.docutils dt {
font-weight: bold }
*/
div.abstract {
margin: 2em 5em }
div.abstract p.topic-title {
font-weight: bold ;
text-align: center }
div.admonition, div.attention, div.caution, div.danger, div.error,
div.hint, div.important, div.note, div.tip, div.warning {
margin: 2em ;
border: medium outset ;
padding: 1em }
div.admonition p.admonition-title, div.hint p.admonition-title,
div.important p.admonition-title, div.note p.admonition-title,
div.tip p.admonition-title {
font-weight: bold ;
font-family: sans-serif }
div.attention p.admonition-title, div.caution p.admonition-title,
div.danger p.admonition-title, div.error p.admonition-title,
div.warning p.admonition-title, .code .error {
color: red ;
font-weight: bold ;
font-family: sans-serif }
/* Uncomment (and remove this text!) to get reduced vertical space in
compound paragraphs.
div.compound .compound-first, div.compound .compound-middle {
margin-bottom: 0.5em }
div.compound .compound-last, div.compound .compound-middle {
margin-top: 0.5em }
*/
div.dedication {
margin: 2em 5em ;
text-align: center ;
font-style: italic }
div.dedication p.topic-title {
font-weight: bold ;
font-style: normal }
div.figure {
margin-left: 2em ;
margin-right: 2em }
div.footer, div.header {
clear: both;
font-size: smaller }
div.line-block {
display: block ;
margin-top: 1em ;
margin-bottom: 1em }
div.line-block div.line-block {
margin-top: 0 ;
margin-bottom: 0 ;
margin-left: 1.5em }
div.sidebar {
margin: 0 0 0.5em 1em ;
border: medium outset ;
padding: 1em ;
background-color: #ffffee ;
width: 40% ;
float: right ;
clear: right }
div.sidebar p.rubric {
font-family: sans-serif ;
font-size: medium }
div.system-messages {
margin: 5em }
div.system-messages h1 {
color: red }
div.system-message {
border: medium outset ;
padding: 1em }
div.system-message p.system-message-title {
color: red ;
font-weight: bold }
div.topic {
margin: 2em }
h1.section-subtitle, h2.section-subtitle, h3.section-subtitle,
h4.section-subtitle, h5.section-subtitle, h6.section-subtitle {
margin-top: 0.4em }
h1.title {
text-align: center }
h2.subtitle {
text-align: center }
hr.docutils {
width: 75% }
img.align-left, .figure.align-left, object.align-left, table.align-left {
clear: left ;
float: left ;
margin-right: 1em }
img.align-right, .figure.align-right, object.align-right, table.align-right {
clear: right ;
float: right ;
margin-left: 1em }
img.align-center, .figure.align-center, object.align-center {
display: block;
margin-left: auto;
margin-right: auto;
}
table.align-center {
margin-left: auto;
margin-right: auto;
}
.align-left {
text-align: left }
.align-center {
clear: both ;
text-align: center }
.align-right {
text-align: right }
/* reset inner alignment in figures */
div.align-right {
text-align: inherit }
/* div.align-center * { */
/* text-align: left } */
.align-top {
vertical-align: top }
.align-middle {
vertical-align: middle }
.align-bottom {
vertical-align: bottom }
ol.simple, ul.simple {
margin-bottom: 1em }
ol.arabic {
list-style: decimal }
ol.loweralpha {
list-style: lower-alpha }
ol.upperalpha {
list-style: upper-alpha }
ol.lowerroman {
list-style: lower-roman }
ol.upperroman {
list-style: upper-roman }
p.attribution {
text-align: right ;
margin-left: 50% }
p.caption {
font-style: italic }
p.credits {
font-style: italic ;
font-size: smaller }
p.label {
white-space: nowrap }
p.rubric {
font-weight: bold ;
font-size: larger ;
color: maroon ;
text-align: center }
p.sidebar-title {
font-family: sans-serif ;
font-weight: bold ;
font-size: larger }
p.sidebar-subtitle {
font-family: sans-serif ;
font-weight: bold }
p.topic-title {
font-weight: bold }
pre.address {
margin-bottom: 0 ;
margin-top: 0 ;
font: inherit }
pre.literal-block, pre.doctest-block, pre.math, pre.code {
margin-left: 2em ;
margin-right: 2em }
pre.code .ln { color: gray; } /* line numbers */
pre.code, code { background-color: #eeeeee }
pre.code .comment, code .comment { color: #5C6576 }
pre.code .keyword, code .keyword { color: #3B0D06; font-weight: bold }
pre.code .literal.string, code .literal.string { color: #0C5404 }
pre.code .name.builtin, code .name.builtin { color: #352B84 }
pre.code .deleted, code .deleted { background-color: #DEB0A1}
pre.code .inserted, code .inserted { background-color: #A3D289}
span.classifier {
font-family: sans-serif ;
font-style: oblique }
span.classifier-delimiter {
font-family: sans-serif ;
font-weight: bold }
span.interpreted {
font-family: sans-serif }
span.option {
white-space: nowrap }
span.pre {
white-space: pre }
span.problematic, pre.problematic {
color: red }
span.section-subtitle {
/* font-size relative to parent (h1..h6 element) */
font-size: 80% }
table.citation {
border-left: solid 1px gray;
margin-left: 1px }
table.docinfo {
margin: 2em 4em }
table.docutils {
margin-top: 0.5em ;
margin-bottom: 0.5em }
table.footnote {
border-left: solid 1px black;
margin-left: 1px }
table.docutils td, table.docutils th,
table.docinfo td, table.docinfo th {
padding-left: 0.5em ;
padding-right: 0.5em ;
vertical-align: top }
table.docutils th.field-name, table.docinfo th.docinfo-name {
font-weight: bold ;
text-align: left ;
white-space: nowrap ;
padding-left: 0 }
/* "booktabs" style (no vertical lines) */
table.docutils.booktabs {
border: 0px;
border-top: 2px solid;
border-bottom: 2px solid;
border-collapse: collapse;
}
table.docutils.booktabs * {
border: 0px;
}
table.docutils.booktabs th {
border-bottom: thin solid;
text-align: left;
}
h1 tt.docutils, h2 tt.docutils, h3 tt.docutils,
h4 tt.docutils, h5 tt.docutils, h6 tt.docutils {
font-size: 100% }
ul.auto-toc {
list-style-type: none }
</style>
</head>
<body>
<div class="document">
<a class="reference external image-reference" href="https://odoo-community.org/get-involved?utm_source=readme">
<img alt="Odoo Community Association" src="https://odoo-community.org/readme-banner-image" />
</a>
<div class="section" id="upgrade-analysis">
<h1>Upgrade Analysis</h1>
<!-- !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! This file is generated by oca-gen-addon-readme !!
!! changes will be overwritten. !!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! source digest: sha256:7d83347c5c453bd132f25afe4f88b33bab0a7eb4f4b94796a52e6e9b57d311cc
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->
<p><a class="reference external image-reference" href="https://odoo-community.org/page/development-status"><img alt="Beta" src="https://img.shields.io/badge/maturity-Beta-yellow.png" /></a> <a class="reference external image-reference" href="http://www.gnu.org/licenses/agpl-3.0-standalone.html"><img alt="License: AGPL-3" src="https://img.shields.io/badge/license-AGPL--3-blue.png" /></a> <a class="reference external image-reference" href="https://github.com/OCA/server-tools/tree/18.0/upgrade_analysis"><img alt="OCA/server-tools" src="https://img.shields.io/badge/github-OCA%2Fserver--tools-lightgray.png?logo=github" /></a> <a class="reference external image-reference" href="https://translation.odoo-community.org/projects/server-tools-18-0/server-tools-18-0-upgrade_analysis"><img alt="Translate me on Weblate" src="https://img.shields.io/badge/weblate-Translate%20me-F47D42.png" /></a> <a class="reference external image-reference" href="https://runboat.odoo-community.org/builds?repo=OCA/server-tools&amp;target_branch=18.0"><img alt="Try me on Runboat" src="https://img.shields.io/badge/runboat-Try%20me-875A7B.png" /></a></p>
<p>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:
<a class="reference external" href="https://doc.therp.nl/openupgrade/analysis.html">https://doc.therp.nl/openupgrade/analysis.html</a></p>
<p>This module is just a tool, a continuation of the old
openupgrade_records in OpenUpgrade in previous versions. Its not
recommended to have this module in a production database.</p>
<p><strong>Table of contents</strong></p>
<div class="contents local topic" id="contents">
<ul class="simple">
<li><a class="reference internal" href="#usage" id="toc-entry-1">Usage</a></li>
<li><a class="reference internal" href="#known-issues-roadmap" id="toc-entry-2">Known issues / Roadmap</a></li>
<li><a class="reference internal" href="#bug-tracker" id="toc-entry-3">Bug Tracker</a></li>
<li><a class="reference internal" href="#credits" id="toc-entry-4">Credits</a><ul>
<li><a class="reference internal" href="#authors" id="toc-entry-5">Authors</a></li>
<li><a class="reference internal" href="#contributors" id="toc-entry-6">Contributors</a></li>
<li><a class="reference internal" href="#maintainers" id="toc-entry-7">Maintainers</a></li>
</ul>
</li>
</ul>
</div>
<div class="section" id="usage">
<h2><a class="toc-backref" href="#toc-entry-1">Usage</a></h2>
<p><a class="reference external" href="https://oca.github.io/OpenUpgrade/analyse.html">Usage instructions</a></p>
</div>
<div class="section" id="known-issues-roadmap">
<h2><a class="toc-backref" href="#toc-entry-2">Known issues / Roadmap</a></h2>
<ul class="simple">
<li>Log removed modules in the module that owned them (#468)</li>
<li>Detect renamed many2many tables (#213)</li>
<li>Make sure that the <tt class="docutils literal">migration_analysis.txt</tt> file is always generated
in all cases. (See:
<a class="reference external" href="https://github.com/OCA/OpenUpgrade/pull/3209#issuecomment-1157449981">https://github.com/OCA/OpenUpgrade/pull/3209#issuecomment-1157449981</a>)</li>
</ul>
</div>
<div class="section" id="bug-tracker">
<h2><a class="toc-backref" href="#toc-entry-3">Bug Tracker</a></h2>
<p>Bugs are tracked on <a class="reference external" href="https://github.com/OCA/server-tools/issues">GitHub Issues</a>.
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
<a class="reference external" href="https://github.com/OCA/server-tools/issues/new?body=module:%20upgrade_analysis%0Aversion:%2018.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**">feedback</a>.</p>
<p>Do not contact contributors directly about support or help with technical issues.</p>
</div>
<div class="section" id="credits">
<h2><a class="toc-backref" href="#toc-entry-4">Credits</a></h2>
<div class="section" id="authors">
<h3><a class="toc-backref" href="#toc-entry-5">Authors</a></h3>
<ul class="simple">
<li>Therp BV</li>
<li>Opener B.V.</li>
<li>GRAP</li>
</ul>
</div>
<div class="section" id="contributors">
<h3><a class="toc-backref" href="#toc-entry-6">Contributors</a></h3>
<ul>
<li><p class="first">Stefan Rijnhart &lt;<a class="reference external" href="mailto:stefan&#64;opener.amsterdam">stefan&#64;opener.amsterdam</a>&gt;</p>
</li>
<li><p class="first">Holger Brunn &lt;<a class="reference external" href="mailto:hbrunn&#64;therp.nl">hbrunn&#64;therp.nl</a>&gt;</p>
</li>
<li><p class="first">Ferdinand Gassauer &lt;<a class="reference external" href="mailto:gass&#64;cc-l-12.chircar.at">gass&#64;cc-l-12.chircar.at</a>&gt;</p>
</li>
<li><p class="first">Florent Xicluna &lt;<a class="reference external" href="mailto:florent.xicluna&#64;gmail.com">florent.xicluna&#64;gmail.com</a>&gt;</p>
</li>
<li><p class="first">Miquel Raïch &lt;<a class="reference external" href="mailto:miquel.raich&#64;forgeflow.com">miquel.raich&#64;forgeflow.com</a>&gt;</p>
</li>
<li><p class="first">Sylvain LE GAL &lt;<a class="reference external" href="https://twitter.com/legalsylvain">https://twitter.com/legalsylvain</a>&gt;</p>
</li>
<li><p class="first"><a class="reference external" href="https://www.tecnativa.com">Tecnativa</a>:</p>
<blockquote>
<ul class="simple">
<li>Pedro M. Baeza</li>
<li>Sergio Teruel</li>
</ul>
</blockquote>
</li>
</ul>
</div>
<div class="section" id="maintainers">
<h3><a class="toc-backref" href="#toc-entry-7">Maintainers</a></h3>
<p>This module is maintained by the OCA.</p>
<a class="reference external image-reference" href="https://odoo-community.org">
<img alt="Odoo Community Association" src="https://odoo-community.org/logo.png" />
</a>
<p>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.</p>
<p>Current <a class="reference external" href="https://odoo-community.org/page/maintainer-role">maintainers</a>:</p>
<p><a class="reference external image-reference" href="https://github.com/StefanRijnhart"><img alt="StefanRijnhart" src="https://github.com/StefanRijnhart.png?size=40px" /></a> <a class="reference external image-reference" href="https://github.com/legalsylvain"><img alt="legalsylvain" src="https://github.com/legalsylvain.png?size=40px" /></a></p>
<p>This module is part of the <a class="reference external" href="https://github.com/OCA/server-tools/tree/18.0/upgrade_analysis">OCA/server-tools</a> project on GitHub.</p>
<p>You are welcome to contribute. To learn how please visit <a class="reference external" href="https://odoo-community.org/page/Contribute">https://odoo-community.org/page/Contribute</a>.</p>
</div>
</div>
</div>
</div>
</body>
</html>

View File

@@ -0,0 +1,17 @@
<odoo>
<template id="module_coverage">Module coverage <t t-out="start_version" /> -> <t
t-out="end_version"
/>
============================
.. include:: coverage_legend.rst
+---------------------------------------------------+----------------------+-------------------------------------------------+
| Module | Status + Extra Information |
+===================================================+======================+=================================================+
<t t-foreach="module_descriptions" t-as="module">
|<t t-out="module" />| |<t t-out="module_value" />|
+---------------------------------------------------+----------------------+-------------------------------------------------+
</t>
</template>
</odoo>

View File

@@ -0,0 +1 @@
from . import test_module

View File

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

242
upgrade_analysis/upgrade_log.py Executable file
View File

@@ -0,0 +1,242 @@
# Copyright 2011-2015 Therp BV <https://therp.nl>
# Copyright 2016 Opener B.V. <https://opener.am>
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
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 <module>' 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"),
)

View File

@@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8" ?>
<odoo>
<menuitem
id="menu_upgrade"
name="Upgrade Analysis"
parent="base.menu_administration"
sequence="99"
/>
</odoo>

View File

@@ -0,0 +1,60 @@
<?xml version="1.0" encoding="utf-8" ?>
<odoo>
<record id="view_upgrade_analysis_tree" model="ir.ui.view">
<field name="model">upgrade.analysis</field>
<field name="arch" type="xml">
<list decoration-info="state == 'draft'">
<field name="config_id" />
<field name="analysis_date" />
<field name="state" />
</list>
</field>
</record>
<record id="view_upgrade_analysis_form" model="ir.ui.view">
<field name="model">upgrade.analysis</field>
<field name="arch" type="xml">
<form create="false">
<header>
<field name="state" widget="statusbar" />
<button
name="analyze"
string="Perform Analysis"
type="object"
icon="fa-cogs"
colspan="2"
/>
</header>
<sheet>
<group>
<field name="config_id" readonly="state == 'done'" />
<field name="write_files" readonly="state == 'done'" />
<field name="upgrade_path" invisible="not write_files" />
<field name="analysis_date" invisible="not analysis_date" />
</group>
<group string="Log">
<field
name="log"
nolabel="1"
widget="ace"
options="{'mode': 'txt'}"
colspan="2"
/>
</group>
</sheet>
</form>
</field>
</record>
<record id="action_upgrade_analysis_tree" model="ir.actions.act_window">
<field name="name">Upgrade Analyses</field>
<field name="res_model">upgrade.analysis</field>
</record>
<menuitem
action="action_upgrade_analysis_tree"
id="menu_upgrade_analysis"
name="Upgrade Analyses"
parent="menu_upgrade"
/>
</odoo>

View File

@@ -0,0 +1,76 @@
<?xml version="1.0" encoding="utf-8" ?>
<odoo>
<record id="view_upgrade_comparison_config_tree" model="ir.ui.view">
<field name="model">upgrade.comparison.config</field>
<field name="arch" type="xml">
<list>
<field name="name" />
<field name="server" />
<field name="port" />
<field name="database" />
</list>
</field>
</record>
<record id="view_upgrade_comparison_config_form" model="ir.ui.view">
<field name="model">upgrade.comparison.config</field>
<field name="arch" type="xml">
<form>
<header />
<sheet>
<div class="oe_button_box" name="button_box">
<button
name="action_show_analysis"
type="object"
class="oe_stat_button"
icon="fa-users"
>
<field
string="Analyses"
name="analysis_qty"
widget="statinfo"
/>
</button>
</div>
<group>
<field name="name" />
<field name="server" />
<field name="port" />
<field name="database" />
<field name="username" />
<field name="password" />
<field name="version" />
</group>
<button
name="test_connection"
string="Test Connection"
type="object"
icon="fa-television"
colspan="2"
/>
<newline />
<button
name="new_analysis"
string="New Analysis"
type="object"
icon="fa-cogs"
colspan="2"
/>
</sheet>
</form>
</field>
</record>
<record id="action_upgrade_comparison_config_tree" model="ir.actions.act_window">
<field name="name">upgrade Comparison Configs</field>
<field name="type">ir.actions.act_window</field>
<field name="res_model">upgrade.comparison.config</field>
</record>
<menuitem
action="action_upgrade_comparison_config_tree"
id="menu_upgrade_comparison_config"
name="Comparison Configurations"
parent="menu_upgrade"
/>
</odoo>

View File

@@ -0,0 +1,78 @@
<?xml version="1.0" encoding="utf-8" ?>
<odoo>
<record id="view_upgrade_record_search" model="ir.ui.view">
<field name="model">upgrade.record</field>
<field name="arch" type="xml">
<search>
<field name="module" />
<field name="model" />
<field name="field" />
<field name="type" />
<filter
name="filter_create"
string="Create Mode"
domain="[('mode', '=', 'create')]"
/>
<filter
name="filter_modify"
string="Modify Mode"
domain="[('mode', '=', 'modify')]"
/>
<filter name="group_by_module" context="{'group_by': 'module'}" />
<filter name="group_by_model" context="{'group_by': 'model'}" />
</search>
</field>
</record>
<record id="view_upgrade_record_tree" model="ir.ui.view">
<field name="model">upgrade.record</field>
<field name="arch" type="xml">
<list>
<field name="module" />
<field name="model" />
<field name="field" />
<field name="name" />
<field name="type" />
<field name="mode" />
</list>
</field>
</record>
<record id="view_upgrade_record_form" model="ir.ui.view">
<field name="model">upgrade.record</field>
<field name="arch" type="xml">
<form>
<sheet>
<group>
<field name="name" />
<field name="module" />
<field name="model" />
<field name="field" />
<field name="type" />
<field name="mode" />
</group>
<group string="Attributes">
<field name="attribute_ids" nolabel="1" colspan="2">
<list>
<field name="name" />
<field name="value" />
</list>
</field>
</group>
</sheet>
</form>
</field>
</record>
<record id="action_upgrade_record_tree" model="ir.actions.act_window">
<field name="name">upgrade Records</field>
<field name="res_model">upgrade.record</field>
</record>
<menuitem
action="action_upgrade_record_tree"
id="menu_upgrade_records"
name="Records"
parent="menu_upgrade"
/>
</odoo>

View File

@@ -0,0 +1,2 @@
from . import upgrade_generate_record_wizard
from . import upgrade_install_wizard

View File

@@ -0,0 +1,127 @@
# Copyright 2011-2015 Therp BV <https://therp.nl>
# Copyright 2016 Opener B.V. <https://opener.am>
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
from threading import current_thread
from odoo import _, fields, models
from odoo.exceptions import UserError
from odoo.modules.registry import Registry
from ..odoo_patch.odoo_patch import OdooPatch
class GenerateWizard(models.TransientModel):
_name = "upgrade.generate.record.wizard"
_description = "Upgrade Generate Record Wizard"
state = fields.Selection([("draft", "Draft"), ("done", "Done")], default="draft")
def generate(self):
"""Reinitialize all installed modules.
Equivalent of running the server with '-d <database> --init all'
The goal of this is to fill the records table.
TODO: update module list and versions, then update all modules?"""
# Truncate the records table
self.env.cr.execute("TRUNCATE upgrade_attribute, upgrade_record;")
# Check of all the modules are correctly installed
modules = self.env["ir.module.module"].search(
[("state", "in", ["to install", "to upgrade"])]
)
if modules:
raise UserError(
_("Cannot seem to install or upgrade modules %s")
% (", ".join([module.name for module in modules]))
)
# Now reinitialize all installed modules
self.env["ir.module.module"].search([("state", "=", "installed")]).write(
{"state": "to install"}
)
self.env.cr.commit() # pylint: disable=invalid-commit
# Patch the registry on the thread
thread = current_thread()
thread._upgrade_registry = {}
# Regenerate the registry with monkeypatches that log the records
with OdooPatch():
Registry.new(self.env.cr.dbname, update_module=True)
# Free the registry
delattr(thread, "_upgrade_registry")
# Set domain property
self.env.cr.execute(
""" UPDATE upgrade_record our
SET domain = iaw.domain
FROM ir_model_data imd
JOIN ir_act_window iaw ON imd.res_id = iaw.id
WHERE our.type = 'xmlid'
AND imd.model = 'ir.actions.act_window'
AND our.model = imd.model
AND our.name = imd.module || '.' || imd.name
"""
)
self.env.cache.invalidate(
[
(self.env["upgrade.record"]._fields["domain"], None),
]
)
# Set constraint definition
self.env.cr.execute(
""" UPDATE upgrade_record our
SET definition = btrim(replace(replace(replace(replace(
imc.definition, chr(9), ' '), chr(10), ' '), ' ', ' '), ' ', ' '))
FROM ir_model_data imd
JOIN ir_model_constraint imc ON imd.res_id = imc.id
WHERE our.type = 'xmlid'
AND imd.model = 'ir.model.constraint'
AND our.model = imd.model
AND our.name = imd.module || '.' || imd.name"""
)
self.env.cache.invalidate(
[
(self.env["upgrade.record"]._fields["definition"], None),
]
)
# Set noupdate property from ir_model_data
self.env.cr.execute(
""" UPDATE upgrade_record our
SET noupdate = imd.noupdate
FROM ir_model_data imd
WHERE our.type = 'xmlid'
AND our.model = imd.model
AND our.name = imd.module || '.' || imd.name
"""
)
self.env.cache.invalidate(
[
(self.env["upgrade.record"]._fields["noupdate"], None),
]
)
# Log model records
self.env.cr.execute(
"""INSERT INTO upgrade_record
(create_date, module, name, model, type)
SELECT NOW() AT TIME ZONE 'UTC',
imd2.module, imd2.module || '.' || imd.name AS name,
im.model, 'model' AS type
FROM (
SELECT min(id) as id, name, res_id
FROM ir_model_data
WHERE name LIKE 'model_%' AND model = 'ir.model'
GROUP BY name, res_id
) imd
JOIN ir_model_data imd2 ON imd2.id = imd.id
JOIN ir_model im ON imd.res_id = im.id
ORDER BY imd.name, imd.id""",
)
return self.write({"state": "done"})

View File

@@ -0,0 +1,118 @@
# Copyright 2011-2015 Therp BV <https://therp.nl>
# Copyright 2016 Opener B.V. <https://opener.am>
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
from odoo import api, fields, models
from odoo.modules.registry import Registry
from odoo.osv.expression import AND
from ..blacklist import (
BLACKLIST_MODULES,
BLACKLIST_MODULES_ENDS_WITH,
BLACKLIST_MODULES_STARTS_WITH,
)
class UpgradeInstallWizard(models.TransientModel):
_name = "upgrade.install.wizard"
_description = "Upgrade Install Wizard"
state = fields.Selection(
[("draft", "Draft"), ("done", "Done")], readonly=True, default="draft"
)
module_ids = fields.Many2many(
comodel_name="ir.module.module",
domain=lambda x: x._module_ids_domain(),
string="Modules",
)
module_qty = fields.Integer(
string="Modules Quantity", compute="_compute_module_qty"
)
@api.model
def _module_ids_domain(self, extra_domain=None):
domain = [
"&",
("state", "not in", ["installed", "uninstallable", "unknown"]),
("name", "not in", BLACKLIST_MODULES),
]
if extra_domain:
domain = AND([domain, extra_domain])
modules = self.env["ir.module.module"].search(domain)
for start_pattern in BLACKLIST_MODULES_STARTS_WITH:
modules = modules.filtered(
lambda x, start_pattern=start_pattern: not x.name.startswith(
start_pattern
)
)
for end_pattern in BLACKLIST_MODULES_ENDS_WITH:
modules = modules.filtered(
lambda x, end_pattern=end_pattern: not x.name.endswith(end_pattern)
)
return [("id", "in", modules.ids)]
@api.depends("module_ids")
def _compute_module_qty(self):
for wizard in self:
wizard.module_qty = len(wizard.module_ids)
def select_odoo_modules(self, extra_domain=None):
self.ensure_one()
modules = self.env["ir.module.module"].search(
self._module_ids_domain(extra_domain=extra_domain)
)
modules = modules.filtered(lambda x: x.is_odoo_module)
self.module_ids = modules
return self.return_same_form_view()
def select_oca_modules(self, extra_domain=None):
self.ensure_one()
modules = self.env["ir.module.module"].search(
self._module_ids_domain(extra_domain=extra_domain)
)
modules = modules.filtered(lambda x: x.is_oca_module)
self.module_ids = modules
return self.return_same_form_view()
def select_other_modules(self, extra_domain=None):
self.ensure_one()
modules = self.env["ir.module.module"].search(
self._module_ids_domain(extra_domain=extra_domain)
)
modules = modules.filtered(lambda x: not (x.is_oca_module or x.is_odoo_module))
self.module_ids = modules
return self.return_same_form_view()
def select_installable_modules(self, extra_domain=None):
self.ensure_one()
self.module_ids = self.env["ir.module.module"].search(
self._module_ids_domain(extra_domain=extra_domain)
)
return self.return_same_form_view()
def unselect_modules(self):
self.ensure_one()
self.module_ids = False
return self.return_same_form_view()
def install_modules(self):
"""Set all selected modules and actually install them."""
self.ensure_one()
self.module_ids.write({"state": "to install"})
self.env.cr.commit() # pylint: disable=invalid-commit
Registry.new(self.env.cr.dbname, update_module=True)
self.write({"state": "done"})
return self.return_same_form_view()
def return_same_form_view(self):
return {
"type": "ir.actions.act_window",
"res_model": "upgrade.install.wizard",
"view_mode": "form",
"res_id": self.id,
"views": [(False, "form")],
"target": "new",
}

View File

@@ -0,0 +1,47 @@
<?xml version="1.0" encoding="utf-8" ?>
<odoo>
<record id="view_upgrade_generate_record_wizard_form" model="ir.ui.view">
<field name="model">upgrade.generate.record.wizard</field>
<field name="arch" type="xml">
<form>
<header>
<field name="state" widget="statusbar" />
</header>
<group invisible="state != 'draft'">
<p
colspan="2"
>This will reinitialize all the modules installed on this database. Do not continue if you use this database in production.</p>
</group>
<group invisible="state != 'done'">
<p>Modules initialized and record created</p>
<p colspan="2">Modules initialized and record created</p>
</group>
<footer>
<button
string="Continue"
name="generate"
type="object"
invisible="state != 'draft'"
class="btn-primary"
/>
<button special="cancel" string="Close" class="btn-default" />
</footer>
</form>
</field>
</record>
<record id="action_upgrade_generate_record_wizard" model="ir.actions.act_window">
<field name="name">Generate Records Wizard</field>
<field name="res_model">upgrade.generate.record.wizard</field>
<field name="view_mode">form,list</field>
<field name="target">new</field>
</record>
<menuitem
name="Generate Records Wizard"
id="menu_upgrade_generate_record"
parent="menu_upgrade"
action="action_upgrade_generate_record_wizard"
sequence="15"
/>
</odoo>

View File

@@ -0,0 +1,89 @@
<?xml version="1.0" encoding="utf-8" ?>
<odoo>
<record id="view_upgrade_install_wizard_form" model="ir.ui.view">
<field name="model">upgrade.install.wizard</field>
<field name="arch" type="xml">
<form>
<header>
<field name="state" widget="statusbar" />
</header>
<group invisible="state != 'draft'">
<p
class="alert alert-warning"
role="alert"
colspan="2"
>This will install the selected modules on the database. Do not continue if you use this database in production.</p>
</group>
<group invisible="state != 'done'">
<p
class="alert alert-info"
role="alert"
colspan="2"
>The modules have been installed successfuly</p>
</group>
<header invisible="state != 'draft'">
<button
name="select_installable_modules"
type="object"
string="All Modules"
/>
<button
name="select_odoo_modules"
type="object"
string="All Odoo SA Modules"
class="btn-primary"
/>
<button
name="select_oca_modules"
type="object"
string="All OCA Modules"
/>
<button
name="select_other_modules"
type="object"
string="All Other Modules"
/>
</header>
<button
name="unselect_modules"
type="object"
string="Clear the list"
invisible="state != 'draft'"
/>
<group invisible="state != 'draft'">
<field name="module_qty" />
<field
name="module_ids"
widget="many2many_tags"
options="{'no_create': True}"
/>
</group>
<footer>
<button
name="install_modules"
type="object"
class="btn-primary"
string="Install Modules"
invisible="state != 'draft'"
/>
<button special="cancel" string="Close" class="btn-default" />
</footer>
</form>
</field>
</record>
<record id="action_upgrade_install_wizard" model="ir.actions.act_window">
<field name="name">Install Modules Wizard</field>
<field name="res_model">upgrade.install.wizard</field>
<field name="view_mode">form,list</field>
<field name="target">new</field>
</record>
<menuitem
name="Install Modules Wizard"
id="menu_upgrade_install"
parent="menu_upgrade"
action="action_upgrade_install_wizard"
sequence="14"
/>
</odoo>