# HG changeset patch # User Vincent Hatakeyama <vincent.hatakeyama@xcg-consulting.fr> # Date 1642429766 -3600 # Mon Jan 17 15:29:26 2022 +0100 # Node ID 51a9e864323fd6f4c6a4f9032ce7df8fd574fbd3 # Parent 4e0d93089bbfe1b432c3fcfa9f3289bc941088cf ✨ Odoo 15 compatibility diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -39,6 +39,8 @@ script: # restart odoo with installed modules and use it in background - $CI_PROJECT_DIR/start --db_host=db -d test_setup --max-cron-threads=0 --data-dir /var/lib/odoo & + # install current version as this is the one tested, not the one in the image + - python3 -m pip install --disable-pip-version-check --no-cache-dir --system --upgrade $CI_PROJECT_DIR - sleep 3 # then test the setup files - import_jsonrpc -v --host localhost --password admin -d test_setup --protocol jsonrpc -p 8069 --directory tests/import @@ -54,6 +56,8 @@ script: # restart odoo with installed modules and use it in background - $CI_PROJECT_DIR/start --db_host=db -d test_setup --max-cron-threads=0 --data-dir /var/lib/odoo & + # install current version as this is the one tested, not the one in the image + - python3 -m pip install --disable-pip-version-check --no-cache-dir --system --upgrade $CI_PROJECT_DIR - sleep 3 # then test the setup files - import_base_import -v --host localhost --password admin -d test_setup --protocol jsonrpc -p 8069 --directory tests/import @@ -79,6 +83,14 @@ ODOO_TYPE: odoo13 allow_failure: true +import_jsonrpc_odoo15_test: + extends: import_jsonrpc_odoo11_test + image: + name: registry.xcg.io/odoo/odoo:15.0 + entrypoint: [""] + variables: + ODOO_TYPE: odoo15 + docker_build_copy_test: needs: - job: build-docker-image diff --git a/NEWS.rst b/NEWS.rst --- a/NEWS.rst +++ b/NEWS.rst @@ -2,6 +2,11 @@ History ======= +14.1.0 +------ + +Odoo 15 compatibility. + 14.0.0 ------ diff --git a/odoo_scripts/config.py b/odoo_scripts/config.py --- a/odoo_scripts/config.py +++ b/odoo_scripts/config.py @@ -200,6 +200,7 @@ "odoo10", "odoo11", "odoo13", + "odoo15", ): if path: _logger.info( diff --git a/odoo_scripts/docker_build.py b/odoo_scripts/docker_build.py --- a/odoo_scripts/docker_build.py +++ b/odoo_scripts/docker_build.py @@ -152,7 +152,7 @@ myfile.write( "RUN DEBIAN_FRONTEND=noninteractive apt-get install -y -qq " ) - if odoo_type in ("odoo11", "odoo13"): + if odoo_type in ("odoo11", "odoo13", "odoo15"): myfile.write( "python3-watchdog python3-ipdb python3-pyinotify " "python3-wheel\n" diff --git a/odoo_scripts/docker_dev_start.py b/odoo_scripts/docker_dev_start.py --- a/odoo_scripts/docker_dev_start.py +++ b/odoo_scripts/docker_dev_start.py @@ -28,9 +28,9 @@ _logger = logging.getLogger(__name__) -__version__ = "3.0.0" +__version__ = "3.2.0" __date__ = "2017-08-11" -__updated__ = "2020-11-10" +__updated__ = "2022-01-17" def main(argv=None): # IGNORE:C0111 @@ -364,6 +364,7 @@ coverage = (nmspc.test or nmspc.test_default) and odoo_type in ( "odoo11", "odoo13", + "odoo15", ) arg = ["coverage-start" if coverage else "start"] if db_password: @@ -461,7 +462,7 @@ _logger.info("Local configuration file found: %s", local_conf_path) odoo_conf_file = ( "/etc/odoo/odoo.conf" - if odoo_type in ("odoo11", "odoo12", "odoo13") + if odoo_type in ("odoo11", "odoo12", "odoo13", "odoo15") else "/opt/odoo/etc/odoo.conf" ) mounts.append( @@ -796,7 +797,7 @@ # developer mode options if dev: - if odoo_type in ("odoo10", "odoo11", "odoo13"): + if odoo_type in ("odoo10", "odoo11", "odoo13", "odoo15"): # automatically add reload if not already asks for if not any(opt in dev_opts for opt in ("all", "reload")): dev_opts.append("reload") @@ -819,7 +820,7 @@ # bind Odoo sources if odoo_sources: _logger.info("Binding Odoo sources at %s", odoo_sources) - if odoo_type in ("odoo10", "odoo11", "odoo13"): + if odoo_type in ("odoo10", "odoo11", "odoo13", "odoo15"): # Image 11 uses python 3.5 if based on xenial, or 3.6 for bionic # 13 uses bionic if odoo_type == "odoo10": @@ -828,6 +829,8 @@ pythons = ("python3.5", "python3.6") elif odoo_type == "odoo13": pythons = ("python3.8",) + elif odoo_type == "odoo15": + pythons = ("python3.9",) else: pythons = ("python3.6",) for python in pythons: diff --git a/odoo_scripts/import_jsonrpc.py b/odoo_scripts/import_jsonrpc.py --- a/odoo_scripts/import_jsonrpc.py +++ b/odoo_scripts/import_jsonrpc.py @@ -20,9 +20,9 @@ _logger = logging.getLogger(__name__) -__version__ = "1.1.0" +__version__ = "1.2.0" __date__ = "2020-02-17" -__updated__ = "2021-12-29" +__updated__ = "2022-01-17" def import_with_jsonrpc( @@ -55,9 +55,29 @@ def _ref(xmlid: str, raise_if_not_found: bool = True) -> Union[bool, int]: if xmlid not in xmlid_cache: - full_xmlid = xmlid if "." in xmlid else "." + xmlid try: - record_id = imd.xmlid_to_res_id(full_xmlid, raise_if_not_found) + # o.env.ref also exists but also fails in odoo 15. + # xmlid_to_res_id is now _xmlid_to_res_id + if o.version == "15.0": + if "." in xmlid: + module, xml_id = xmlid.split(".", maxsplit=1) + else: + module, xml_id = "", xmlid + # issue with check_object_reference: inactive record are + # not found, so use a good old search + imd_id = imd.search( + [("name", "=", xml_id), ("module", "=", module)] + ) + record_id = ( + imd.read(imd_id, ["res_id"])[0]["res_id"] + if imd_id + else None + ) + else: + full_xmlid = xmlid if "." in xmlid else "." + xmlid + record_id = imd.xmlid_to_res_id( + full_xmlid, raise_if_not_found + ) except RPCError as error: if allow_missing_refs: _logger.warning(str(error)) diff --git a/odoo_scripts/import_sql.py b/odoo_scripts/import_sql.py --- a/odoo_scripts/import_sql.py +++ b/odoo_scripts/import_sql.py @@ -14,9 +14,9 @@ _logger = logging.getLogger(__name__) -__version__ = "1.0.0" +__version__ = "1.1.0" __date__ = "2020-06-08" -__updated__ = "2020-06-08" +__updated__ = "2022-01-18" def _execute(cursor, query, parameters): @@ -24,6 +24,18 @@ cursor.execute(query, parameters) +def _column_exists(cursor, table_name: str, column_name: str) -> bool: + """Return true if the column exists in the table.""" + _execute( + cursor, + "SELECT count(*) FROM information_schema.columns WHERE table_name=%s " + "and column_name=%s", + (table_name, column_name), + ) + result = cursor.fetchall()[0][0] + return bool(result) + + def sql_import( connection, table_filenames: List[Tuple[str, str]], delimiter: str ) -> None: @@ -41,6 +53,10 @@ _logger.info( "Importing - %s in %s (table %s)", csv_file, model, table ) + has_date_init = _column_exists(cur, "ir_model_data", "date_init") + has_date_update = _column_exists( + cur, "ir_model_data", "date_update" + ) with open(csv_file, "r") as file: reader = csv.DictReader( file, delimiter=delimiter, quotechar='"' @@ -99,14 +115,15 @@ ), ) _execute(cur, query, list(row.values()) + [res_id]) - # update date_update in ir_model_data - _execute( - cur, - "UPDATE ir_model_data " - "SET date_update=(now() at time zone 'UTC') " - "WHERE id=%s", - (imd_id,), - ) + # update date_update in ir_model_data if it exists + if has_date_update: + _execute( + cur, + "UPDATE ir_model_data SET " + "date_update=(now() at time zone 'UTC') " + "WHERE id=%s", + (imd_id,), + ) written += 1 else: # otherwise do an insert and update the columns @@ -130,11 +147,24 @@ db_id = cur.fetchone()[0] _execute( cur, - "INSERT INTO ir_model_data (module, name, " - "model, res_id, date_init, date_update) " - "VALUES (%s, %s, %s, %s, " - "(now() at time zone 'UTC'), " - "(now() at time zone 'UTC'))", + "INSERT INTO ir_model_data (create_date, " + "create_uid, write_date, write_uid, module, " + "name, model, res_id" + + (", date_init" if has_date_init else "") + + (", date_update" if has_date_update else "") + + ") VALUES ((now() at time zone 'UTC'), 1, " + "(now() at time zone 'UTC'), 1, %s, %s, %s, %s" + + ( + ",(now() at time zone 'UTC')" + if has_date_init + else "" + ) + + ( + ",(now() at time zone 'UTC')" + if has_date_update + else "" + ) + + ")", (module, name, model, db_id), ) created += 1 @@ -183,7 +213,7 @@ program_license = """%s Created by Vincent Hatakeyama on %s. - Copyright 2020 XCG Consulting. All rights reserved. + Copyright 2020, 2022 XCG Consulting. All rights reserved. Licensed under the MIT License diff --git a/start b/start --- a/start +++ b/start @@ -27,7 +27,7 @@ odoo_command=openerp-server odoo_addons_path=${ODOO_ADDONS_PATH:-/opt/odoo/sources/odoo} ;; - odoo10 | odoo11 | odoo13) + odoo10 | odoo11 | odoo13 | odoo15) odoo_command=odoo ;; esac