mirror of
https://github.com/bringout/oca-technical.git
synced 2026-04-18 11:52:00 +02:00
Initial commit: OCA Technical packages (595 packages)
This commit is contained in:
commit
2cc02aac6e
24950 changed files with 2318079 additions and 0 deletions
|
|
@ -0,0 +1,235 @@
|
|||
# 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 _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),
|
||||
"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 = "{}.{}".format(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"),
|
||||
)
|
||||
Loading…
Add table
Add a link
Reference in a new issue