From 74c4b78fc76a98d4eb1fdc212c31eab7ce3f1688 Mon Sep 17 00:00:00 2001 From: belloafeez Date: Thu, 1 Aug 2024 08:35:34 +0100 Subject: [PATCH 01/54] Signed-off-by: belloafeez Added all files for odoo --- odoo/Odoo.config | 0 odoo/add-ons.sh | 0 odoo/entrypoint.sh | 49 +++++++++++++++++++++++++++++++++++++++++++ odoo/odoo.conf | 37 ++++++++++++++++++++++++++++++++ odoo/wait-for-psql.py | 32 ++++++++++++++++++++++++++++ 5 files changed, 118 insertions(+) create mode 100644 odoo/Odoo.config create mode 100644 odoo/add-ons.sh create mode 100644 odoo/entrypoint.sh create mode 100644 odoo/odoo.conf create mode 100644 odoo/wait-for-psql.py diff --git a/odoo/Odoo.config b/odoo/Odoo.config new file mode 100644 index 0000000..e69de29 diff --git a/odoo/add-ons.sh b/odoo/add-ons.sh new file mode 100644 index 0000000..e69de29 diff --git a/odoo/entrypoint.sh b/odoo/entrypoint.sh new file mode 100644 index 0000000..f802bcb --- /dev/null +++ b/odoo/entrypoint.sh @@ -0,0 +1,49 @@ +#!/bin/bash + +set -e + +if [ -v PASSWORD_FILE ]; then + PASSWORD="$(< $PASSWORD_FILE)" +fi + +# set the postgres database host, port, user and password according to the environment +# and pass them as arguments to the odoo process if not present in the config file +: ${HOST:=${DB_PORT_5432_TCP_ADDR:='db'}} +: ${PORT:=${DB_PORT_5432_TCP_PORT:=5432}} +: ${USER:=${DB_ENV_POSTGRES_USER:=${POSTGRES_USER:='odoo'}}} +: ${PASSWORD:=${DB_ENV_POSTGRES_PASSWORD:=${POSTGRES_PASSWORD:='odoo'}}} + +DB_ARGS=() +function check_config() { + param="$1" + value="$2" + if grep -q -E "^\s*\b${param}\b\s*=" "$ODOO_RC" ; then + value=$(grep -E "^\s*\b${param}\b\s*=" "$ODOO_RC" |cut -d " " -f3|sed 's/["\n\r]//g') + fi; + DB_ARGS+=("--${param}") + DB_ARGS+=("${value}") +} +check_config "db_host" "$HOST" +check_config "db_port" "$PORT" +check_config "db_user" "$USER" +check_config "db_password" "$PASSWORD" + +case "$1" in + -- | odoo) + shift + if [[ "$1" == "scaffold" ]] ; then + exec odoo "$@" + else + wait-for-psql.py ${DB_ARGS[@]} --timeout=30 + exec odoo "$@" "${DB_ARGS[@]}" + fi + ;; + -*) + wait-for-psql.py ${DB_ARGS[@]} --timeout=30 + exec odoo "$@" "${DB_ARGS[@]}" + ;; + *) + exec "$@" +esac + +exit 1 diff --git a/odoo/odoo.conf b/odoo/odoo.conf new file mode 100644 index 0000000..28f70c1 --- /dev/null +++ b/odoo/odoo.conf @@ -0,0 +1,37 @@ +[options] +addons_path = /mnt/extra-addons +data_dir = /var/lib/odoo +; admin_passwd = admin +; csv_internal_sep = , +; db_maxconn = 64 +; db_name = False +; db_template = template1 +; dbfilter = .* +; debug_mode = False +; email_from = False +; limit_memory_hard = 2684354560 +; limit_memory_soft = 2147483648 +; limit_request = 8192 +; limit_time_cpu = 60 +; limit_time_real = 120 +; list_db = True +; log_db = False +; log_handler = [':INFO'] +; log_level = info +; logfile = None +; longpolling_port = 8072 +; max_cron_threads = 2 +; osv_memory_age_limit = 1.0 +; osv_memory_count_limit = False +; smtp_password = False +; smtp_port = 25 +; smtp_server = localhost +; smtp_ssl = False +; smtp_user = False +; workers = 0 +; xmlrpc = True +; xmlrpc_interface = +; xmlrpc_port = 8069 +; xmlrpcs = True +; xmlrpcs_interface = +; xmlrpcs_port = 8071 diff --git a/odoo/wait-for-psql.py b/odoo/wait-for-psql.py new file mode 100644 index 0000000..a55f440 --- /dev/null +++ b/odoo/wait-for-psql.py @@ -0,0 +1,32 @@ +#!/usr/bin/env python3 +import argparse +import psycopg2 +import sys +import time + + +if __name__ == '__main__': + arg_parser = argparse.ArgumentParser() + arg_parser.add_argument('--db_host', required=True) + arg_parser.add_argument('--db_port', required=True) + arg_parser.add_argument('--db_user', required=True) + arg_parser.add_argument('--db_password', required=True) + arg_parser.add_argument('--timeout', type=int, default=5) + + args = arg_parser.parse_args() + + start_time = time.time() + while (time.time() - start_time) < args.timeout: + try: + conn = psycopg2.connect(user=args.db_user, host=args.db_host, port=args.db_port, password=args.db_password, dbname='postgres') + error = '' + break + except psycopg2.OperationalError as e: + error = e + else: + conn.close() + time.sleep(1) + + if error: + print("Database connection failure: %s" % error, file=sys.stderr) + sys.exit(1) From 41913581a14c4df3618b4a481e6bc8169126c9a6 Mon Sep 17 00:00:00 2001 From: belloafeez Date: Thu, 1 Aug 2024 09:49:27 +0100 Subject: [PATCH 02/54] docker compose updated Signed-off-by: belloafeez --- docker-compose.yml | 84 ++++++++++++++++++++++++++++++++-------------- 1 file changed, 59 insertions(+), 25 deletions(-) diff --git a/docker-compose.yml b/docker-compose.yml index 3b7ba85..c7eaeea 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -22,20 +22,7 @@ services: build: context: ./openems-edge image: openems-edge:latest - - db: - build: - context: ./odoo-database - image: odoo-db - user: root - environment: - - POSTGRES_USER=odoo - - POSTGRES_PASSWORD=odoo16@2022 - - POSTGRES_DB=postgres - restart: always # run as a service - volumes: - - ./postgresql:/var/lib/postgresql/data - + odoo16: build: context: ./odoo @@ -44,23 +31,70 @@ services: depends_on: - db ports: - - "10016:8069" - - "20016:8072" # live chat - tty: true - command: -- + - "8069:8069" + volumes: + - odoo-web-data:/var/lib/odoo + - ./config:/etc/odoo + - ./addons:/mnt/extra-addons environment: - HOST=db - USER=odoo - - PASSWORD=odoo16@2022 + - PASSWORD=odoo # Replace 'odoo-password' with your actual password + db: + build: + context: ./odoo-database + image: odoo-db + user: root + environment: + - POSTGRES_DB=postgres + - POSTGRES_PASSWORD=odoo # Replace 'odoo-password' with your actual password + - POSTGRES_USER=odoo + - PGDATA=/var/lib/postgresql/data/pgdata volumes: - #- /etc/timezone:/etc/timezone:ro - #- /etc/localtime:/etc/localtime:ro - # - ./entrypoint.sh:/entrypoint.sh # if you want to install additional Python packages, uncomment this line! - - ./addons:/mnt/extra-addons - - ./etc:/etc/odoo - restart: always + - odoo-db-data:/var/lib/postgresql/data/pgdata +volumes: + odoo-web-data: + odoo-db-data: + # db: + # build: + # context: ./odoo-database + # image: odoo-db + # user: root + # environment: + # - POSTGRES_USER=odoo + # - POSTGRES_PASSWORD=odoo16@2022 + # - POSTGRES_DB=postgres + # restart: always # run as a service + # volumes: + # - ./postgresql:/var/lib/postgresql/data + + # odoo16: + # build: + # context: ./odoo + # image: odoo + # user: root + # depends_on: + # - db + # ports: + # - "10016:8069" + # - "20016:8072" # live chat + # tty: true + # command: -- + # environment: + # - HOST=db + # - USER=odoo + # - PASSWORD=odoo16@2022 + # volumes: + # #- /etc/timezone:/etc/timezone:ro + # #- /etc/localtime:/etc/localtime:ro + # # - ./entrypoint.sh:/entrypoint.sh # if you want to install additional Python packages, uncomment this line! + # - ./addons:/mnt/extra-addons + # - ./etc:/etc/odoo + # restart: always + + # openems-database: # build: From 87fc6c027612db726b9399f3384e9072298c370e Mon Sep 17 00:00:00 2001 From: belloafeez Date: Thu, 1 Aug 2024 10:24:53 +0100 Subject: [PATCH 03/54] docker compose update Signed-off-by: belloafeez --- SECURITY.md | 14 -- ] | 13 -- docker-compose.yml | 84 +++------ entrypoint.sh | 51 ------ etc/odoo.conf | 400 ------------------------------------------- etc/requirements.txt | 8 - run.sh | 19 -- 7 files changed, 25 insertions(+), 564 deletions(-) delete mode 100644 SECURITY.md delete mode 100644 ] delete mode 100644 entrypoint.sh delete mode 100644 etc/odoo.conf delete mode 100644 etc/requirements.txt delete mode 100644 run.sh diff --git a/SECURITY.md b/SECURITY.md deleted file mode 100644 index 29fab47..0000000 --- a/SECURITY.md +++ /dev/null @@ -1,14 +0,0 @@ -# Security Policy - -See https://github.com/energy-iot/docs/security/policy - -## Supported Versions - -All versions of Energy IoT Open source strive to keep up of critical and high vulnarabilities patches when available. - -https://github.com/OpenEMS/openems/releases/tag/2024.2.0 -https://github.com/OpenEMS/openems/releases/tag/2023.11.0 - -## Reporting a Vulnerability - -See https://github.com/energy-iot/docs/security/policy diff --git a/] b/] deleted file mode 100644 index 5c11fac..0000000 --- a/] +++ /dev/null @@ -1,13 +0,0 @@ - - -Signed-off-by: belloafeez - -# Please enter the commit message for your changes. Lines starting -# with '#' will be ignored, and an empty message aborts the commit. -# -# On branch axmsoftware-new -# Changes to be committed: -# modified: .github/workflows/deploy-pipeline.yml - - -destroy pipeline diff --git a/docker-compose.yml b/docker-compose.yml index c7eaeea..3b7ba85 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -22,7 +22,20 @@ services: build: context: ./openems-edge image: openems-edge:latest - + + db: + build: + context: ./odoo-database + image: odoo-db + user: root + environment: + - POSTGRES_USER=odoo + - POSTGRES_PASSWORD=odoo16@2022 + - POSTGRES_DB=postgres + restart: always # run as a service + volumes: + - ./postgresql:/var/lib/postgresql/data + odoo16: build: context: ./odoo @@ -31,70 +44,23 @@ services: depends_on: - db ports: - - "8069:8069" - volumes: - - odoo-web-data:/var/lib/odoo - - ./config:/etc/odoo - - ./addons:/mnt/extra-addons + - "10016:8069" + - "20016:8072" # live chat + tty: true + command: -- environment: - HOST=db - USER=odoo - - PASSWORD=odoo # Replace 'odoo-password' with your actual password - db: - build: - context: ./odoo-database - image: odoo-db - user: root - environment: - - POSTGRES_DB=postgres - - POSTGRES_PASSWORD=odoo # Replace 'odoo-password' with your actual password - - POSTGRES_USER=odoo - - PGDATA=/var/lib/postgresql/data/pgdata + - PASSWORD=odoo16@2022 volumes: - - odoo-db-data:/var/lib/postgresql/data/pgdata -volumes: - odoo-web-data: - odoo-db-data: - - # db: - # build: - # context: ./odoo-database - # image: odoo-db - # user: root - # environment: - # - POSTGRES_USER=odoo - # - POSTGRES_PASSWORD=odoo16@2022 - # - POSTGRES_DB=postgres - # restart: always # run as a service - # volumes: - # - ./postgresql:/var/lib/postgresql/data + #- /etc/timezone:/etc/timezone:ro + #- /etc/localtime:/etc/localtime:ro + # - ./entrypoint.sh:/entrypoint.sh # if you want to install additional Python packages, uncomment this line! + - ./addons:/mnt/extra-addons + - ./etc:/etc/odoo + restart: always - # odoo16: - # build: - # context: ./odoo - # image: odoo - # user: root - # depends_on: - # - db - # ports: - # - "10016:8069" - # - "20016:8072" # live chat - # tty: true - # command: -- - # environment: - # - HOST=db - # - USER=odoo - # - PASSWORD=odoo16@2022 - # volumes: - # #- /etc/timezone:/etc/timezone:ro - # #- /etc/localtime:/etc/localtime:ro - # # - ./entrypoint.sh:/entrypoint.sh # if you want to install additional Python packages, uncomment this line! - # - ./addons:/mnt/extra-addons - # - ./etc:/etc/odoo - # restart: always - - # openems-database: # build: diff --git a/entrypoint.sh b/entrypoint.sh deleted file mode 100644 index bde63c8..0000000 --- a/entrypoint.sh +++ /dev/null @@ -1,51 +0,0 @@ -#!/bin/bash - -set -e - -# set the postgres database host, port, user and password according to the environment -# and pass them as arguments to the odoo process if not present in the config file -: ${HOST:=${DB_PORT_5432_TCP_ADDR:='db'}} -: ${PORT:=${DB_PORT_5432_TCP_PORT:=5432}} -: ${USER:=${DB_ENV_POSTGRES_USER:=${POSTGRES_USER:='odoo'}}} -: ${PASSWORD:=${DB_ENV_POSTGRES_PASSWORD:=${POSTGRES_PASSWORD:='odoo16@2022'}}} - -# install python packages -pip3 install pip --upgrade -pip3 install -r /etc/odoo/requirements.txt - -# sed -i 's|raise werkzeug.exceptions.BadRequest(msg)|self.jsonrequest = {}|g' /usr/lib/python3/dist-packages/odoo/http.py - -DB_ARGS=() -function check_config() { - param="$1" - value="$2" - if grep -q -E "^\s*\b${param}\b\s*=" "$ODOO_RC" ; then - value=$(grep -E "^\s*\b${param}\b\s*=" "$ODOO_RC" |cut -d " " -f3|sed 's/["\n\r]//g') - fi; - DB_ARGS+=("--${param}") - DB_ARGS+=("${value}") -} -check_config "db_host" "$HOST" -check_config "db_port" "$PORT" -check_config "db_user" "$USER" -check_config "db_password" "$PASSWORD" - -case "$1" in - -- | odoo) - shift - if [[ "$1" == "scaffold" ]] ; then - exec odoo "$@" - else - wait-for-psql.py ${DB_ARGS[@]} --timeout=30 - exec odoo "$@" "${DB_ARGS[@]}" - fi - ;; - -*) - wait-for-psql.py ${DB_ARGS[@]} --timeout=30 - exec odoo "$@" "${DB_ARGS[@]}" - ;; - *) - exec "$@" -esac - -exit 1 \ No newline at end of file diff --git a/etc/odoo.conf b/etc/odoo.conf deleted file mode 100644 index f7b2fc6..0000000 --- a/etc/odoo.conf +++ /dev/null @@ -1,400 +0,0 @@ -[options] -; =================== -; | Common options) | -; =================== -; ------ -; -c / --config | specify alternate config file -; ------ -; config = - -; ------ -; -s / --save | save configuration to ~/.odoorc (or to ~/.openerp_serverrc if it exists) -; ------ -; save = - -; ------ -; -i / --init | install one or more modules (comma-separated list, use "all" for all modules), requires -d -; ------ -; init = - -; ------ -; -u / --update | update one or more modules (comma-separated list, use "all" for all modules). Requires -d. -; ------ -; update = - -; ------ -; --without-demo | disable loading demo data for modules to be installed (comma-separated, use "all" for all modules). Requires -d and -i. Default is %default -; ------ -; without_demo = - -; ------ -; -P / --import-partial | Use this for big data importation, if it crashes you will be able to continue at the current state. Provide a filename to store intermediate importation states. -; ------ -; import_partial = - -; ------ -; --pidfile | file where the server pid will be stored -; ------ -; pidfile = - -; ------ -; --addons-path | type = string | specify additional addons paths (separated by commas). -; ------ -addons_path = /mnt/extra-addons - -; ------ -; --upgrade-path | type = string | specify an additional upgrade path. -; ------ -; upgrade_path = - -; ------ -; --load | Comma-separated list of server-wide modules. -; ------ -; server_wide_modules = base,web - -; ------ -; -D / --data-dir | Directory where to store Odoo data -; ------ -data_dir = /etc/odoo - -admin_passwd = openemspassword - -; ============================== -; | HTTP Service Configuration | -; ============================== -; ------ -; --http-interface | Listen interface address for HTTP services. Keep empty to listen on all interfaces (0.0.0.0) -; ------ -; http_interface = - -; ------ -; -p / --http-port | type = int | Listen port for the main HTTP service -; ------ -; http_port = 8069 - -; ------ -; --longpolling-port | type = int | Listen port for the longpolling HTTP service -; ------ -; longpolling_port = 8072 - -; ------ -; --no-http | Disable the HTTP and Longpolling services entirely -; ------ -; http_enable = True - -; ------ -; --proxy-mode | Activate reverse proxy WSGI wrappers (headers rewriting) Only enable this when running behind a trusted web proxy! -; ------ -; proxy_mode = - -; ------ -; --xmlrpc-interface | SUPPRESSHELP -; ------ -; http_interface = - -; ------ -; --xmlrpc-port | type = int | SUPPRESSHELP -; ------ -; http_port = - -; ------ -; --no-xmlrpc | SUPPRESSHELP -; ------ -; http_enable = - -; =============================== -; | Web interface Configuration | -; =============================== -; ------ -; --db-filter | Regular expressions for filtering available databases for Web UI. The expression can use %d (domain) and %h (host) placeholders. -; ------ -; dbfilter = - -; ========================= -; | Testing Configuration | -; ========================= -; ------ -; --test-file | Launch a python test file. -; ------ -; test_file = - -; ------ -; --test-enable | Enable unit tests. -; ------ -; test_enable = - -; ------ -; --test-tags | Comma-separated list of spec to filter which tests to execute. Enable unit tests if set. A filter spec has the format: [-][tag][/module][:class][.method] The '-' specifies if we want to include or exclude tests matching this spec. The tag will match tags added on a class with a @tagged decorator. By default tag value is 'standard' when not given on include mode. '*' will match all tags. Tag will also match module name (deprecated, use /module) The module, class, and method will respectively match the module name, test class name and test method name. examples: :TestClass.test_func,/test_module,external -; ------ -; test_tags = - -; ------ -; --screencasts | Screencasts will go in DIR/{db_name}/screencasts. -; ------ -; screencasts = - -; ------ -; --screenshots | Screenshots will go in DIR/{db_name}/screenshots. Defaults to /etc/odoo/odoo_tests. -; ------ -; screenshots = /etc/odoo/odoo_tests - -; ========================= -; | Logging Configuration | -; ========================= -; ------ -; --logfile | file where the server log will be stored -; ------ -logfile = /etc/odoo/odoo-server.log - -; ------ -; --syslog | Send the log to the syslog server -; ------ -; syslog = - -; ------ -; --log-handler | setup a handler at LEVEL for a given PREFIX. An empty PREFIX indicates the root logger. This option can be repeated. Example: "odoo.orm:DEBUG" or "werkzeug:CRITICAL" (default: ":INFO") -; ------ -; None = :INFO - -; ------ -; --log-request | shortcut for --log-handler=odoo.http.rpc.request:DEBUG -; ------ -; log_handler = - -; ------ -; --log-response | shortcut for --log-handler=odoo.http.rpc.response:DEBUG -; ------ -; log_handler = - -; ------ -; --log-web | shortcut for --log-handler=odoo.http:DEBUG -; ------ -; log_handler = - -; ------ -; --log-sql | shortcut for --log-handler=odoo.sql_db:DEBUG -; ------ -; log_handler = - -; ------ -; --log-db | Logging database -; ------ -; log_db = - -; ------ -; --log-db-level | Logging database level -; ------ -; log_db_level = warning - -; ------ -; --log-level | type = choice | choices = ['info', 'debug_rpc', 'warn', 'test', 'critical', 'runbot', 'debug_sql', 'error', 'debug', 'debug_rpc_answer', 'notset'] | specify the level of the logging. Accepted values: ['info', 'debug_rpc', 'warn', 'test', 'critical', 'runbot', 'debug_sql', 'error', 'debug', 'debug_rpc_answer', 'notset']. -; ------ -; log_level = info - -; ====================== -; | SMTP Configuration | -; ====================== -; ------ -; --email-from | specify the SMTP email address for sending email -; ------ -; email_from = - -; ------ -; --smtp | specify the SMTP server for sending email -; ------ -; smtp_server = localhost - -; ------ -; --smtp-port | type = int | specify the SMTP port -; ------ -; smtp_port = 25 - -; ------ -; --smtp-ssl | if passed, SMTP connections will be encrypted with SSL (STARTTLS) -; ------ -; smtp_ssl = - -; ------ -; --smtp-user | specify the SMTP username for sending email -; ------ -; smtp_user = - -; ------ -; --smtp-password | specify the SMTP password for sending email -; ------ -; smtp_password = - -; ============================ -; | Database related options | -; ============================ -; ------ -; -d / --database | specify the database name -; ------ -; db_name = - -; ------ -; -r / --db_user | specify the database user name -; ------ -; db_user = - -; ------ -; -w / --db_password | specify the database password -; ------ -; db_password = - -; ------ -; --pg_path | specify the pg executable path -; ------ -; pg_path = - -; ------ -; --db_host | specify the database host -; ------ -; db_host = - -; ------ -; --db_port | type = int | specify the database port -; ------ -; db_port = - -; ------ -; --db_sslmode | type = choice | choices = ['disable', 'allow', 'prefer', 'require', 'verify-ca', 'verify-full'] | specify the database ssl connection mode (see PostgreSQL documentation) -; ------ -; db_sslmode = prefer - -; ------ -; --db_maxconn | type = int | specify the maximum number of physical connections to PostgreSQL -; ------ -; db_maxconn = 64 - -; ------ -; --db-template | specify a custom database template to create a new database -; ------ -; db_template = template0 - -; ======================== -; | Internationalisation | -; ======================== -; ------ -; --load-language | specifies the languages for the translations you want to be loaded -; ------ -; load_language = - -; ------ -; -l / --language | specify the language of the translation file. Use it with --i18n-export or --i18n-import -; ------ -; language = - -; ------ -; --i18n-export | export all sentences to be translated to a CSV file, a PO file or a TGZ archive and exit -; ------ -; translate_out = - -; ------ -; --i18n-import | import a CSV or a PO file with translations and exit. The '-l' option is required. -; ------ -; translate_in = - -; ------ -; --i18n-overwrite | overwrites existing translation terms on updating a module or importing a CSV or a PO file. -; ------ -; overwrite_existing_translations = - -; ------ -; --modules | specify modules to export. Use in combination with --i18n-export -; ------ -; translate_modules = - -; ============================ -; | Security-related options | -; ============================ -; ------ -; --no-database-list | Disable the ability to obtain or view the list of databases. Also disable access to the database manager and selector, so be sure to set a proper --database parameter first -; ------ -; list_db = True - -; ==================== -; | Advanced options | -; ==================== -; ------ -; --dev | type = string | Enable developer mode. Param: List of options separated by comma. Options : all, [pudb|wdb|ipdb|pdb], reload, qweb, werkzeug, xml -; ------ -dev_mode = reload - -; ------ -; --shell-interface | type = string | Specify a preferred REPL to use in shell mode. Supported REPLs are: [ipython|ptpython|bpython|python] -; ------ -; shell_interface = - -; ------ -; --stop-after-init | stop the server after its initialization -; ------ -; stop_after_init = - -; ------ -; --osv-memory-count-limit | type = int | Force a limit on the maximum number of records kept in the virtual osv_memory tables. The default is False, which means no count-based limit. -; ------ -; osv_memory_count_limit = - -; ------ -; --transient-age-limit | type = float | Time limit (decimal value in hours) records created with a TransientModel (mosly wizard) are kept in the database. Default to 1 hour. -; ------ -; transient_age_limit = 1.0 - -; ------ -; --osv-memory-age-limit | type = float | Deprecated alias to the transient-age-limit option -; ------ -; osv_memory_age_limit = - -; ------ -; --max-cron-threads | type = int | Maximum number of threads processing concurrently cron jobs (default 2). -; ------ -; max_cron_threads = 2 - -; ------ -; --unaccent | Try to enable the unaccent extension when creating new databases. -; ------ -; unaccent = - -; ------ -; --geoip-db | Absolute path to the GeoIP database file. -; ------ -; geoip_database = /usr/share/GeoIP/GeoLite2-City.mmdb - -; =========================== -; | Multiprocessing options | -; =========================== -; ------ -; --workers | type = int | Specify the number of workers, 0 disable prefork mode. -; ------ -; workers = - -; ------ -; --limit-memory-soft | type = int | Maximum allowed virtual memory per worker (in bytes), when reached the worker be reset after the current request (default 2048MiB). -; ------ -; limit_memory_soft = 2147483648 - -; ------ -; --limit-memory-hard | type = int | Maximum allowed virtual memory per worker (in bytes), when reached, any memory allocation will fail (default 2560MiB). -; ------ -; limit_memory_hard = 2684354560 - -; ------ -; --limit-time-cpu | type = int | Maximum allowed CPU time per request (default 60). -; ------ -; limit_time_cpu = 60 - -; ------ -; --limit-time-real | type = int | Maximum allowed Real time per request (default 120). -; ------ -; limit_time_real = 120 - -; ------ -; --limit-time-real-cron | type = int | Maximum allowed Real time per cron job. (default: --limit-time-real). Set to 0 for no limit. -; ------ -; limit_time_real_cron = -1 - -; ------ -; --limit-request | type = int | Maximum number of request to be processed per worker (default 8192). -; ------ -; limit_request = 8192 diff --git a/etc/requirements.txt b/etc/requirements.txt deleted file mode 100644 index 6853d72..0000000 --- a/etc/requirements.txt +++ /dev/null @@ -1,8 +0,0 @@ -# ----------------------- -# | Add Python packages | -# ----------------------- -# To install below packages at startup, uncomment this line in "docker-compose.yml" file! -# - ./entrypoint.sh:/entrypoint.sh -# then down the docker container ($ docker-compose down) and up it again ($ docker-compose up -d). -# ----------------------- -# paramiko==2.7.2 # for auto_backup module diff --git a/run.sh b/run.sh deleted file mode 100644 index 47ccd36..0000000 --- a/run.sh +++ /dev/null @@ -1,19 +0,0 @@ -#!/bin/bash -DESTINATION=$1 -PORT=$2 -CHAT=$3 -# clone Odoo directory -git clone --depth=1 https://github.com/minhng92/odoo-16-docker-compose $DESTINATION -rm -rf $DESTINATION/.git -# set permission -mkdir -p $DESTINATION/postgresql -sudo chmod -R 777 $DESTINATION -# config -if grep -qF "fs.inotify.max_user_watches" /etc/sysctl.conf; then echo $(grep -F "fs.inotify.max_user_watches" /etc/sysctl.conf); else echo "fs.inotify.max_user_watches = 524288" | sudo tee -a /etc/sysctl.conf; fi -sudo sysctl -p -sed -i 's/10016/'$PORT'/g' $DESTINATION/docker-compose.yml -sed -i 's/20016/'$CHAT'/g' $DESTINATION/docker-compose.yml -# run Odoo -docker-compose -f $DESTINATION/docker-compose.yml up -d - -echo 'Started Odoo @ http://localhost:'$PORT' | Master Password: minhng.info | Live chat port: '$CHAT From f3bc998948c1dff5f4f56bb009ccf8942fbf245a Mon Sep 17 00:00:00 2001 From: belloafeez Date: Thu, 1 Aug 2024 11:01:24 +0100 Subject: [PATCH 04/54] updated odoo addons Signed-off-by: belloafeez --- addons/openems/.gitignore | 3 + addons/openems/__init__.py | 1 + addons/openems/__manifest__.py | 40 + addons/openems/controllers/__init__.py | 1 + addons/openems/controllers/alerting.py | 86 + addons/openems/controllers/const.py | 5 + addons/openems/controllers/openems_backend.py | 276 +++ addons/openems/controllers/setup_protocol.py | 142 ++ addons/openems/controllers/user.py | 32 + addons/openems/data/OpenEMS-Logo.jpg | Bin 0 -> 152320 bytes addons/openems/data/demo.xml | 12 + addons/openems/data/ir_config_parameter.xml | 9 + addons/openems/data/res_partner_category.xml | 11 + addons/openems/i18n/de.po | 1666 +++++++++++++++++ addons/openems/i18n/openems.pot | 1666 +++++++++++++++++ .../openems/mail/openems/alerting_offline.xml | 275 +++ .../mail/openems/alerting_sum_state.xml | 268 +++ .../mail/openems/setup_protocol_customer.xml | 170 ++ .../mail/openems/setup_protocol_installer.xml | 173 ++ .../mail/openems/user_registration.xml | 197 ++ .../migrations/16.0.1.0.1/post-migrate.py | 9 + .../migrations/16.0.1.0.1/pre-migrate.py | 7 + addons/openems/models/__init__.py | 1 + addons/openems/models/device.py | 321 ++++ addons/openems/models/partner.py | 12 + addons/openems/models/setup_protocol.py | 49 + addons/openems/models/stock_production_lot.py | 23 + addons/openems/models/user.py | 37 + addons/openems/report/setup_protocol.xml | 311 +++ addons/openems/security/ir.model.access.csv | 31 + addons/openems/security/openems.xml | 54 + .../.setuptools-odoo-make-default-ignore | 2 + addons/openems/setup/README | 2 + addons/openems/static/description/icon.png | Bin 0 -> 53271 bytes addons/openems/static/mail/OpenEMS-Logo.jpg | Bin 0 -> 152320 bytes addons/openems/views/device.xml | 320 ++++ addons/openems/views/partner.xml | 28 + addons/openems/views/setup_protocol.xml | 82 + .../views/stock_production_lot_views.xml | 13 + addons/openems/views/user.xml | 25 + addons/partner_firstname/README.rst | 146 ++ addons/partner_firstname/__init__.py | 2 + addons/partner_firstname/__manifest__.py | 30 + addons/partner_firstname/exceptions.py | 12 + addons/partner_firstname/hooks.py | 9 + addons/partner_firstname/i18n/am.po | 130 ++ addons/partner_firstname/i18n/ar.po | 131 ++ addons/partner_firstname/i18n/bg.po | 130 ++ addons/partner_firstname/i18n/bs.po | 131 ++ addons/partner_firstname/i18n/ca.po | 139 ++ addons/partner_firstname/i18n/cs.po | 130 ++ addons/partner_firstname/i18n/da.po | 135 ++ addons/partner_firstname/i18n/de.po | 136 ++ addons/partner_firstname/i18n/el_GR.po | 131 ++ addons/partner_firstname/i18n/en_GB.po | 131 ++ addons/partner_firstname/i18n/es.po | 136 ++ addons/partner_firstname/i18n/es_CR.po | 131 ++ addons/partner_firstname/i18n/es_EC.po | 131 ++ addons/partner_firstname/i18n/es_MX.po | 131 ++ addons/partner_firstname/i18n/es_VE.po | 131 ++ addons/partner_firstname/i18n/et.po | 130 ++ addons/partner_firstname/i18n/eu.po | 130 ++ addons/partner_firstname/i18n/fi.po | 130 ++ addons/partner_firstname/i18n/fr.po | 138 ++ addons/partner_firstname/i18n/fr_CA.po | 131 ++ addons/partner_firstname/i18n/fr_CH.po | 131 ++ addons/partner_firstname/i18n/gl.po | 130 ++ addons/partner_firstname/i18n/hr.po | 132 ++ addons/partner_firstname/i18n/hr_HR.po | 132 ++ addons/partner_firstname/i18n/hu.po | 138 ++ addons/partner_firstname/i18n/it.po | 136 ++ addons/partner_firstname/i18n/ja.po | 130 ++ addons/partner_firstname/i18n/lt.po | 131 ++ addons/partner_firstname/i18n/lv.po | 131 ++ addons/partner_firstname/i18n/mk.po | 130 ++ addons/partner_firstname/i18n/mn.po | 130 ++ addons/partner_firstname/i18n/nb.po | 131 ++ addons/partner_firstname/i18n/nb_NO.po | 131 ++ addons/partner_firstname/i18n/nl.po | 130 ++ addons/partner_firstname/i18n/nl_BE.po | 131 ++ addons/partner_firstname/i18n/nl_NL.po | 138 ++ .../i18n/partner_firstname.pot | 124 ++ addons/partner_firstname/i18n/pl.po | 132 ++ addons/partner_firstname/i18n/pt.po | 130 ++ addons/partner_firstname/i18n/pt_BR.po | 138 ++ addons/partner_firstname/i18n/pt_PT.po | 131 ++ addons/partner_firstname/i18n/ro.po | 131 ++ addons/partner_firstname/i18n/ru.po | 132 ++ addons/partner_firstname/i18n/sk.po | 130 ++ addons/partner_firstname/i18n/sl.po | 131 ++ addons/partner_firstname/i18n/sr@latin.po | 132 ++ addons/partner_firstname/i18n/sv.po | 130 ++ addons/partner_firstname/i18n/th.po | 130 ++ addons/partner_firstname/i18n/tr.po | 130 ++ addons/partner_firstname/i18n/tr_TR.po | 131 ++ addons/partner_firstname/i18n/vi.po | 130 ++ addons/partner_firstname/i18n/zh_CN.po | 131 ++ addons/partner_firstname/i18n/zh_TW.po | 131 ++ addons/partner_firstname/models/__init__.py | 3 + .../models/base_config_settings.py | 71 + .../partner_firstname/models/res_partner.py | 270 +++ addons/partner_firstname/models/res_users.py | 49 + addons/partner_firstname/readme/CONFIGURE.rst | 14 + .../partner_firstname/readme/CONTRIBUTORS.rst | 23 + .../partner_firstname/readme/DESCRIPTION.rst | 2 + addons/partner_firstname/readme/ROADMAP.rst | 3 + addons/partner_firstname/readme/USAGE.rst | 13 + .../static/description/icon.png | Bin 0 -> 9455 bytes .../static/description/index.html | 488 +++++ addons/partner_firstname/tests/__init__.py | 12 + addons/partner_firstname/tests/base.py | 65 + .../tests/test_config_settings.py | 35 + addons/partner_firstname/tests/test_copy.py | 95 + addons/partner_firstname/tests/test_create.py | 79 + .../partner_firstname/tests/test_defaults.py | 64 + addons/partner_firstname/tests/test_delete.py | 38 + addons/partner_firstname/tests/test_empty.py | 73 + addons/partner_firstname/tests/test_name.py | 119 ++ addons/partner_firstname/tests/test_order.py | 38 + .../tests/test_partner_form.py | 106 ++ .../partner_firstname/tests/test_user_form.py | 51 + .../views/base_config_view.xml | 28 + .../partner_firstname/views/res_partner.xml | 105 ++ addons/partner_firstname/views/res_user.xml | 25 + addons/web_m2x_options/README.rst | 217 +++ addons/web_m2x_options/__init__.py | 1 + addons/web_m2x_options/__manifest__.py | 21 + addons/web_m2x_options/i18n/ar.po | 133 ++ addons/web_m2x_options/i18n/de.po | 159 ++ addons/web_m2x_options/i18n/es.po | 145 ++ addons/web_m2x_options/i18n/es_BO.po | 116 ++ addons/web_m2x_options/i18n/fi.po | 132 ++ addons/web_m2x_options/i18n/fr.po | 158 ++ addons/web_m2x_options/i18n/hr.po | 150 ++ addons/web_m2x_options/i18n/it.po | 133 ++ addons/web_m2x_options/i18n/nl.po | 162 ++ addons/web_m2x_options/i18n/nl_NL.po | 125 ++ addons/web_m2x_options/i18n/pt_BR.po | 156 ++ addons/web_m2x_options/i18n/sl.po | 133 ++ addons/web_m2x_options/i18n/tr.po | 132 ++ .../web_m2x_options/i18n/web_m2x_options.pot | 115 ++ addons/web_m2x_options/i18n/zh_CN.po | 153 ++ addons/web_m2x_options/models/__init__.py | 2 + .../models/ir_config_parameter.py | 18 + addons/web_m2x_options/models/ir_http.py | 11 + .../web_m2x_options/readme/CONTRIBUTORS.rst | 16 + addons/web_m2x_options/readme/CREDITS.rst | 1 + addons/web_m2x_options/readme/DESCRIPTION.rst | 10 + addons/web_m2x_options/readme/ROADMAP.rst | 6 + addons/web_m2x_options/readme/USAGE.rst | 95 + .../static/description/icon.png | Bin 0 -> 9455 bytes .../static/description/index.html | 412 ++++ .../static/src/components/base.xml | 46 + .../static/src/components/form.esm.js | 404 ++++ .../src/components/relational_utils.esm.js | 221 +++ addons/web_m2x_options/tests/__init__.py | 2 + .../tests/test_ir_config_parameter.py | 28 + 157 files changed, 19020 insertions(+) create mode 100644 addons/openems/.gitignore create mode 100644 addons/openems/__init__.py create mode 100644 addons/openems/__manifest__.py create mode 100644 addons/openems/controllers/__init__.py create mode 100644 addons/openems/controllers/alerting.py create mode 100644 addons/openems/controllers/const.py create mode 100644 addons/openems/controllers/openems_backend.py create mode 100644 addons/openems/controllers/setup_protocol.py create mode 100644 addons/openems/controllers/user.py create mode 100644 addons/openems/data/OpenEMS-Logo.jpg create mode 100644 addons/openems/data/demo.xml create mode 100644 addons/openems/data/ir_config_parameter.xml create mode 100644 addons/openems/data/res_partner_category.xml create mode 100644 addons/openems/i18n/de.po create mode 100644 addons/openems/i18n/openems.pot create mode 100644 addons/openems/mail/openems/alerting_offline.xml create mode 100644 addons/openems/mail/openems/alerting_sum_state.xml create mode 100644 addons/openems/mail/openems/setup_protocol_customer.xml create mode 100644 addons/openems/mail/openems/setup_protocol_installer.xml create mode 100644 addons/openems/mail/openems/user_registration.xml create mode 100644 addons/openems/migrations/16.0.1.0.1/post-migrate.py create mode 100644 addons/openems/migrations/16.0.1.0.1/pre-migrate.py create mode 100644 addons/openems/models/__init__.py create mode 100644 addons/openems/models/device.py create mode 100644 addons/openems/models/partner.py create mode 100644 addons/openems/models/setup_protocol.py create mode 100644 addons/openems/models/stock_production_lot.py create mode 100644 addons/openems/models/user.py create mode 100644 addons/openems/report/setup_protocol.xml create mode 100644 addons/openems/security/ir.model.access.csv create mode 100644 addons/openems/security/openems.xml create mode 100644 addons/openems/setup/.setuptools-odoo-make-default-ignore create mode 100644 addons/openems/setup/README create mode 100644 addons/openems/static/description/icon.png create mode 100644 addons/openems/static/mail/OpenEMS-Logo.jpg create mode 100644 addons/openems/views/device.xml create mode 100644 addons/openems/views/partner.xml create mode 100644 addons/openems/views/setup_protocol.xml create mode 100644 addons/openems/views/stock_production_lot_views.xml create mode 100644 addons/openems/views/user.xml create mode 100644 addons/partner_firstname/README.rst create mode 100644 addons/partner_firstname/__init__.py create mode 100644 addons/partner_firstname/__manifest__.py create mode 100644 addons/partner_firstname/exceptions.py create mode 100644 addons/partner_firstname/hooks.py create mode 100644 addons/partner_firstname/i18n/am.po create mode 100644 addons/partner_firstname/i18n/ar.po create mode 100644 addons/partner_firstname/i18n/bg.po create mode 100644 addons/partner_firstname/i18n/bs.po create mode 100644 addons/partner_firstname/i18n/ca.po create mode 100644 addons/partner_firstname/i18n/cs.po create mode 100644 addons/partner_firstname/i18n/da.po create mode 100644 addons/partner_firstname/i18n/de.po create mode 100644 addons/partner_firstname/i18n/el_GR.po create mode 100644 addons/partner_firstname/i18n/en_GB.po create mode 100644 addons/partner_firstname/i18n/es.po create mode 100644 addons/partner_firstname/i18n/es_CR.po create mode 100644 addons/partner_firstname/i18n/es_EC.po create mode 100644 addons/partner_firstname/i18n/es_MX.po create mode 100644 addons/partner_firstname/i18n/es_VE.po create mode 100644 addons/partner_firstname/i18n/et.po create mode 100644 addons/partner_firstname/i18n/eu.po create mode 100644 addons/partner_firstname/i18n/fi.po create mode 100644 addons/partner_firstname/i18n/fr.po create mode 100644 addons/partner_firstname/i18n/fr_CA.po create mode 100644 addons/partner_firstname/i18n/fr_CH.po create mode 100644 addons/partner_firstname/i18n/gl.po create mode 100644 addons/partner_firstname/i18n/hr.po create mode 100644 addons/partner_firstname/i18n/hr_HR.po create mode 100644 addons/partner_firstname/i18n/hu.po create mode 100644 addons/partner_firstname/i18n/it.po create mode 100644 addons/partner_firstname/i18n/ja.po create mode 100644 addons/partner_firstname/i18n/lt.po create mode 100644 addons/partner_firstname/i18n/lv.po create mode 100644 addons/partner_firstname/i18n/mk.po create mode 100644 addons/partner_firstname/i18n/mn.po create mode 100644 addons/partner_firstname/i18n/nb.po create mode 100644 addons/partner_firstname/i18n/nb_NO.po create mode 100644 addons/partner_firstname/i18n/nl.po create mode 100644 addons/partner_firstname/i18n/nl_BE.po create mode 100644 addons/partner_firstname/i18n/nl_NL.po create mode 100644 addons/partner_firstname/i18n/partner_firstname.pot create mode 100644 addons/partner_firstname/i18n/pl.po create mode 100644 addons/partner_firstname/i18n/pt.po create mode 100644 addons/partner_firstname/i18n/pt_BR.po create mode 100644 addons/partner_firstname/i18n/pt_PT.po create mode 100644 addons/partner_firstname/i18n/ro.po create mode 100644 addons/partner_firstname/i18n/ru.po create mode 100644 addons/partner_firstname/i18n/sk.po create mode 100644 addons/partner_firstname/i18n/sl.po create mode 100644 addons/partner_firstname/i18n/sr@latin.po create mode 100644 addons/partner_firstname/i18n/sv.po create mode 100644 addons/partner_firstname/i18n/th.po create mode 100644 addons/partner_firstname/i18n/tr.po create mode 100644 addons/partner_firstname/i18n/tr_TR.po create mode 100644 addons/partner_firstname/i18n/vi.po create mode 100644 addons/partner_firstname/i18n/zh_CN.po create mode 100644 addons/partner_firstname/i18n/zh_TW.po create mode 100644 addons/partner_firstname/models/__init__.py create mode 100644 addons/partner_firstname/models/base_config_settings.py create mode 100644 addons/partner_firstname/models/res_partner.py create mode 100644 addons/partner_firstname/models/res_users.py create mode 100644 addons/partner_firstname/readme/CONFIGURE.rst create mode 100644 addons/partner_firstname/readme/CONTRIBUTORS.rst create mode 100644 addons/partner_firstname/readme/DESCRIPTION.rst create mode 100644 addons/partner_firstname/readme/ROADMAP.rst create mode 100644 addons/partner_firstname/readme/USAGE.rst create mode 100644 addons/partner_firstname/static/description/icon.png create mode 100644 addons/partner_firstname/static/description/index.html create mode 100644 addons/partner_firstname/tests/__init__.py create mode 100644 addons/partner_firstname/tests/base.py create mode 100644 addons/partner_firstname/tests/test_config_settings.py create mode 100644 addons/partner_firstname/tests/test_copy.py create mode 100644 addons/partner_firstname/tests/test_create.py create mode 100644 addons/partner_firstname/tests/test_defaults.py create mode 100644 addons/partner_firstname/tests/test_delete.py create mode 100644 addons/partner_firstname/tests/test_empty.py create mode 100644 addons/partner_firstname/tests/test_name.py create mode 100644 addons/partner_firstname/tests/test_order.py create mode 100644 addons/partner_firstname/tests/test_partner_form.py create mode 100644 addons/partner_firstname/tests/test_user_form.py create mode 100644 addons/partner_firstname/views/base_config_view.xml create mode 100644 addons/partner_firstname/views/res_partner.xml create mode 100644 addons/partner_firstname/views/res_user.xml create mode 100644 addons/web_m2x_options/README.rst create mode 100644 addons/web_m2x_options/__init__.py create mode 100644 addons/web_m2x_options/__manifest__.py create mode 100644 addons/web_m2x_options/i18n/ar.po create mode 100644 addons/web_m2x_options/i18n/de.po create mode 100644 addons/web_m2x_options/i18n/es.po create mode 100644 addons/web_m2x_options/i18n/es_BO.po create mode 100644 addons/web_m2x_options/i18n/fi.po create mode 100644 addons/web_m2x_options/i18n/fr.po create mode 100644 addons/web_m2x_options/i18n/hr.po create mode 100644 addons/web_m2x_options/i18n/it.po create mode 100644 addons/web_m2x_options/i18n/nl.po create mode 100644 addons/web_m2x_options/i18n/nl_NL.po create mode 100644 addons/web_m2x_options/i18n/pt_BR.po create mode 100644 addons/web_m2x_options/i18n/sl.po create mode 100644 addons/web_m2x_options/i18n/tr.po create mode 100644 addons/web_m2x_options/i18n/web_m2x_options.pot create mode 100644 addons/web_m2x_options/i18n/zh_CN.po create mode 100644 addons/web_m2x_options/models/__init__.py create mode 100644 addons/web_m2x_options/models/ir_config_parameter.py create mode 100644 addons/web_m2x_options/models/ir_http.py create mode 100644 addons/web_m2x_options/readme/CONTRIBUTORS.rst create mode 100644 addons/web_m2x_options/readme/CREDITS.rst create mode 100644 addons/web_m2x_options/readme/DESCRIPTION.rst create mode 100644 addons/web_m2x_options/readme/ROADMAP.rst create mode 100644 addons/web_m2x_options/readme/USAGE.rst create mode 100644 addons/web_m2x_options/static/description/icon.png create mode 100644 addons/web_m2x_options/static/description/index.html create mode 100644 addons/web_m2x_options/static/src/components/base.xml create mode 100644 addons/web_m2x_options/static/src/components/form.esm.js create mode 100644 addons/web_m2x_options/static/src/components/relational_utils.esm.js create mode 100644 addons/web_m2x_options/tests/__init__.py create mode 100644 addons/web_m2x_options/tests/test_ir_config_parameter.py diff --git a/addons/openems/.gitignore b/addons/openems/.gitignore new file mode 100644 index 0000000..e41d5e2 --- /dev/null +++ b/addons/openems/.gitignore @@ -0,0 +1,3 @@ +.swp +.swo +**/__pycache__ diff --git a/addons/openems/__init__.py b/addons/openems/__init__.py new file mode 100644 index 0000000..72d3ea6 --- /dev/null +++ b/addons/openems/__init__.py @@ -0,0 +1 @@ +from . import controllers, models diff --git a/addons/openems/__manifest__.py b/addons/openems/__manifest__.py new file mode 100644 index 0000000..232ebf1 --- /dev/null +++ b/addons/openems/__manifest__.py @@ -0,0 +1,40 @@ +{ + "name": "OpenEMS", + "summary": "Everything related to OpenEMS (Open Energy Management System)", + "version": "16.0.1.0.1", + "author": "OpenEMS Association e.V.", + "maintainer": "OpenEMS Association e.V.", + "contributors": [ + "Stefan Feilmeier " + "Maximilian Lang " + ], + "website": "https://openems.io", + "license": "AGPL-3", + "category": "Specific Industry Applications", + "depends": ["base", "web", "mail", "crm", "resource", "stock", "web_m2x_options", "partner_firstname"], + "data": [ + "data/ir_config_parameter.xml", + "data/res_partner_category.xml", + "security/openems.xml", + "security/ir.model.access.csv", + "report/setup_protocol.xml", + "views/device.xml", + "views/partner.xml", + "views/setup_protocol.xml", + "views/user.xml", + "views/stock_production_lot_views.xml", + "mail/openems/alerting_offline.xml", + "mail/openems/alerting_sum_state.xml", + "mail/openems/setup_protocol_customer.xml", + "mail/openems/setup_protocol_installer.xml", + "mail/openems/user_registration.xml", + ], + "demo": ["data/demo.xml"], + "js": [], + "css": [], + "qweb": [], + "images": [], + "test": [], + "installable": True, + "application": True, +} diff --git a/addons/openems/controllers/__init__.py b/addons/openems/controllers/__init__.py new file mode 100644 index 0000000..3e863cd --- /dev/null +++ b/addons/openems/controllers/__init__.py @@ -0,0 +1 @@ +from . import openems_backend, setup_protocol, user, alerting diff --git a/addons/openems/controllers/alerting.py b/addons/openems/controllers/alerting.py new file mode 100644 index 0000000..7a848f2 --- /dev/null +++ b/addons/openems/controllers/alerting.py @@ -0,0 +1,86 @@ +import logging +from datetime import datetime +from enum import Enum + +from odoo import http +from odoo.http import request + +class SumState(Enum): + FAULT = 0 + WARNING = 1 + +class Message: + sentAt: datetime + edgeId: str + userIds: list[int] + + def __init__(self, sentAt: datetime, edgeId: str, userIds: list[int]) -> None: + self.sentAt = sentAt + self.edgeId = edgeId + self.userIds = userIds + +class SumStateMessage(Message): + state: SumState + + def __init__(self, sentAt: datetime, edgeId: str, userIds: list[int], state: SumState) -> None: + super().__init__(sentAt, edgeId, userIds) + self.state = state + +class Alerting(http.Controller): + __logger = logging.getLogger("Alerting") + + @http.route("/openems_backend/mail/alerting_sum_state", type="json", auth="user") + def sum_state_alerting(self, sentAt: str, params: list[dict]): + msgs = self.__get_sum_state_params(sentAt, params) + update_func = lambda role, at: { role.write({"sum_state_last_notification": at})} + + if len(msgs) == 0: + self.__logger.error("Scheduled SumState-Alerting-Mail without any recipients!!!") + + template = request.env.ref('openems.alerting_sum_state') + for msg in msgs: + self.__send_mails(template, msg, update_func) + + return {} + + @http.route("/openems_backend/mail/alerting_offline", type="json", auth="user") + def offline_alerting(self, sentAt: str, params: list[dict]): + msgs = self.__get_offline_params(sentAt, params) + update_func = lambda role, at: { role.write({"offline_last_notification": at})} + + template = request.env.ref("openems.alerting_offline") + for msg in msgs: + self.__send_mails(template, msg, update_func) + + return {} + + def __get_offline_params(self, sentAt, params) -> list[Message]: + msgs = list() + sent = datetime.strptime(sentAt, "%Y-%m-%d %H:%M:%S") + for param in params: + edgeId = param["edgeId"] + recipients = param["recipients"] + msgs.append(Message(sent, edgeId, recipients)); + return msgs + + def __get_sum_state_params(self, sentAt, params) -> list[SumStateMessage]: + msgs = list() + sent = datetime.strptime(sentAt, "%Y-%m-%d %H:%M:%S") + for param in params: + edgeId = param["edgeId"] + recipients = param["recipients"] + state = param["state"] + msgs.append(SumStateMessage(sent, edgeId, recipients, state)); + return msgs + + def __send_mails(self, template, msg: Message, update_func): + roles = http.request.env['openems.alerting'].search( + [('user_id','in',msg.userIds),('device_id','=',msg.edgeId)] + ) + + for role in roles: + try: + template.send_mail(res_id=role.id, force_send=True) + update_func(role, msg.sentAt) + except Exception as err: + self.__logger.error("[" + str(err) + "] Unable to send template[" + str(template.name) +"] to edgeUser[user=" + str(role.id) + ", edge=" + str(msg.edgeId)+ "]") \ No newline at end of file diff --git a/addons/openems/controllers/const.py b/addons/openems/controllers/const.py new file mode 100644 index 0000000..c6fbc01 --- /dev/null +++ b/addons/openems/controllers/const.py @@ -0,0 +1,5 @@ +from odoo.modules.module import get_module_resource + +import base64 + +OPENEMS_LOGO_BASE64 = base64.b64encode(open(get_module_resource('openems', 'data', 'OpenEMS-Logo.jpg') , "rb").read()) \ No newline at end of file diff --git a/addons/openems/controllers/openems_backend.py b/addons/openems/controllers/openems_backend.py new file mode 100644 index 0000000..d0dcb80 --- /dev/null +++ b/addons/openems/controllers/openems_backend.py @@ -0,0 +1,276 @@ +from odoo import http + + +class OpenemsBackend(http.Controller): + @http.route("/openems_backend/info", auth="user", type="json") + def index(self): + # Get user + user_id = http.request.env.context.get("uid") + res_users = http.request.env["res.users"].sudo() + user_rec = res_users.search_read( + [("id", "=", user_id)], + ["login", "name", "groups_id", "global_role", "openems_language"], + )[0] + res_users.browse([user_id]) + + # Get res group model + res_groups_model = http.request.env["res.groups"].sudo() + + # Get Manager and Reader group + manager_group = res_groups_model.env.ref("openems.group_openems_manager") + reader_group = res_groups_model.env.ref("openems.group_openems_reader") + + manager_group_id = manager_group["id"] + reader_group_id = reader_group["id"] + + # Get user attributes + global_role = user_rec["global_role"] + if manager_group_id in user_rec["groups_id"]: + # Manager group + global_role = "admin" + + # return empty device (use pagination) list if user is manager or reader + if manager_group_id in user_rec["groups_id"] or reader_group_id in user_rec["groups_id"]: + return { + "user": { + "id": user_rec["id"], + "login": user_rec["login"], + "name": user_rec["name"], + "global_role": global_role, + "language": user_rec["openems_language"], + "has_multiple_edges": True + }, + "devices": [], + } + + # Get specific Device roles + device_user_role_model = http.request.env["openems.device_user_role"] + user_role_ids = device_user_role_model.search_read( + [("user_id", "=", user_id)], ["id", "role"] + ) + + # Get Devices + device_model = http.request.env["openems.device"] + devices = device_model.search_read( + [], ["id", "name", "user_role_ids", "comment", "producttype", + "lastmessage", "first_setup_protocol_date", "openems_sum_state_level"] + ) + + devs = [] + for device_rec in devices: + # Set user role per group + role = "guest" + if manager_group_id in user_rec["groups_id"]: + # Manager group + role = "admin" + elif reader_group_id in user_rec["groups_id"]: + # Reader group + role = "guest" + + # Set specific user role + for device_role_id in device_rec["user_role_ids"]: + for user_role_id in user_role_ids: + if device_role_id == user_role_id["id"]: + role = user_role_id["role"] + + # Prepare result + dev = { + "id": device_rec["id"], + "name": device_rec["name"], + "comment": device_rec["comment"], + "producttype": device_rec["producttype"], + "role": role, + "lastmessage": device_rec["lastmessage"], + "openems_sum_state_level": device_rec["openems_sum_state_level"] + } + + if device_rec["first_setup_protocol_date"]: + dev["first_setup_protocol_date"] = device_rec[ + "first_setup_protocol_date" + ] + + devs.append(dev) + + return { + "user": { + "id": user_rec["id"], + "login": user_rec["login"], + "name": user_rec["name"], + "global_role": global_role, + "language": user_rec["openems_language"], + "has_multiple_edges": len(devs) > 1 + }, + "devices": devs, + } + + @http.route("/openems_backend/get_edge_with_role", auth="user", type="json") + def get_edge_with_role(self, edge_id: str): + user_id = http.request.env.context.get("uid") + res_users = http.request.env["res.users"].sudo() + user_rec = res_users.search_read( + [("id", "=", user_id)], + ["login", "name", "groups_id"], + )[0] + + # Get res group model + res_groups_model = http.request.env["res.groups"].sudo() + + # Get Manager and Reader group + manager_group = res_groups_model.env.ref("openems.group_openems_manager") + reader_group = res_groups_model.env.ref("openems.group_openems_reader") + + manager_group_id = manager_group["id"] + reader_group_id = reader_group["id"] + + # get devices for which the user has permissions + device_model = http.request.env["openems.device"] + devices = device_model.search_read( + [("name", "=", edge_id)], + ["id", "name", "comment", "producttype", "lastmessage", "first_setup_protocol_date", "openems_sum_state_level"]) + + if len(devices) != 1: + return {} + + device = devices[0] + + # Get specific Device roles + device_user_role_model = http.request.env["openems.device_user_role"] + device_user_roles = device_user_role_model.search_read( + [("user_id", "=", user_id), + ("device_id", "=", device["id"])], ["id", "role"] + ) + + # Set user role per group + role = "guest" + if manager_group_id in user_rec["groups_id"]: + # Manager group + role = "admin" + elif reader_group_id in user_rec["groups_id"]: + # Reader group + role = "guest" + + # Set specific user role + if len(device_user_roles) > 0: + role = device_user_roles[0]["role"] + + dev = { + "id": device["id"], + "name": device["name"], + "comment": device["comment"], + "producttype": device["producttype"], + "role": role, + "lastmessage": device["lastmessage"], + "openems_sum_state_level": device["openems_sum_state_level"] + } + if device["first_setup_protocol_date"]: + dev["first_setup_protocol_date"] = device["first_setup_protocol_date"] + + return dev + + @http.route("/openems_backend/get_edges", auth="user", type="json") + def get_edges(self, limit, page, query=None, searchParams=None): + # Get user + user_id = http.request.env.context.get("uid") + res_users = http.request.env["res.users"].sudo() + user_rec = res_users.search_read( + [("id", "=", user_id)], + ["login", "name", "groups_id", "global_role"], + )[0] + + # Get res group model + res_groups_model = http.request.env["res.groups"].sudo() + + # Get Manager and Reader group + manager_group = res_groups_model.env.ref("openems.group_openems_manager") + reader_group = res_groups_model.env.ref("openems.group_openems_reader") + + manager_group_id = manager_group["id"] + reader_group_id = reader_group["id"] + + # Get specific Device roles + device_user_role_model = http.request.env["openems.device_user_role"] + user_role_ids = device_user_role_model.search_read( + [("user_id", "=", user_id)], ["id", "role"] + ) + + domains = [] + logical_operators = [] + additional_domains = [] + if query: + logical_operators.extend(['|', '|']) + domains = [ + ("name", "ilike", query), + ("comment", "ilike", query), + ("producttype", "ilike", query)] + + if searchParams: + if searchParams.get("producttype"): + additional_domains.append( + ("producttype", "in", searchParams.get("producttype"))) + + if searchParams.get("sumState"): + sum_states = list(map(lambda s: s.lower(), searchParams.get("sumState"))) + additional_domains.append( + ("openems_sum_state_level", "in", sum_states)) + + if "isOnline" in searchParams: + additional_domains.append( + ("openems_is_connected", "=", searchParams.get("isOnline"))) + + if len(additional_domains) > 1: + for _ in range(len(additional_domains) - 1): + logical_operators.insert(0, '&') + + # insert 'and' if both are not 'None' + if query and searchParams: + logical_operators.insert(0, '&') + + domains.extend(additional_domains) + logical_operators.extend(domains) + + # Get Devices + device_model = http.request.env["openems.device"] + devices = device_model.search_read( + logical_operators, + ["id", "name", "user_role_ids", "comment", "producttype", + "lastmessage", "first_setup_protocol_date", "openems_sum_state_level"], + limit=limit, offset=(page * limit) + ) + devs = [] + for device_rec in devices: + # Set user role per group + role = "guest" + if manager_group_id in user_rec["groups_id"]: + # Manager group + role = "admin" + elif reader_group_id in user_rec["groups_id"]: + # Reader group + role = "guest" + + # Set specific user role + for device_role_id in device_rec["user_role_ids"]: + for user_role_id in user_role_ids: + if device_role_id == user_role_id["id"]: + role = user_role_id["role"] + + # Prepare result + dev = { + "id": device_rec["id"], + "name": device_rec["name"], + "comment": device_rec["comment"], + "producttype": device_rec["producttype"], + "role": role, + "lastmessage": device_rec["lastmessage"], + "openems_sum_state_level": device_rec["openems_sum_state_level"] + } + + if device_rec["first_setup_protocol_date"]: + dev["first_setup_protocol_date"] = device_rec[ + "first_setup_protocol_date" + ] + + devs.append(dev) + + return { + "devices": devs, + } diff --git a/addons/openems/controllers/setup_protocol.py b/addons/openems/controllers/setup_protocol.py new file mode 100644 index 0000000..d64b18e --- /dev/null +++ b/addons/openems/controllers/setup_protocol.py @@ -0,0 +1,142 @@ +import base64 + +from odoo import http +from odoo.http import request + + +class SetupProtocol(http.Controller): + @http.route("/openems_backend/sendSetupProtocolEmail", type="json", auth="user") + def index(self, setupProtocolId, edgeId): + setup_protocol_model = request.env["openems.setup_protocol"] + setup_protocol_record = setup_protocol_model.search_read( + [("id", "=", setupProtocolId)] + ) + if len(setup_protocol_record) != 1: + raise ValueError("Setup protocol not found for id [" + edgeId + "]") + + device_model = request.env["openems.device"] + device_rec = device_model.search_read([("name", "=", edgeId)]) + if len(device_rec) != 1: + raise ValueError("Device not found for id [" + edgeId + "]") + + name = ( + "IBN-" + + edgeId + + "-" + + setup_protocol_record[0]["create_date"].strftime("%d.%m.%Y") + + ".pdf" + ) + + data = request.env.ref( + "openems.action_openems_setup_protocol_report" + )._render_qweb_pdf([setupProtocolId]) + ibnPdf = request.env["ir.attachment"].create( + { + "res_model": "openems.device", + "res_id": device_rec[0]["id"], + "name": name, + "store_fname": name, + "datas": base64.b64encode(data[0]), + } + ) + + templates = self.getTemplates(device_rec[0]['oem'], ibnPdf) + + templates['installer'].send_mail(setupProtocolId, force_send=True) + templates['customer'].send_mail(setupProtocolId, force_send=True) + + return {} + + def getTemplates(self, oem: str, protocol): + templates = {'customer': None, 'installer': None} + + templates['customer'] = request.env.ref( + "openems.setup_protocol_email_customer") + templates['installer'] = request.env.ref( + "openems.setup_protocol_email_installer") + + logo = request.env.ref("openems.attachment_logo_openems") + + templates['customer'].attachment_ids = [ + (6, 0, [protocol.id, logo.id])] + templates['installer'].attachment_ids = [ + (6, 0, [protocol.id, logo.id])] + + return templates + + @http.route('/openems_backend/get_latest_setup_protocol', type='json', auth='user') + def get_latest_setup_protocol(self, edge_name): + # search for device + device_model = request.env['openems.device'] + device = device_model.search([('name', '=', edge_name)]) + + response = dict() + if not len(device.setup_protocol_ids) > 0: + return response + + latest_protocol = device.setup_protocol_ids[0] + + # build customer object + customer = latest_protocol.customer_id + customer_values = dict({ + "firstname": customer['firstname'], + "lastname": customer['lastname'], + "email": customer['email'], + "phone": customer['phone'], + "address": { + "street": customer['street'], + "city": customer['city'], + "zip": customer['zip'], + "country": customer['country_id']['name'] + } + }) + + # check company for customer + customer_company = customer['commercial_company_name'] + if customer_company: + customer_values.update({ + "company": { + "name": customer['commercial_company_name'] + } + }) + response.update({"customer": customer_values}) + + # check different location is available + location = latest_protocol['different_location_id'] + if location: + location_values = dict({ + "firstname": location['firstname'], + "lastname": location['lastname'], + "email": location['email'], + "phone": location['phone'], + "address": { + "street": location['street'], + "city": location['city'], + "zip": location['zip'], + "country": location['country_id']['name'] + } + }) + + # check company for different location + different_location_company = location['commercial_company_name'] + if different_location_company: + location_values.update({ + "company": { + "name": location['commercial_company_name'] + } + }) + response.update({"location": location_values}) + + # build items object + items = list() + for item in latest_protocol.item_ids: + items.append({ + "view": item['view'], + "field": item['field'], + "category": item['category'], + "name": item['name'], + "value": item['value'] + }) + response.update({"items": items}) + + return response diff --git a/addons/openems/controllers/user.py b/addons/openems/controllers/user.py new file mode 100644 index 0000000..75ec137 --- /dev/null +++ b/addons/openems/controllers/user.py @@ -0,0 +1,32 @@ +from odoo import http +from odoo.http import request + +class User(http.Controller): + @http.route("/openems_backend/sendRegistrationEmail", type="json", auth="user") + def index(self, userId, password=None, oem: str = ''): + user_model = request.env["res.users"] + user_record = user_model.search_read([("id", "=", userId)], ["partner_id"]) + if len(user_record) != 1: + raise ValueError("User not found for id [" + userId + "]") + + partner = user_record[0] + partner_id = partner.get("partner_id") + if partner_id is None: + raise ValueError("User has no partner") + + if password is None: + password = "*****" + # load template + template = self.getTemplate(oem) + # set mail values + email_values = { + 'password': password + } + # send mail + template.with_context(email_values).send_mail( + res_id=partner_id[0], force_send=True) + return {} + + def getTemplate(self, oem: str): + template = request.env.ref("openems.registration_email") + return template diff --git a/addons/openems/data/OpenEMS-Logo.jpg b/addons/openems/data/OpenEMS-Logo.jpg new file mode 100644 index 0000000000000000000000000000000000000000..13ae0fba6120a7472998decceef335398be01035 GIT binary patch literal 152320 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

`b%zWJVoybJJC+al7(vmUoDSw-d(zU?;>j| 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 + + + + + edge0 + OpenEMS Edge #0 + DEMO_API_KEY + + + + diff --git a/addons/openems/data/ir_config_parameter.xml b/addons/openems/data/ir_config_parameter.xml new file mode 100644 index 0000000..b1da5cf --- /dev/null +++ b/addons/openems/data/ir_config_parameter.xml @@ -0,0 +1,9 @@ + + + + + edge_monitoring_url + http://localhost:8082/device/ + + + diff --git a/addons/openems/data/res_partner_category.xml b/addons/openems/data/res_partner_category.xml new file mode 100644 index 0000000..f56c0e0 --- /dev/null +++ b/addons/openems/data/res_partner_category.xml @@ -0,0 +1,11 @@ + + + + + Created via IBN + + + Customer + + + diff --git a/addons/openems/i18n/de.po b/addons/openems/i18n/de.po new file mode 100644 index 0000000..cc4c660 --- /dev/null +++ b/addons/openems/i18n/de.po @@ -0,0 +1,1666 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * openems +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 16.0-20240218\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2024-02-18 11:57+0000\n" +"PO-Revision-Date: 2024-02-18 11:57+0000\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: openems +#: model:mail.template,body_html:openems.setup_protocol_email_installer +msgid "" +"\n" +"\n" +"\n" +"\n" +"\n" +" OpenEMS setup protocol \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +"\n" +"\n" +"\n" +"

\n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +"
\n" +" \n" +"
\n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +"
\n" +" \n" +"
\n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +"
\n" +"

\n" +"

\n" +" \n" +"
\n" +"
Dear \n" +" ,\n" +"
\n" +"
\n" +"
please find the setup protocol for your customer attached.\n" +"
\n" +"
\n" +"
Best Regards
\n" +"
\n" +"
OpenEMS Association e.V.
\n" +"
\n" +"
\n" +" \n" +"
\n" +"
\n" +" \n" +"
\n" +"
\n" +"\n" +"\n" +"\n" +" \n" +" " +msgstr "" + +#. module: openems +#: model:mail.template,body_html:openems.registration_email +msgid "" +"\n" +"\n" +"\n" +"\n" +"\n" +" Registrierung erfolgreich \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +"\n" +"\n" +"\n" +"
\n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +"
\n" +" \n" +"
\n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +"
\n" +" \n" +"
\n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +"
\n" +"

\n" +"

\n" +" \n" +"
\n" +"
Guten Tag \n" +" ,\n" +"
\n" +"
\n" +"
Ihr Zugang zu OpenEMS UI wurde erstellt.
\n" +"
\n" +"
Sie können sich auf OpenEMS UI einloggen, um auf das Online-Monitoring zuzugreifen.
\n" +"
\n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +"
Ihre Zugangsdaten:
E-Mail\n" +" \n" +"
Passwort\n" +" \n" +"
\n" +"
\n" +"
Best Regards
\n" +"
\n" +"
OpenEMS Association e.V.
\n" +"
\n" +"
\n" +" \n" +"
\n" +"
\n" +" \n" +"
\n" +"
\n" +"\n" +"\n" +"\n" +" \n" +" " +msgstr "" + +#. module: openems +#: model:mail.template,body_html:openems.setup_protocol_email_customer +msgid "" +"\n" +"\n" +"\n" +"\n" +"\n" +" Your OpenEMS Edge setup protocol \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +"\n" +"\n" +"\n" +"
\n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +"
\n" +" \n" +"
\n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +"
\n" +" \n" +"
\n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +"
\n" +"

\n" +"

\n" +" \n" +"
\n" +"
Welcome to OpenEMS,
\n" +"
\n" +"
please find your setup protocol for OpenEMS Edge attached.
\n" +"
\n" +"
Best Regards
\n" +"
\n" +"
OpenEMS Association e.V.
\n" +"
\n" +"
\n" +" \n" +"
\n" +"
\n" +" \n" +"
\n" +"
\n" +"\n" +"\n" +"\n" +" \n" +" " +msgstr "" + +#. module: openems +#: model:mail.template,body_html:openems.alerting_email_generic +msgid "" +"\n" +"\n" +"\n" +"\n" +"\n" +" OpenEMS Alert - Edge is offline\n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +"\n" +"\n" +"\n" +"
\n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +"
\n" +" \n" +"
\n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +"
\n" +" \n" +"
\n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +"
\n" +"

\n" +"

\n" +" \n" +"
\n" +"
Dear \n" +" ,\n" +"
\n" +"
\n" +"
Your OpenEMS Edge with number is offline since:
\n" +"
\n" +"
\n" +" \n" +" \n" +" \n" +" \n" +" \n" +" (UTC)\n" +" \n" +"
\n" +"
\n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +"
Info
\n" +" Edge-Version\n" +" \n" +" \n" +"
\n" +" Type\n" +" \n" +" \n" +" \n" +"
\n" +"
\n" +"
Best Regards
\n" +"
\n" +"
OpenEMS Association e.V.
\n" +"
\n" +"
\n" +" \n" +"
\n" +"
\n" +" \n" +"
\n" +" \n" +"
\n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +"
\n" +" \n" +"
\n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +"
\n" +"
Wenn Sie keine E-Mail Benachrichtigung mehr wünschen, können Sie die Funktion hier deaktivieren.
\n" +"
\n" +"
Dies ist eine automatisch generierte Nachricht. Bitte antworten Sie nicht auf diese Nachricht!
\n" +"
\n" +"
\n" +" \n" +"
\n" +"
\n" +" \n" +"
\n" +"\n" +"\n" +"\n" +" \n" +" " +msgstr "" + +#. module: openems +#: model:ir.actions.report,print_report_name:openems.action_openems_setup_protocol_report +msgid "" +"('IBN-' + object.openems_device_id.name + '-' + " +"object.create_date.strftime('%d.%m.%Y'))" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__apikey +msgid "API-Key" +msgstr "" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.openems_device_form +msgid "Access Role in Online-Monitoring" +msgstr "Zugriffsrollen im Online-Monitoring" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__message_needaction +msgid "Action Needed" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__active +msgid "Active" +msgstr "" + +#. module: openems +#: model:ir.model.fields.selection,name:openems.selection__openems_device_user_role__role__admin +#: model:ir.model.fields.selection,name:openems.selection__res_users__global_role__admin +msgid "Admin" +msgstr "" + +#. module: openems +#: model:ir.ui.menu,name:openems.menu_openems_admin +msgid "Administration" +msgstr "" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.device_search_view +msgid "Archived" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__message_attachment_count +msgid "Attachment Count" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_res_users__branding_partner_id +msgid "Branding Partner" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol_item__category +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol_production_lot__category +msgid "Category" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__comment +msgid "Comment" +msgstr "" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.openems_device_form +msgid "Configuration" +msgstr "Konfiguration" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.openems_device_form +msgid "Configuration Updates" +msgstr "Konfigurationsänderungen" + +#. module: openems +#: model:ir.model,name:openems.model_res_partner +msgid "Contact" +msgstr "Kontakt" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__create_uid +#: model:ir.model.fields,field_description:openems.field_openems_device_tag__create_uid +#: model:ir.model.fields,field_description:openems.field_openems_device_user_role__create_uid +#: model:ir.model.fields,field_description:openems.field_openems_openemsconfigupdate__create_uid +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol__create_uid +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol_item__create_uid +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol_production_lot__create_uid +#: model:ir.model.fields,field_description:openems.field_openems_systemmessage__create_uid +msgid "Created by" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__create_date +#: model:ir.model.fields,field_description:openems.field_openems_device_tag__create_date +#: model:ir.model.fields,field_description:openems.field_openems_device_user_role__create_date +#: model:ir.model.fields,field_description:openems.field_openems_openemsconfigupdate__create_date +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol__create_date +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol_item__create_date +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol_production_lot__create_date +#: model:ir.model.fields,field_description:openems.field_openems_systemmessage__create_date +msgid "Created on" +msgstr "" + +#. module: openems +#: model:res.partner.category,name:openems.res_partner_category_created_via_ibn +msgid "Created via IBN" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_systemmessage__timestamp +msgid "Creation date" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol__customer_id +#: model:res.partner.category,name:openems.res_partner_category_customer +msgid "Customer" +msgstr "" + +#. module: openems +#: model:ir.model.fields.selection,name:openems.selection__res_users__openems_language__cz +msgid "Czech" +msgstr "" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.report_openems_setup_protocol_template +msgid "Datum:" +msgstr "" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.device_search_view +#: model_terms:ir.ui.view,arch_db:openems.openems_device_tree +msgid "Description" +msgstr "Bezeichnung" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.openems_openemsconfigupdate_tree +msgid "Details" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_stock_lot__device_id +#: model:ir.model.fields,field_description:openems.field_stock_lot__device_ids +msgid "Device" +msgstr "" + +#. module: openems +#: model:ir.actions.act_window,name:openems.action_openems_openemsconfigupdate +#: model:ir.ui.menu,name:openems.menu_openems_admin_openemsconfigupdate +msgid "Device Configuration Updates" +msgstr "" + +#. module: openems +#: model:ir.actions.act_window,name:openems.action_openems_device +#: model:ir.ui.menu,name:openems.menu_openems_content_devices +msgid "Devices" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol__different_location_id +msgid "Different Location" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__display_name +#: model:ir.model.fields,field_description:openems.field_openems_device_tag__display_name +#: model:ir.model.fields,field_description:openems.field_openems_device_user_role__display_name +#: model:ir.model.fields,field_description:openems.field_openems_openemsconfigupdate__display_name +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol__display_name +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol_item__display_name +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol_production_lot__display_name +#: model:ir.model.fields,field_description:openems.field_openems_systemmessage__display_name +msgid "Display Name" +msgstr "" + +#. module: openems +#: model:ir.model.fields.selection,name:openems.selection__res_users__openems_language__nl +msgid "Dutch" +msgstr "" + +#. module: openems +#: model:mail.template,name:openems.alerting_email_generic +msgid "E-Mail Alerting" +msgstr "" + +#. module: openems +#: model:mail.template,name:openems.registration_email +msgid "E-Mail Kunden Registrierung" +msgstr "" + +#. module: openems +#: model:mail.template,name:openems.setup_protocol_email_customer +msgid "E-Mail setup protocol for customer" +msgstr "" + +#. module: openems +#: model:mail.template,name:openems.setup_protocol_email_installer +msgid "E-Mail setup protocol for installer" +msgstr "" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.report_openems_setup_protocol_template +msgid "E-Mail-Adresse" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__emshardware +msgid "EMS Hardware" +msgstr "" + +#. module: openems +#: model:ir.model.fields.selection,name:openems.selection__res_users__openems_language__en +msgid "English" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol__item_ids +msgid "Entry Items" +msgstr "" + +#. module: openems +#: model:ir.model.fields.selection,name:openems.selection__openems_device__openems_sum_state_level__fault +msgid "Fault" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol_item__field +msgid "Field Identifier" +msgstr "" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.report_openems_setup_protocol_template +msgid "Firmenname" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__first_setup_protocol_date +msgid "First Setup Protocol Date" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__message_follower_ids +msgid "Followers" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__message_partner_ids +msgid "Followers (Partners)" +msgstr "" + +#. module: openems +#: model:ir.model.fields.selection,name:openems.selection__res_users__openems_language__fr +msgid "French" +msgstr "" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.openems_device_form +msgid "General" +msgstr "" + +#. module: openems +#: model:ir.model.fields.selection,name:openems.selection__res_users__openems_language__de +msgid "German" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_res_users__global_role +msgid "Global Role" +msgstr "" + +#. module: openems +#: model:ir.model.fields.selection,name:openems.selection__openems_device_user_role__role__guest +#: model:ir.model.fields.selection,name:openems.selection__res_users__global_role__guest +msgid "Guest" +msgstr "" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.openems_device_form +msgid "Hardware" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__has_message +msgid "Has Message" +msgstr "" + +#. module: openems +#: model:ir.model.fields.selection,name:openems.selection__res_users__openems_language__hu +msgid "Hungarian" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__id +#: model:ir.model.fields,field_description:openems.field_openems_device_tag__id +#: model:ir.model.fields,field_description:openems.field_openems_device_user_role__id +#: model:ir.model.fields,field_description:openems.field_openems_openemsconfigupdate__id +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol__id +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol_item__id +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol_production_lot__id +#: model:ir.model.fields,field_description:openems.field_openems_systemmessage__id +msgid "ID" +msgstr "" + +#. module: openems +#: model:ir.model.fields,help:openems.field_openems_device__message_needaction +msgid "If checked, new messages require your attention." +msgstr "" + +#. module: openems +#: model:ir.model.fields,help:openems.field_openems_device__message_has_error +#: model:ir.model.fields,help:openems.field_openems_device__message_has_sms_error +msgid "If checked, some messages have a delivery error." +msgstr "" + +#. module: openems +#: model:ir.model.fields.selection,name:openems.selection__openems_device__openems_sum_state_level__info +msgid "Info" +msgstr "" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.report_openems_setup_protocol_template +msgid "Installateur" +msgstr "" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.openems_device_form +msgid "Installation" +msgstr "Inbetriebnahme" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.openems_device_form +msgid "Installation Log" +msgstr "Inbetriebnahme Protokolle" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__setup_password +msgid "Installation key" +msgstr "Installateursschlüssel" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_res_partner__installer_setup_protocols_ids +#: model:ir.model.fields,field_description:openems.field_res_users__installer_setup_protocols_ids +msgid "Installed OpenEMS Edge" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol__installer_id +#: model:ir.model.fields.selection,name:openems.selection__openems_device_user_role__role__installer +#: model:ir.model.fields.selection,name:openems.selection__res_users__global_role__installer +msgid "Installer" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__internalnote +msgid "Internal note" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__message_is_follower +msgid "Is Follower" +msgstr "" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.openems_device_form +msgid "Is connected" +msgstr "" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.report_openems_setup_protocol_template +msgid "Kontaktdaten Endkunde" +msgstr "" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.report_openems_setup_protocol_template +msgid "Land" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device____last_update +#: model:ir.model.fields,field_description:openems.field_openems_device_tag____last_update +#: model:ir.model.fields,field_description:openems.field_openems_device_user_role____last_update +#: model:ir.model.fields,field_description:openems.field_openems_openemsconfigupdate____last_update +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol____last_update +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol_item____last_update +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol_production_lot____last_update +#: model:ir.model.fields,field_description:openems.field_openems_systemmessage____last_update +msgid "Last Modified on" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__write_uid +#: model:ir.model.fields,field_description:openems.field_openems_device_tag__write_uid +#: model:ir.model.fields,field_description:openems.field_openems_device_user_role__write_uid +#: model:ir.model.fields,field_description:openems.field_openems_openemsconfigupdate__write_uid +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol__write_uid +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol_item__write_uid +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol_production_lot__write_uid +#: model:ir.model.fields,field_description:openems.field_openems_systemmessage__write_uid +msgid "Last Updated by" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__write_date +#: model:ir.model.fields,field_description:openems.field_openems_device_tag__write_date +#: model:ir.model.fields,field_description:openems.field_openems_device_user_role__write_date +#: model:ir.model.fields,field_description:openems.field_openems_openemsconfigupdate__write_date +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol__write_date +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol_item__write_date +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol_production_lot__write_date +#: model:ir.model.fields,field_description:openems.field_openems_systemmessage__write_date +msgid "Last Updated on" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__lastupdate +msgid "Last data update" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__lastmessage +msgid "Last message" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device_user_role__last_notification +msgid "Last notification sent" +msgstr "" + +#. module: openems +#: model:ir.model,name:openems.model_stock_lot +msgid "Lot/Serial" +msgstr "Los/Serie" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__message_main_attachment_id +msgid "Main Attachment" +msgstr "" + +#. module: openems +#: model:res.groups,name:openems.group_openems_manager +msgid "Manager" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__manual_setup_date +msgid "Manual Setup Date" +msgstr "" + +#. module: openems +#: model:res.groups,comment:openems.group_openems_manager +msgid "Members of this group can manage all devices" +msgstr "" + +#. module: openems +#: model:res.groups,comment:openems.group_openems_reader +msgid "Members of this group have reading access to all devices" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_systemmessage__text +msgid "Message" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__message_has_error +msgid "Message Delivery error" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__message_ids +msgid "Messages" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__name +#: model:ir.model.fields,field_description:openems.field_openems_device_tag__name +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol_item__name +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol_production_lot__name +msgid "Name" +msgstr "" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.report_openems_setup_protocol_template +msgid "Name Installateur" +msgstr "" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.report_openems_setup_protocol_template +msgid "Name Kontaktperson" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__name_number +msgid "Name Number" +msgstr "" + +#. module: openems +#: model:ir.model.constraint,message:openems.constraint_openems_device_unique_name +msgid "Name needs to be unique" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device_user_role__time_to_wait +msgid "Notification" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__message_needaction_counter +msgid "Number of Actions" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__message_has_error_counter +msgid "Number of errors" +msgstr "" + +#. module: openems +#: model:ir.model.fields,help:openems.field_openems_device__message_needaction_counter +msgid "Number of messages requiring action" +msgstr "" + +#. module: openems +#: model:ir.model.fields,help:openems.field_openems_device__message_has_error_counter +msgid "Number of messages with delivery error" +msgstr "" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.openems_device_tree +msgid "OE Connected" +msgstr "" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.openems_device_tree +msgid "OE State" +msgstr "" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.openems_device_tree +msgid "OE Version" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__oem +msgid "OEM Branding" +msgstr "" + +#. module: openems +#: model:ir.model.fields.selection,name:openems.selection__openems_device__openems_sum_state_level__ok +msgid "Ok" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__monitoring_url +msgid "Online-Monitoring" +msgstr "" + +#. module: openems +#: model:ir.model.fields.selection,name:openems.selection__openems_device__oem__openems +#: model:ir.module.category,name:openems.module_category_openems +#: model:ir.ui.menu,name:openems.menu_openems +#: model_terms:ir.ui.view,arch_db:openems.openems_users_form +msgid "OpenEMS" +msgstr "" + +#. module: openems +#: model:mail.template,subject:openems.alerting_email_generic +msgid "OpenEMS Alert - Edge is offline" +msgstr "" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.report_openems_setup_protocol_template +msgid "OpenEMS Association e.V." +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__openems_config_components +msgid "OpenEMS Config" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__openems_config +msgid "OpenEMS Config Full" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__openems_config_update_ids +msgid "OpenEMS Config Updates" +msgstr "" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.openems_openemsconfigupdate_tree +msgid "OpenEMS Configuration Updates" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device_user_role__device_id +#: model:ir.model.fields,field_description:openems.field_openems_openemsconfigupdate__device_id +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol__device_id +#: model:ir.model.fields,field_description:openems.field_openems_systemmessage__device_id +#: model:ir.model.fields.selection,name:openems.selection__openems_device__producttype__openems-edge +#: model:ir.ui.menu,name:openems.menu_openems_content +msgid "OpenEMS Edge" +msgstr "" + +#. module: openems +#: model:ir.model,name:openems.model_openems_device +msgid "OpenEMS Edge Device" +msgstr "" + +#. module: openems +#: model:ir.model,name:openems.model_openems_openemsconfigupdate +msgid "OpenEMS Edge Device Configuration Update" +msgstr "" + +#. module: openems +#: model:ir.model,name:openems.model_openems_device_tag +msgid "OpenEMS Edge Device Tag" +msgstr "" + +#. module: openems +#: model:ir.model,name:openems.model_openems_device_user_role +msgid "OpenEMS Edge Device User Role" +msgstr "" + +#. module: openems +#: model:ir.model,name:openems.model_openems_setup_protocol_item +msgid "OpenEMS Edge Setup Protocol Entry Item" +msgstr "" + +#. module: openems +#: model:ir.model,name:openems.model_openems_setup_protocol_production_lot +msgid "OpenEMS Edge Setup Protocol Serial Number" +msgstr "" + +#. module: openems +#: model:ir.model,name:openems.model_openems_setup_protocol +msgid "OpenEMS Edge Setup Protocols (IBN)" +msgstr "" + +#. module: openems +#: model:ir.model,name:openems.model_openems_systemmessage +msgid "OpenEMS Edge Systemmessage" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__openems_is_connected +msgid "OpenEMS Is connected" +msgstr "" + +#. module: openems +#: model:ir.actions.report,name:openems.action_openems_setup_protocol_report +msgid "OpenEMS Setup Protocol" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__openems_sum_state_level +msgid "OpenEMS State" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__openems_version +#: model_terms:ir.ui.view,arch_db:openems.device_search_view +msgid "OpenEMS Version" +msgstr "" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.device_search_view +#: model_terms:ir.ui.view,arch_db:openems.openems_device_tree +msgid "OpenEMS-Number" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_res_users__openems_language +msgid "Openems Language" +msgstr "" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.report_openems_setup_protocol_template +msgid "Ort" +msgstr "" + +#. module: openems +#: model:ir.model.fields.selection,name:openems.selection__openems_device_user_role__role__owner +#: model:ir.model.fields.selection,name:openems.selection__res_users__global_role__owner +msgid "Owner" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_res_partner__customer_setup_protocols_ids +#: model:ir.model.fields,field_description:openems.field_res_users__customer_setup_protocols_ids +msgid "Owner of OpenEMS Edge" +msgstr "" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.report_openems_setup_protocol_template +msgid "PLZ" +msgstr "" + +#. module: openems +#: model:ir.model.fields,help:openems.field_openems_device__setup_password +msgid "Password for commissioning by the installer" +msgstr "Passwort für die Inbetriebnahme durch den Installateur" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.openems_setup_protocol_form +msgid "Print" +msgstr "" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.openems_device_form +msgid "Product" +msgstr "Produkt" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__producttype +msgid "Product type" +msgstr "" + +#. module: openems +#: model:res.groups,name:openems.group_openems_reader +msgid "Read access" +msgstr "" + +#. module: openems +#: model:mail.template,subject:openems.registration_email +msgid "Registrierung erfolgreich" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device_user_role__role +msgid "Role" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__user_role_ids +#: model:ir.model.fields,field_description:openems.field_res_users__device_role_ids +msgid "Roles" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__message_has_sms_error +msgid "SMS Delivery error" +msgstr "" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.openems_device_form +msgid "Security" +msgstr "Sicherheit" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol_production_lot__lot_id +msgid "Serial Number" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol__productionlot_ids +msgid "Serial Numbers" +msgstr "" + +#. module: openems +#: model:ir.model.constraint,message:openems.constraint_openems_device_unique_stock_production_lot_id +msgid "Serial number needs to be unique" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol_item__setup_protocol_id +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol_production_lot__setup_protocol_id +#: model_terms:ir.ui.view,arch_db:openems.report_openems_setup_protocol_template +msgid "Setup Protocol" +msgstr "" + +#. module: openems +#: model:ir.actions.act_window,name:openems.action_openems_admin_setup_protocol +#: model:ir.model.fields,field_description:openems.field_openems_device__setup_protocol_ids +#: model:ir.ui.menu,name:openems.menu_openems_admin_setup_protocol +#: model_terms:ir.ui.view,arch_db:openems.res_partner_form +msgid "Setup Protocols" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol_item__sequence +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol_production_lot__sequence +msgid "Sort" +msgstr "" + +#. module: openems +#: model:ir.model.fields.selection,name:openems.selection__res_users__openems_language__es +msgid "Spanish" +msgstr "" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.report_openems_setup_protocol_template +msgid "Speicherstandort" +msgstr "" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.openems_device_form +msgid "Status" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__stock_production_lot_id +msgid "Stock Production Lot" +msgstr "" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.report_openems_setup_protocol_template +msgid "Straße / Hausnummer" +msgstr "" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.openems_device_form +msgid "System Messages" +msgstr "" + +#. module: openems +#: model:ir.actions.act_window,name:openems.action_openems_systemmessage +#: model:ir.model.fields,field_description:openems.field_openems_device__systemmessage_ids +#: model:ir.ui.menu,name:openems.menu_openems_admin_systemmessages +msgid "Systemmessages" +msgstr "" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.openems_device_form +msgid "Systemstatus" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__tag_ids +msgid "Tags" +msgstr "" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.report_openems_setup_protocol_template +msgid "Telefonnummer" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_systemmessage__text_teaser +msgid "Text Teaser" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_openemsconfigupdate__details +msgid "Update Details" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_openemsconfigupdate__teaser +msgid "Update Details Teaser" +msgstr "" + +#. module: openems +#: model:ir.model,name:openems.model_res_users +#: model:ir.model.fields,field_description:openems.field_openems_device_user_role__user_id +msgid "User" +msgstr "Benutzer" + +#. module: openems +#: model:ir.model.constraint,message:openems.constraint_openems_device_user_role_device_user_uniq +msgid "User already exists for this device." +msgstr "" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.openems_systemmessage_tree +msgid "Users" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol_item__value +msgid "Value" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol_item__view +msgid "View Identifier" +msgstr "" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.report_openems_setup_protocol_template +msgid "Vor- Nachname" +msgstr "" + +#. module: openems +#: model:ir.model.fields.selection,name:openems.selection__openems_device__openems_sum_state_level__warning +msgid "Warning" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__website_message_ids +msgid "Website Messages" +msgstr "" + +#. module: openems +#: model:ir.model.fields,help:openems.field_openems_device__website_message_ids +msgid "Website communication history" +msgstr "" + +#. module: openems +#: model:mail.template,subject:openems.setup_protocol_email_customer +#: model:mail.template,subject:openems.setup_protocol_email_installer +msgid "Your OpenEMS setup protocol for {{object.openems_device_id.name}}" +msgstr "" diff --git a/addons/openems/i18n/openems.pot b/addons/openems/i18n/openems.pot new file mode 100644 index 0000000..c02fb93 --- /dev/null +++ b/addons/openems/i18n/openems.pot @@ -0,0 +1,1666 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * openems +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 16.0-20240218\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2024-02-18 11:56+0000\n" +"PO-Revision-Date: 2024-02-18 11:56+0000\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: openems +#: model:mail.template,body_html:openems.setup_protocol_email_installer +msgid "" +"\n" +"\n" +"\n" +"\n" +"\n" +" OpenEMS setup protocol \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +"\n" +"\n" +"\n" +"
\n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +"
\n" +" \n" +"
\n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +"
\n" +" \n" +"
\n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +"
\n" +"

\n" +"

\n" +" \n" +"
\n" +"
Dear \n" +" ,\n" +"
\n" +"
\n" +"
please find the setup protocol for your customer attached.\n" +"
\n" +"
\n" +"
Best Regards
\n" +"
\n" +"
OpenEMS Association e.V.
\n" +"
\n" +"
\n" +" \n" +"
\n" +"
\n" +" \n" +"
\n" +"
\n" +"\n" +"\n" +"\n" +" \n" +" " +msgstr "" + +#. module: openems +#: model:mail.template,body_html:openems.registration_email +msgid "" +"\n" +"\n" +"\n" +"\n" +"\n" +" Registrierung erfolgreich \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +"\n" +"\n" +"\n" +"
\n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +"
\n" +" \n" +"
\n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +"
\n" +" \n" +"
\n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +"
\n" +"

\n" +"

\n" +" \n" +"
\n" +"
Guten Tag \n" +" ,\n" +"
\n" +"
\n" +"
Ihr Zugang zu OpenEMS UI wurde erstellt.
\n" +"
\n" +"
Sie können sich auf OpenEMS UI einloggen, um auf das Online-Monitoring zuzugreifen.
\n" +"
\n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +"
Ihre Zugangsdaten:
E-Mail\n" +" \n" +"
Passwort\n" +" \n" +"
\n" +"
\n" +"
Best Regards
\n" +"
\n" +"
OpenEMS Association e.V.
\n" +"
\n" +"
\n" +" \n" +"
\n" +"
\n" +" \n" +"
\n" +"
\n" +"\n" +"\n" +"\n" +" \n" +" " +msgstr "" + +#. module: openems +#: model:mail.template,body_html:openems.setup_protocol_email_customer +msgid "" +"\n" +"\n" +"\n" +"\n" +"\n" +" Your OpenEMS Edge setup protocol \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +"\n" +"\n" +"\n" +"
\n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +"
\n" +" \n" +"
\n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +"
\n" +" \n" +"
\n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +"
\n" +"

\n" +"

\n" +" \n" +"
\n" +"
Welcome to OpenEMS,
\n" +"
\n" +"
please find your setup protocol for OpenEMS Edge attached.
\n" +"
\n" +"
Best Regards
\n" +"
\n" +"
OpenEMS Association e.V.
\n" +"
\n" +"
\n" +" \n" +"
\n" +"
\n" +" \n" +"
\n" +"
\n" +"\n" +"\n" +"\n" +" \n" +" " +msgstr "" + +#. module: openems +#: model:mail.template,body_html:openems.alerting_email_generic +msgid "" +"\n" +"\n" +"\n" +"\n" +"\n" +" OpenEMS Alert - Edge is offline\n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +"\n" +"\n" +"\n" +"
\n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +"
\n" +" \n" +"
\n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +"
\n" +" \n" +"
\n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +"
\n" +"

\n" +"

\n" +" \n" +"
\n" +"
Dear \n" +" ,\n" +"
\n" +"
\n" +"
Your OpenEMS Edge with number is offline since:
\n" +"
\n" +"
\n" +" \n" +" \n" +" \n" +" \n" +" \n" +" (UTC)\n" +" \n" +"
\n" +"
\n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +"
Info
\n" +" Edge-Version\n" +" \n" +" \n" +"
\n" +" Type\n" +" \n" +" \n" +" \n" +"
\n" +"
\n" +"
Best Regards
\n" +"
\n" +"
OpenEMS Association e.V.
\n" +"
\n" +"
\n" +" \n" +"
\n" +"
\n" +" \n" +"
\n" +" \n" +"
\n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +"
\n" +" \n" +"
\n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +"
\n" +"
Wenn Sie keine E-Mail Benachrichtigung mehr wünschen, können Sie die Funktion hier deaktivieren.
\n" +"
\n" +"
Dies ist eine automatisch generierte Nachricht. Bitte antworten Sie nicht auf diese Nachricht!
\n" +"
\n" +"
\n" +" \n" +"
\n" +"
\n" +" \n" +"
\n" +"\n" +"\n" +"\n" +" \n" +" " +msgstr "" + +#. module: openems +#: model:ir.actions.report,print_report_name:openems.action_openems_setup_protocol_report +msgid "" +"('IBN-' + object.openems_device_id.name + '-' + " +"object.create_date.strftime('%d.%m.%Y'))" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__apikey +msgid "API-Key" +msgstr "" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.openems_device_form +msgid "Access Role in Online-Monitoring" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__message_needaction +msgid "Action Needed" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__active +msgid "Active" +msgstr "" + +#. module: openems +#: model:ir.model.fields.selection,name:openems.selection__openems_device_user_role__role__admin +#: model:ir.model.fields.selection,name:openems.selection__res_users__global_role__admin +msgid "Admin" +msgstr "" + +#. module: openems +#: model:ir.ui.menu,name:openems.menu_openems_admin +msgid "Administration" +msgstr "" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.device_search_view +msgid "Archived" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__message_attachment_count +msgid "Attachment Count" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_res_users__branding_partner_id +msgid "Branding Partner" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol_item__category +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol_production_lot__category +msgid "Category" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__comment +msgid "Comment" +msgstr "" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.openems_device_form +msgid "Configuration" +msgstr "" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.openems_device_form +msgid "Configuration Updates" +msgstr "" + +#. module: openems +#: model:ir.model,name:openems.model_res_partner +msgid "Contact" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__create_uid +#: model:ir.model.fields,field_description:openems.field_openems_device_tag__create_uid +#: model:ir.model.fields,field_description:openems.field_openems_device_user_role__create_uid +#: model:ir.model.fields,field_description:openems.field_openems_openemsconfigupdate__create_uid +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol__create_uid +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol_item__create_uid +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol_production_lot__create_uid +#: model:ir.model.fields,field_description:openems.field_openems_systemmessage__create_uid +msgid "Created by" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__create_date +#: model:ir.model.fields,field_description:openems.field_openems_device_tag__create_date +#: model:ir.model.fields,field_description:openems.field_openems_device_user_role__create_date +#: model:ir.model.fields,field_description:openems.field_openems_openemsconfigupdate__create_date +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol__create_date +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol_item__create_date +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol_production_lot__create_date +#: model:ir.model.fields,field_description:openems.field_openems_systemmessage__create_date +msgid "Created on" +msgstr "" + +#. module: openems +#: model:res.partner.category,name:openems.res_partner_category_created_via_ibn +msgid "Created via IBN" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_systemmessage__timestamp +msgid "Creation date" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol__customer_id +#: model:res.partner.category,name:openems.res_partner_category_customer +msgid "Customer" +msgstr "" + +#. module: openems +#: model:ir.model.fields.selection,name:openems.selection__res_users__openems_language__cz +msgid "Czech" +msgstr "" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.report_openems_setup_protocol_template +msgid "Datum:" +msgstr "" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.device_search_view +#: model_terms:ir.ui.view,arch_db:openems.openems_device_tree +msgid "Description" +msgstr "" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.openems_openemsconfigupdate_tree +msgid "Details" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_stock_lot__device_id +#: model:ir.model.fields,field_description:openems.field_stock_lot__device_ids +msgid "Device" +msgstr "" + +#. module: openems +#: model:ir.actions.act_window,name:openems.action_openems_openemsconfigupdate +#: model:ir.ui.menu,name:openems.menu_openems_admin_openemsconfigupdate +msgid "Device Configuration Updates" +msgstr "" + +#. module: openems +#: model:ir.actions.act_window,name:openems.action_openems_device +#: model:ir.ui.menu,name:openems.menu_openems_content_devices +msgid "Devices" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol__different_location_id +msgid "Different Location" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__display_name +#: model:ir.model.fields,field_description:openems.field_openems_device_tag__display_name +#: model:ir.model.fields,field_description:openems.field_openems_device_user_role__display_name +#: model:ir.model.fields,field_description:openems.field_openems_openemsconfigupdate__display_name +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol__display_name +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol_item__display_name +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol_production_lot__display_name +#: model:ir.model.fields,field_description:openems.field_openems_systemmessage__display_name +msgid "Display Name" +msgstr "" + +#. module: openems +#: model:ir.model.fields.selection,name:openems.selection__res_users__openems_language__nl +msgid "Dutch" +msgstr "" + +#. module: openems +#: model:mail.template,name:openems.alerting_email_generic +msgid "E-Mail Alerting" +msgstr "" + +#. module: openems +#: model:mail.template,name:openems.registration_email +msgid "E-Mail Kunden Registrierung" +msgstr "" + +#. module: openems +#: model:mail.template,name:openems.setup_protocol_email_customer +msgid "E-Mail setup protocol for customer" +msgstr "" + +#. module: openems +#: model:mail.template,name:openems.setup_protocol_email_installer +msgid "E-Mail setup protocol for installer" +msgstr "" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.report_openems_setup_protocol_template +msgid "E-Mail-Adresse" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__emshardware +msgid "EMS Hardware" +msgstr "" + +#. module: openems +#: model:ir.model.fields.selection,name:openems.selection__res_users__openems_language__en +msgid "English" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol__item_ids +msgid "Entry Items" +msgstr "" + +#. module: openems +#: model:ir.model.fields.selection,name:openems.selection__openems_device__openems_sum_state_level__fault +msgid "Fault" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol_item__field +msgid "Field Identifier" +msgstr "" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.report_openems_setup_protocol_template +msgid "Firmenname" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__first_setup_protocol_date +msgid "First Setup Protocol Date" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__message_follower_ids +msgid "Followers" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__message_partner_ids +msgid "Followers (Partners)" +msgstr "" + +#. module: openems +#: model:ir.model.fields.selection,name:openems.selection__res_users__openems_language__fr +msgid "French" +msgstr "" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.openems_device_form +msgid "General" +msgstr "" + +#. module: openems +#: model:ir.model.fields.selection,name:openems.selection__res_users__openems_language__de +msgid "German" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_res_users__global_role +msgid "Global Role" +msgstr "" + +#. module: openems +#: model:ir.model.fields.selection,name:openems.selection__openems_device_user_role__role__guest +#: model:ir.model.fields.selection,name:openems.selection__res_users__global_role__guest +msgid "Guest" +msgstr "" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.openems_device_form +msgid "Hardware" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__has_message +msgid "Has Message" +msgstr "" + +#. module: openems +#: model:ir.model.fields.selection,name:openems.selection__res_users__openems_language__hu +msgid "Hungarian" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__id +#: model:ir.model.fields,field_description:openems.field_openems_device_tag__id +#: model:ir.model.fields,field_description:openems.field_openems_device_user_role__id +#: model:ir.model.fields,field_description:openems.field_openems_openemsconfigupdate__id +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol__id +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol_item__id +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol_production_lot__id +#: model:ir.model.fields,field_description:openems.field_openems_systemmessage__id +msgid "ID" +msgstr "" + +#. module: openems +#: model:ir.model.fields,help:openems.field_openems_device__message_needaction +msgid "If checked, new messages require your attention." +msgstr "" + +#. module: openems +#: model:ir.model.fields,help:openems.field_openems_device__message_has_error +#: model:ir.model.fields,help:openems.field_openems_device__message_has_sms_error +msgid "If checked, some messages have a delivery error." +msgstr "" + +#. module: openems +#: model:ir.model.fields.selection,name:openems.selection__openems_device__openems_sum_state_level__info +msgid "Info" +msgstr "" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.report_openems_setup_protocol_template +msgid "Installateur" +msgstr "" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.openems_device_form +msgid "Installation" +msgstr "" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.openems_device_form +msgid "Installation Log" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__setup_password +msgid "Installation key" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_res_partner__installer_setup_protocols_ids +#: model:ir.model.fields,field_description:openems.field_res_users__installer_setup_protocols_ids +msgid "Installed OpenEMS Edge" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol__installer_id +#: model:ir.model.fields.selection,name:openems.selection__openems_device_user_role__role__installer +#: model:ir.model.fields.selection,name:openems.selection__res_users__global_role__installer +msgid "Installer" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__internalnote +msgid "Internal note" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__message_is_follower +msgid "Is Follower" +msgstr "" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.openems_device_form +msgid "Is connected" +msgstr "" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.report_openems_setup_protocol_template +msgid "Kontaktdaten Endkunde" +msgstr "" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.report_openems_setup_protocol_template +msgid "Land" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device____last_update +#: model:ir.model.fields,field_description:openems.field_openems_device_tag____last_update +#: model:ir.model.fields,field_description:openems.field_openems_device_user_role____last_update +#: model:ir.model.fields,field_description:openems.field_openems_openemsconfigupdate____last_update +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol____last_update +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol_item____last_update +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol_production_lot____last_update +#: model:ir.model.fields,field_description:openems.field_openems_systemmessage____last_update +msgid "Last Modified on" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__write_uid +#: model:ir.model.fields,field_description:openems.field_openems_device_tag__write_uid +#: model:ir.model.fields,field_description:openems.field_openems_device_user_role__write_uid +#: model:ir.model.fields,field_description:openems.field_openems_openemsconfigupdate__write_uid +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol__write_uid +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol_item__write_uid +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol_production_lot__write_uid +#: model:ir.model.fields,field_description:openems.field_openems_systemmessage__write_uid +msgid "Last Updated by" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__write_date +#: model:ir.model.fields,field_description:openems.field_openems_device_tag__write_date +#: model:ir.model.fields,field_description:openems.field_openems_device_user_role__write_date +#: model:ir.model.fields,field_description:openems.field_openems_openemsconfigupdate__write_date +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol__write_date +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol_item__write_date +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol_production_lot__write_date +#: model:ir.model.fields,field_description:openems.field_openems_systemmessage__write_date +msgid "Last Updated on" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__lastupdate +msgid "Last data update" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__lastmessage +msgid "Last message" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device_user_role__last_notification +msgid "Last notification sent" +msgstr "" + +#. module: openems +#: model:ir.model,name:openems.model_stock_lot +msgid "Lot/Serial" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__message_main_attachment_id +msgid "Main Attachment" +msgstr "" + +#. module: openems +#: model:res.groups,name:openems.group_openems_manager +msgid "Manager" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__manual_setup_date +msgid "Manual Setup Date" +msgstr "" + +#. module: openems +#: model:res.groups,comment:openems.group_openems_manager +msgid "Members of this group can manage all devices" +msgstr "" + +#. module: openems +#: model:res.groups,comment:openems.group_openems_reader +msgid "Members of this group have reading access to all devices" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_systemmessage__text +msgid "Message" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__message_has_error +msgid "Message Delivery error" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__message_ids +msgid "Messages" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__name +#: model:ir.model.fields,field_description:openems.field_openems_device_tag__name +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol_item__name +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol_production_lot__name +msgid "Name" +msgstr "" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.report_openems_setup_protocol_template +msgid "Name Installateur" +msgstr "" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.report_openems_setup_protocol_template +msgid "Name Kontaktperson" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__name_number +msgid "Name Number" +msgstr "" + +#. module: openems +#: model:ir.model.constraint,message:openems.constraint_openems_device_unique_name +msgid "Name needs to be unique" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device_user_role__time_to_wait +msgid "Notification" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__message_needaction_counter +msgid "Number of Actions" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__message_has_error_counter +msgid "Number of errors" +msgstr "" + +#. module: openems +#: model:ir.model.fields,help:openems.field_openems_device__message_needaction_counter +msgid "Number of messages requiring action" +msgstr "" + +#. module: openems +#: model:ir.model.fields,help:openems.field_openems_device__message_has_error_counter +msgid "Number of messages with delivery error" +msgstr "" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.openems_device_tree +msgid "OE Connected" +msgstr "" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.openems_device_tree +msgid "OE State" +msgstr "" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.openems_device_tree +msgid "OE Version" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__oem +msgid "OEM Branding" +msgstr "" + +#. module: openems +#: model:ir.model.fields.selection,name:openems.selection__openems_device__openems_sum_state_level__ok +msgid "Ok" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__monitoring_url +msgid "Online-Monitoring" +msgstr "" + +#. module: openems +#: model:ir.model.fields.selection,name:openems.selection__openems_device__oem__openems +#: model:ir.module.category,name:openems.module_category_openems +#: model:ir.ui.menu,name:openems.menu_openems +#: model_terms:ir.ui.view,arch_db:openems.openems_users_form +msgid "OpenEMS" +msgstr "" + +#. module: openems +#: model:mail.template,subject:openems.alerting_email_generic +msgid "OpenEMS Alert - Edge is offline" +msgstr "" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.report_openems_setup_protocol_template +msgid "OpenEMS Association e.V." +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__openems_config_components +msgid "OpenEMS Config" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__openems_config +msgid "OpenEMS Config Full" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__openems_config_update_ids +msgid "OpenEMS Config Updates" +msgstr "" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.openems_openemsconfigupdate_tree +msgid "OpenEMS Configuration Updates" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device_user_role__device_id +#: model:ir.model.fields,field_description:openems.field_openems_openemsconfigupdate__device_id +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol__device_id +#: model:ir.model.fields,field_description:openems.field_openems_systemmessage__device_id +#: model:ir.model.fields.selection,name:openems.selection__openems_device__producttype__openems-edge +#: model:ir.ui.menu,name:openems.menu_openems_content +msgid "OpenEMS Edge" +msgstr "" + +#. module: openems +#: model:ir.model,name:openems.model_openems_device +msgid "OpenEMS Edge Device" +msgstr "" + +#. module: openems +#: model:ir.model,name:openems.model_openems_openemsconfigupdate +msgid "OpenEMS Edge Device Configuration Update" +msgstr "" + +#. module: openems +#: model:ir.model,name:openems.model_openems_device_tag +msgid "OpenEMS Edge Device Tag" +msgstr "" + +#. module: openems +#: model:ir.model,name:openems.model_openems_device_user_role +msgid "OpenEMS Edge Device User Role" +msgstr "" + +#. module: openems +#: model:ir.model,name:openems.model_openems_setup_protocol_item +msgid "OpenEMS Edge Setup Protocol Entry Item" +msgstr "" + +#. module: openems +#: model:ir.model,name:openems.model_openems_setup_protocol_production_lot +msgid "OpenEMS Edge Setup Protocol Serial Number" +msgstr "" + +#. module: openems +#: model:ir.model,name:openems.model_openems_setup_protocol +msgid "OpenEMS Edge Setup Protocols (IBN)" +msgstr "" + +#. module: openems +#: model:ir.model,name:openems.model_openems_systemmessage +msgid "OpenEMS Edge Systemmessage" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__openems_is_connected +msgid "OpenEMS Is connected" +msgstr "" + +#. module: openems +#: model:ir.actions.report,name:openems.action_openems_setup_protocol_report +msgid "OpenEMS Setup Protocol" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__openems_sum_state_level +msgid "OpenEMS State" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__openems_version +#: model_terms:ir.ui.view,arch_db:openems.device_search_view +msgid "OpenEMS Version" +msgstr "" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.device_search_view +#: model_terms:ir.ui.view,arch_db:openems.openems_device_tree +msgid "OpenEMS-Number" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_res_users__openems_language +msgid "Openems Language" +msgstr "" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.report_openems_setup_protocol_template +msgid "Ort" +msgstr "" + +#. module: openems +#: model:ir.model.fields.selection,name:openems.selection__openems_device_user_role__role__owner +#: model:ir.model.fields.selection,name:openems.selection__res_users__global_role__owner +msgid "Owner" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_res_partner__customer_setup_protocols_ids +#: model:ir.model.fields,field_description:openems.field_res_users__customer_setup_protocols_ids +msgid "Owner of OpenEMS Edge" +msgstr "" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.report_openems_setup_protocol_template +msgid "PLZ" +msgstr "" + +#. module: openems +#: model:ir.model.fields,help:openems.field_openems_device__setup_password +msgid "Password for commissioning by the installer" +msgstr "" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.openems_setup_protocol_form +msgid "Print" +msgstr "" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.openems_device_form +msgid "Product" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__producttype +msgid "Product type" +msgstr "" + +#. module: openems +#: model:res.groups,name:openems.group_openems_reader +msgid "Read access" +msgstr "" + +#. module: openems +#: model:mail.template,subject:openems.registration_email +msgid "Registrierung erfolgreich" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device_user_role__role +msgid "Role" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__user_role_ids +#: model:ir.model.fields,field_description:openems.field_res_users__device_role_ids +msgid "Roles" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__message_has_sms_error +msgid "SMS Delivery error" +msgstr "" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.openems_device_form +msgid "Security" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol_production_lot__lot_id +msgid "Serial Number" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol__productionlot_ids +msgid "Serial Numbers" +msgstr "" + +#. module: openems +#: model:ir.model.constraint,message:openems.constraint_openems_device_unique_stock_production_lot_id +msgid "Serial number needs to be unique" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol_item__setup_protocol_id +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol_production_lot__setup_protocol_id +#: model_terms:ir.ui.view,arch_db:openems.report_openems_setup_protocol_template +msgid "Setup Protocol" +msgstr "" + +#. module: openems +#: model:ir.actions.act_window,name:openems.action_openems_admin_setup_protocol +#: model:ir.model.fields,field_description:openems.field_openems_device__setup_protocol_ids +#: model:ir.ui.menu,name:openems.menu_openems_admin_setup_protocol +#: model_terms:ir.ui.view,arch_db:openems.res_partner_form +msgid "Setup Protocols" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol_item__sequence +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol_production_lot__sequence +msgid "Sort" +msgstr "" + +#. module: openems +#: model:ir.model.fields.selection,name:openems.selection__res_users__openems_language__es +msgid "Spanish" +msgstr "" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.report_openems_setup_protocol_template +msgid "Speicherstandort" +msgstr "" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.openems_device_form +msgid "Status" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__stock_production_lot_id +msgid "Stock Production Lot" +msgstr "" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.report_openems_setup_protocol_template +msgid "Straße / Hausnummer" +msgstr "" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.openems_device_form +msgid "System Messages" +msgstr "" + +#. module: openems +#: model:ir.actions.act_window,name:openems.action_openems_systemmessage +#: model:ir.model.fields,field_description:openems.field_openems_device__systemmessage_ids +#: model:ir.ui.menu,name:openems.menu_openems_admin_systemmessages +msgid "Systemmessages" +msgstr "" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.openems_device_form +msgid "Systemstatus" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__tag_ids +msgid "Tags" +msgstr "" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.report_openems_setup_protocol_template +msgid "Telefonnummer" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_systemmessage__text_teaser +msgid "Text Teaser" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_openemsconfigupdate__details +msgid "Update Details" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_openemsconfigupdate__teaser +msgid "Update Details Teaser" +msgstr "" + +#. module: openems +#: model:ir.model,name:openems.model_res_users +#: model:ir.model.fields,field_description:openems.field_openems_device_user_role__user_id +msgid "User" +msgstr "" + +#. module: openems +#: model:ir.model.constraint,message:openems.constraint_openems_device_user_role_device_user_uniq +msgid "User already exists for this device." +msgstr "" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.openems_systemmessage_tree +msgid "Users" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol_item__value +msgid "Value" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol_item__view +msgid "View Identifier" +msgstr "" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.report_openems_setup_protocol_template +msgid "Vor- Nachname" +msgstr "" + +#. module: openems +#: model:ir.model.fields.selection,name:openems.selection__openems_device__openems_sum_state_level__warning +msgid "Warning" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__website_message_ids +msgid "Website Messages" +msgstr "" + +#. module: openems +#: model:ir.model.fields,help:openems.field_openems_device__website_message_ids +msgid "Website communication history" +msgstr "" + +#. module: openems +#: model:mail.template,subject:openems.setup_protocol_email_customer +#: model:mail.template,subject:openems.setup_protocol_email_installer +msgid "Your OpenEMS setup protocol for {{object.openems_device_id.name}}" +msgstr "" diff --git a/addons/openems/mail/openems/alerting_offline.xml b/addons/openems/mail/openems/alerting_offline.xml new file mode 100644 index 0000000..2d2a38d --- /dev/null +++ b/addons/openems/mail/openems/alerting_offline.xml @@ -0,0 +1,275 @@ + + + + + E-Mail Offline-Alerting + + ]]> + {{object.user_id.partner_id.id}} + OpenEMS Alert - Edge is offline + + + + + OpenEMS Alert - Edge is offline + + + + + + + + + + + + + + + +
+ + + + + + +
+ +
+ + + + + + +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+

+

+ +
+
+ + + , + + Ms/Mr , + Customer, +
+
+
Your OpenEMS Edge with number is offline since: +
+
+
+ + + + + + + (UTC) + + +
+
+ + + + + + + + + + + + +
Info
+ OpenEMS-Version + + + + + UNKNOWN +
+ Type + + + + + + + +
+
+
Best Regards
+
+
OpenEMS Association e.V.
+
+
+ +
+
+ +
+ +
+ + + + + + +
+ +
+ + + + + + + + + + + + + + + +
+
If you do no longer wish to receive email notifications, you can disable the feature here .
+
+
This is an automatically generated message. Please do not reply to this message!
+
+ + + + + + +
+ OpenEMS Logo +
+
+

+

+ +
+
+ +
+
+ +
+ + + + ]]> +
+
+
+
diff --git a/addons/openems/mail/openems/alerting_sum_state.xml b/addons/openems/mail/openems/alerting_sum_state.xml new file mode 100644 index 0000000..5ac49f6 --- /dev/null +++ b/addons/openems/mail/openems/alerting_sum_state.xml @@ -0,0 +1,268 @@ + + + + + E-Mail SumState Alerting + + ]]> + {{object.user_id.partner_id.id}} + OpenEMS Alert - Edge is in {{object.device_id.openems_sum_state_level}} State + + + + + OpenEMS Alert - Edge is in fault + + + + + + + + + + + + + + + +
+ + + + + + +
+ +
+ + + + + + +
+ +
+ + + + + + + + + + + + + + + + + + + + + +
+

+

+ +
+
+ + + , + + Ms/Mr , + Customer, +
+
+
Your OpenEMS Edge with number is in a continuous + + + + + + + UNKNOWN + state! +
+
+ + + + + + + + + + + + +
Info
+ OpenEMS-Version + + + + + UNKNOWN +
+ Type + + + + + + + +
+
+
Best Regards
+
+
OpenEMS Association e.V.
+
+
+ +
+
+ +
+ +
+ + + + + + +
+ +
+ + + + + + + + + + + + + + + +
+
If you do no longer wish to receive email notifications, you can disable the feature here .
+
+
This is an automatically generated message. Please do not reply to this message!
+
+ + + + + + +
+ OpenEMS Logo +
+
+

+

+ +
+
+ +
+
+ +
+ + + + ]]> +
+
+
+
diff --git a/addons/openems/mail/openems/setup_protocol_customer.xml b/addons/openems/mail/openems/setup_protocol_customer.xml new file mode 100644 index 0000000..3b1e781 --- /dev/null +++ b/addons/openems/mail/openems/setup_protocol_customer.xml @@ -0,0 +1,170 @@ + + + + + E-Mail setup protocol for customer + + ]]> + {{object.customer_id.id}} + Your OpenEMS setup protocol for {{object.openems_device_id.name}} + false + + + + + Your OpenEMS Edge setup protocol + + + + + + + + + + + + + + + +
+ + + + + + +
+ +
+ + + + + + +
+ +
+ + + + + + + + + + + + + + + + + + +
+

+

+ +
+
Welcome to OpenEMS,
+
+
please find your setup protocol for OpenEMS Edge attached.
+
+
Best Regards
+
+
OpenEMS Association e.V.
+
+
+ +
+
+ +
+
+ + + + ]]> +
+
+
+
diff --git a/addons/openems/mail/openems/setup_protocol_installer.xml b/addons/openems/mail/openems/setup_protocol_installer.xml new file mode 100644 index 0000000..13afd9d --- /dev/null +++ b/addons/openems/mail/openems/setup_protocol_installer.xml @@ -0,0 +1,173 @@ + + + + + E-Mail setup protocol for installer + + ]]> + {{object.installer_id.id}} + Your OpenEMS setup protocol for {{object.openems_device_id.name}} + false + + + + + OpenEMS setup protocol + + + + + + + + + + + + + + + +
+ + + + + + +
+ +
+ + + + + + +
+ +
+ + + + + + + + + + + + + + + + + + +
+

+

+ +
+
Dear + , +
+
+
please find the setup protocol for your customer attached. +
+
+
Best Regards
+
+
OpenEMS Association e.V.
+
+
+ +
+
+ +
+
+ + + + ]]> +
+
+
+
diff --git a/addons/openems/mail/openems/user_registration.xml b/addons/openems/mail/openems/user_registration.xml new file mode 100644 index 0000000..cfd4183 --- /dev/null +++ b/addons/openems/mail/openems/user_registration.xml @@ -0,0 +1,197 @@ + + + + + E-Mail Kunden Registrierung + + ]]> + {{object.id}} + Registrierung erfolgreich + false + + + + + Registrierung erfolgreich + + + + + + + + + + + + + + + +
+ + + + + + +
+ +
+ + + + + + +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+

+

+ +
+
Guten Tag + , +
+
+
Ihr Zugang zu OpenEMS UI wurde erstellt.
+
+
Sie können sich auf OpenEMS UI einloggen, um auf das Online-Monitoring zuzugreifen.
+
+ + + + + + + + + + + + +
Ihre Zugangsdaten:
E-Mail + +
Passwort + +
+
+
Best Regards
+
+
OpenEMS Association e.V.
+
+
+ +
+
+ +
+
+ + + + ]]> +
+
+
+
diff --git a/addons/openems/migrations/16.0.1.0.1/post-migrate.py b/addons/openems/migrations/16.0.1.0.1/post-migrate.py new file mode 100644 index 0000000..1eab6fe --- /dev/null +++ b/addons/openems/migrations/16.0.1.0.1/post-migrate.py @@ -0,0 +1,9 @@ +def migrate(cr, version): + cr.execute(""" + INSERT INTO openems_alerting (device_id, device_name, user_id, user_login, offline_delay, warning_delay, fault_delay, offline_last_notification) + SELECT device_id, dev.name, user_id, usr.login, time_to_wait, 0, 0, last_notification + FROM openems_alerting_migrate AS migrate + LEFT JOIN openems_device AS dev ON dev.id = migrate.device_id + LEFT JOIN res_users AS usr ON usr.id = migrate.user_id + """) + cr.execute('DROP TABLE openems_alerting_migrate') diff --git a/addons/openems/migrations/16.0.1.0.1/pre-migrate.py b/addons/openems/migrations/16.0.1.0.1/pre-migrate.py new file mode 100644 index 0000000..341e4a5 --- /dev/null +++ b/addons/openems/migrations/16.0.1.0.1/pre-migrate.py @@ -0,0 +1,7 @@ +def migrate(cr, version): + cr.execute(""" + SELECT device_id, user_id, time_to_wait, last_notification + INTO openems_alerting_migrate + FROM openems_device_user_role + WHERE time_to_wait > 0; + """) diff --git a/addons/openems/models/__init__.py b/addons/openems/models/__init__.py new file mode 100644 index 0000000..c4a7e59 --- /dev/null +++ b/addons/openems/models/__init__.py @@ -0,0 +1 @@ +from . import device, partner, setup_protocol, user, stock_production_lot diff --git a/addons/openems/models/device.py b/addons/openems/models/device.py new file mode 100644 index 0000000..bdbda80 --- /dev/null +++ b/addons/openems/models/device.py @@ -0,0 +1,321 @@ +from odoo import api, fields, models, exceptions, _ +from datetime import datetime +from odoo.exceptions import ValidationError +import random +import re +import string + +class Device(models.Model): + _name = "openems.device" + _description = "OpenEMS Edge Device" + _inherit = "mail.thread" + _order = "name_number asc" + _sql_constraints = [ + ("unique_name", "unique(name)", "Name needs to be unique"), + ("unique_stock_production_lot_id", "unique(stock_production_lot_id)", + "Serial number needs to be unique") + ] + + name = fields.Char(required=True) + active = fields.Boolean("Active", default=True, tracking=True) + comment = fields.Char(tracking=True) + internalnote = fields.Text("Internal note", tracking=True) + tag_ids = fields.Many2many("openems.device_tag", string="Tags", tracking=True) + monitoring_url = fields.Char( + "Online-Monitoring", compute="_compute_monitoring_url", store=False + ) + stock_production_lot_id = fields.Many2one("stock.lot") + first_setup_protocol_date = fields.Datetime( + "First Setup Protocol Date", compute="_compute_first_setup_protocol" + ) + manual_setup_date = fields.Datetime("Manual Setup Date") + + @api.depends("setup_protocol_ids", "manual_setup_date") + def _compute_first_setup_protocol(self): + for rec in self: + if rec.manual_setup_date: + rec.first_setup_protocol_date = rec.manual_setup_date + elif len(rec.setup_protocol_ids) > 0: + rec.first_setup_protocol_date = rec.setup_protocol_ids[ + (len(rec.setup_protocol_ids) - 1) + ]["create_date"] + else: + rec.first_setup_protocol_date = None + + @api.depends("name") + def _compute_monitoring_url(self): + # Corrected the parameter key to 'edge_monitoring_url' + base_url = self.env["ir.config_parameter"].sudo().get_param("edge_monitoring_url", default='#') + for rec in self: + if isinstance(rec.name, str) and rec.name: + # Ensuring there is a '/' between base_url and rec.name if it's not already present + separator = '' if base_url.endswith('/') else '/' + rec.monitoring_url = base_url + separator + rec.name + "/live" + else: + rec.monitoring_url = base_url + + producttype = fields.Selection( + [ + ("openems-edge", "OpenEMS Edge"), + ], + "Product type", + tracking=True, + ) + emshardware = fields.Selection([], "EMS Hardware", tracking=True) + oem = fields.Selection( + [ + ("openems", "OpenEMS"), + ], + "OEM Branding", + default="openems", + ) + + # Settings + openems_config = fields.Text("OpenEMS Config Full") + openems_config_components = fields.Text("OpenEMS Config") + openems_version = fields.Char("OpenEMS Version", tracking=True) + + # Security + setup_password = fields.Char( + "Installation Key", + help="Password for commissioning by the installer", + ) + apikey = fields.Char("API-Key", required=True, tracking=True) + + # 'openems_sum_state_level' is updated by OpenEMS Backend + openems_sum_state_level = fields.Selection( + [("ok", "Ok"), ("info", "Info"), ("warning", "Warning"), ("fault", "Fault")], + "OpenEMS State", + ) + # 'openems_is_connected' is updated by OpenEMS Backend + openems_is_connected = fields.Boolean("OpenEMS Is connected") + + # System Status + lastmessage = fields.Datetime("Last message") + lastupdate = fields.Datetime("Last data update") + + # Verknüpfungen + systemmessage_ids = fields.One2many( + "openems.systemmessage", "device_id", string="System Messages" + ) + user_role_ids = fields.One2many( + "openems.device_user_role", "device_id", string="Roles", tracking=True + ) + alerting_settings = fields.One2many( + "openems.alerting", "device_id", string="Alerting", tracking=True + ) + openems_config_update_ids = fields.One2many( + "openems.openemsconfigupdate", "device_id", string="OpenEMS Config Updates" + ) + setup_protocol_ids = fields.One2many( + "openems.setup_protocol", "device_id", "Setup Protocols" + ) + + # Helper fields + name_number = fields.Integer(compute="_compute_name_number", store="True") + + @api.depends("name") + def _compute_name_number(self): + for rec in self: + rec.name_number = int(rec.name[4:]) if rec.name.startswith("edge") else -1 + + def _get_openems_state_number(self, string): + state = 0 + if string == "info": + state = 1 + elif string == "warning": + state = 2 + elif string == "fault": + state = 3 + return state + + def write(self, vals): + """Prohibit to change name field after creation.""" + if 'name' in vals: + for record in self: + if record.id and record.name != vals['name']: + self.env.cr.execute(""" + SELECT EXISTS ( + SELECT 1 FROM openems_device + WHERE name = %s AND id != %s + ) + """, (vals['name'], record.id)) + exists = self.env.cr.fetchone()[0] + if exists: + # This means there's already a device with the intended new name + raise exceptions.UserError( + "The name '{}' is already in use or does not follow the required pattern.".format( + vals['name'])) + + # If you simply want to prevent name changes, the following UserError suffices + raise exceptions.UserError("The name of the device cannot be changed after creation.") + return super(Device, self).write(vals) + + @api.model + def create(self, vals): + + # Generate setup password if not provided + if 'setup_password' not in vals or not vals['setup_password']: + vals['setup_password'] = self._generate_unique_setup_password() + + # Generate API key if not provided + if 'apikey' not in vals or not vals['apikey']: + vals['apikey'] = self._generate_api_key() + + return super(Device, self).create(vals) + + def _generate_unique_setup_password(self): + is_unique = False + setup_password = '' + while not is_unique: + # Generate a random setup password + raw_password = ''.join(random.choices(string.ascii_uppercase + string.digits, k=16)) + setup_password = '-'.join([raw_password[i:i + 4] for i in range(0, len(raw_password), 4)]) + # Check if the generated setup password already exists + existing = self.search_count([('setup_password', '=', setup_password)]) + # If the password does not exist, it is unique, and we can exit the loop + if existing == 0: + is_unique = True + return setup_password + + def _generate_api_key(self): + # Initialize a flag to indicate whether the generated key is unique + is_unique = False + api_key = '' + while not is_unique: + # Generate a random API key + api_key = ''.join(random.choices(string.ascii_letters + string.digits, k=20)) + # Check if the generated API key already exists + existing = self.search_count([('apikey', '=', api_key)]) + # If the key does not exist, it is unique, and we can exit the loop + if existing == 0: + is_unique = True + return api_key + + @api.onchange('setup_password') + def _check_setup_password_format(self): + for record in self: + if not record.setup_password: + continue + if not re.match(r"^[A-Z0-9]{4}-[A-Z0-9]{4}-[A-Z0-9]{4}-[A-Z0-9]{4}$", record.setup_password): + raise ValidationError("The device ID must be formatted as XXXX-XXXX-XXXX-XXXX") + + @api.onchange('apikey') + def _check_api_key_uniqueness(self): + for record in self: + if record.apikey: + # Prepare the domain for searching duplicates + domain = [('apikey', '=', record.apikey)] + # If the record is already saved (has a valid database ID), exclude it from the search + if record.id and isinstance(record.id, (int,)): + domain.append(('id', '!=', record.id)) + # Check if any other records with the same API key exist + existing = self.search_count(domain) + # If there are duplicates, raise a ValidationError + if existing: + raise ValidationError( + _("The API key already exists and must be unique. Please choose a different API key.")) + + +class DeviceTag(models.Model): + _name = "openems.device_tag" + _description = "OpenEMS Edge Device Tag" + name = fields.Char(required=True) + + +class DeviceUserRole(models.Model): + _name = "openems.device_user_role" + _description = "OpenEMS Edge Device User Role" + _sql_constraints = [ + ( + "device_user_uniq", + "unique(device_id, user_id)", + "User already exists for this device.", + ), + ] + device_id = fields.Many2one("openems.device", string="OpenEMS Edge") + user_id = fields.Many2one("res.users", string="User") + role = fields.Selection( + [ + ("admin", "Admin"), + ("installer", "Installer"), + ("owner", "Owner"), + ("guest", "Guest"), + ], + default="guest", + required=True, + ) + + +class OpenemsConfigUpdate(models.Model): + _name = "openems.openemsconfigupdate" + _description = "OpenEMS Edge Device Configuration Update" + _order = "create_date desc" + + device_id = fields.Many2one("openems.device", string="OpenEMS Edge") + teaser = fields.Text("Update Details Teaser") + details = fields.Html("Update Details") + + +class Systemmessage(models.Model): + _name = "openems.systemmessage" + _description = "OpenEMS Edge Systemmessage" + _order = "create_date desc" + + timestamp = fields.Datetime("Creation date") + device_id = fields.Many2one("openems.device", string="OpenEMS Edge") + text = fields.Text("Message") + text_teaser = fields.Char(compute="_compute_text_teaser") + + @api.depends("text") + def _compute_text_teaser(self): + for rec in self: + # get up to 100 characters from first line + rec.text_teaser = rec.text.splitlines()[0][0:100] if rec.text else False + +class Alerting(models.Model): + _name = "openems.alerting" + _description = "OpenEMS Edge AlertingSettings" + _sql_constraints = [ + ( + "device_user_uniq", + "unique(device_id, user_id)", + "User already has Alerting Settings.", + ), + ] + + device_id = fields.Many2one("openems.device", string="OpenEMS Edge") + user_id = fields.Many2one("res.users", string="User") + + offline_delay = fields.Integer(string="Offline Notification", default=1440) + warning_delay = fields.Integer(string="Warning Notification", default=1440) + fault_delay = fields.Integer(string="Fault Notification", default=1440) + + offline_last_notification = fields.Datetime(string="Last Offline notification sent") + sum_state_last_notification = fields.Datetime(string="Last SumState notification sent") + + device_name = fields.Text(compute="_compute_device_name", store="True") + user_login = fields.Text(compute="_compute_user_login", store="True") + + user_role = fields.Selection( + [("admin", "Admin"), ("installer", "Installer"), ("owner", "Owner"), ("guest", "Guest"),], + compute="_compute_user_role", store="False") + + @api.depends("device_id") + def _compute_device_name(self): + for rec in self: + rec.device_name = rec.device_id.name; + + @api.depends("user_id") + def _compute_user_login(self): + for rec in self: + rec.user_login = rec.user_id.login; + + @api.depends("user_id", "device_id") + def _compute_user_role(self): + for rec in self: + user_role: DeviceUserRole = rec.user_id.device_role_ids.search([('device_id','=',rec.device_id.id)]) + if user_role: + return user_role.role + else: + return rec.user_id.global_role diff --git a/addons/openems/models/partner.py b/addons/openems/models/partner.py new file mode 100644 index 0000000..37ab8e5 --- /dev/null +++ b/addons/openems/models/partner.py @@ -0,0 +1,12 @@ +from odoo import fields, models + + +class ResPartner(models.Model): + _inherit = "res.partner" + + installer_setup_protocols_ids = fields.One2many( + "openems.setup_protocol", "installer_id", "Installed OpenEMS Edge" + ) + customer_setup_protocols_ids = fields.One2many( + "openems.setup_protocol", "customer_id", "Owner of OpenEMS Edge" + ) diff --git a/addons/openems/models/setup_protocol.py b/addons/openems/models/setup_protocol.py new file mode 100644 index 0000000..548576e --- /dev/null +++ b/addons/openems/models/setup_protocol.py @@ -0,0 +1,49 @@ +from odoo import fields, models + + +class SetupProtocol(models.Model): + _name = "openems.setup_protocol" + _description = "OpenEMS Edge Setup Protocols (IBN)" + _order = "create_date desc" + + customer_id = fields.Many2one("res.partner", "Customer", required=True) + different_location_id = fields.Many2one("res.partner", "Different Location") + installer_id = fields.Many2one("res.partner", "Installer", required=True) + device_id = fields.Many2one("openems.device", "OpenEMS Edge", required=True) + productionlot_ids = fields.One2many( + "openems.setup_protocol_production_lot", "setup_protocol_id", "Serial Numbers" + ) + item_ids = fields.One2many( + "openems.setup_protocol_item", "setup_protocol_id", "Entry Items" + ) + + +class SetupProtocolProductionLot(models.Model): + _name = "openems.setup_protocol_production_lot" + _description = "OpenEMS Edge Setup Protocol Serial Number" + _order = "setup_protocol_id, category, sequence asc" + + sequence = fields.Integer("Sort") + category = fields.Char("Category") + name = fields.Char("Name") + lot_id = fields.Many2one("stock.production.lot", "Serial Number") + setup_protocol_id = fields.Many2one( + "openems.setup_protocol", "Setup Protocol", ondelete="cascade" + ) + + +class SetupProtocolItem(models.Model): + _name = "openems.setup_protocol_item" + _description = "OpenEMS Edge Setup Protocol Entry Item" + _order = "setup_protocol_id, category, sequence asc" + + sequence = fields.Integer("Sort") + category = fields.Char("Category") + name = fields.Char("Name") + value = fields.Char("Value") + setup_protocol_id = fields.Many2one( + "openems.setup_protocol", "Setup Protocol", ondelete="cascade" + ) + view = fields.Char("View Identifier") + field = fields.Char("Field Identifier") + diff --git a/addons/openems/models/stock_production_lot.py b/addons/openems/models/stock_production_lot.py new file mode 100644 index 0000000..37ebb22 --- /dev/null +++ b/addons/openems/models/stock_production_lot.py @@ -0,0 +1,23 @@ +from odoo import fields, models, api + + +class ProductionLot(models.Model): + _inherit = "stock.lot" + + device_id = fields.Many2one( + 'openems.device', compute='compute_device_id', inverse='device_inverse') + device_ids = fields.One2many('openems.device', 'stock_production_lot_id') + + @api.depends('device_ids') + def compute_device_id(self): + if len(self.device_ids) > 0: + self.device_id = self.device_ids[0] + + def device_inverse(self): + if len(self.device_ids) > 0: + if len(self.device_id.stock_production_lot_id) > 0: + raise ValueError("A serial number has already been assigned to the device") + + device = self.env['openems.device'].browse(self.device_ids[0].id) + device.stock_production_lot_id = False + self.device_id.stock_production_lot_id = self diff --git a/addons/openems/models/user.py b/addons/openems/models/user.py new file mode 100644 index 0000000..321dd87 --- /dev/null +++ b/addons/openems/models/user.py @@ -0,0 +1,37 @@ +from odoo import fields, models + + +class ResUsers(models.Model): + _inherit = "res.users" + + branding_partner_id = fields.Many2one("res.partner", string="Branding Partner") + global_role = fields.Selection( + [ + ("admin", "Admin"), + ("installer", "Installer"), + ("owner", "Owner"), + ("guest", "Guest"), + ], + default="guest", + required=True, + ) + device_role_ids = fields.One2many( + "openems.device_user_role", "user_id", string="Roles" + ) + alerting_settings = fields.One2many( + "openems.alerting", "user_id", string="Alerting" + ) + openems_language = fields.Selection( + [ + ("EN", "English"), + ("DE", "German"), + ("CZ", "Czech"), + ("NL", "Dutch"), + ("ES", "Spanish"), + ("FR", "French"), + ("HU", "Hungarian"), + ("JA", "Japanese"), + ], + default="DE", + required=True, + ) diff --git a/addons/openems/report/setup_protocol.xml b/addons/openems/report/setup_protocol.xml new file mode 100644 index 0000000..c9db4ec --- /dev/null +++ b/addons/openems/report/setup_protocol.xml @@ -0,0 +1,311 @@ + + + + OpenEMS Setup Protocol + openems.setup_protocol + qweb-pdf + openems.report_openems_setup_protocol_template + ('IBN-' + object.openems_device_id.name + '-' + object.create_date.strftime('%d.%m.%Y')) + + + diff --git a/addons/openems/security/ir.model.access.csv b/addons/openems/security/ir.model.access.csv new file mode 100644 index 0000000..1ccc0f1 --- /dev/null +++ b/addons/openems/security/ir.model.access.csv @@ -0,0 +1,31 @@ +id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink +access_openems_device_portal,access_openems_device_portal,openems.model_openems_device,base.group_portal,1,0,0,0 +access_openems_device_user,access_openems_device_user,openems.model_openems_device,base.group_user,1,0,0,0 +access_openems_device_manager,access_openems_device_manager,openems.model_openems_device,openems.group_openems_manager,1,1,1,0 +access_openems_device_tag_portal,access_openems_device_tag_portal,openems.model_openems_device_tag,base.group_portal,1,0,0,0 +access_openems_device_tag_user,access_openems_device_tag_user,openems.model_openems_device_tag,base.group_user,1,0,0,0 +access_openems_device_tag_manager,access_openems_device_tag_manager,openems.model_openems_device_tag,openems.group_openems_manager,1,1,1,1 +access_openems_device_user_role_portal,access_openems_device_user_role_portal,openems.model_openems_device_user_role,base.group_portal,1,0,0,0 +access_openems_device_user_role_user,access_openems_device_user_role_user,openems.model_openems_device_user_role,base.group_user,1,0,0,0 +access_openems_device_user_role_manager,access_openems_device_user_role_manager,openems.model_openems_device_user_role,openems.group_openems_manager,1,1,1,1 +access_openems_alerting_portal,access_openems_alerting_portal,openems.model_openems_alerting,base.group_portal,1,0,0,0 +access_openems_alerting_user,access_openems_alerting_user,openems.model_openems_alerting,base.group_user,1,0,0,0 +access_openems_alerting_manager,access_openems_alerting_manager,openems.model_openems_alerting,openems.group_openems_manager,1,1,1,1 +access_openems_systemmessage_portal,access_openems_systemmessage_portal,openems.model_openems_systemmessage,base.group_portal,1,0,0,0 +access_openems_systemmessage_user,access_openems_systemmessage_user,openems.model_openems_systemmessage,base.group_user,1,0,0,0 +access_openems_systemmessage_manager,access_openems_systemmessage_manager,openems.model_openems_systemmessage,openems.group_openems_manager,1,1,1,1 +access_openems_openemsconfigupdate_portal,access_openems_openemsconfigupdate_portal,openems.model_openems_openemsconfigupdate,base.group_portal,1,0,0,0 +access_openems_openemsconfigupdate_user,access_openems_openemsconfigupdate_user,openems.model_openems_openemsconfigupdate,base.group_user,1,0,0,0 +access_openems_openemsconfigupdate_manager,access_openems_openemsconfigupdate_manager,openems.model_openems_openemsconfigupdate,openems.group_openems_manager,1,1,1,1 +access_openems_setup_protocol_portal,access_openems_setup_protocol_portal,openems.model_openems_setup_protocol,base.group_portal,1,0,0,0 +access_openems_setup_protocol_user,access_openems_setup_protocol_user,openems.model_openems_setup_protocol,base.group_user,1,0,0,0 +access_openems_setup_protocol_manager,access_openems_setup_protocol_manager,openems.model_openems_setup_protocol,openems.group_openems_manager,1,1,1,1 +access_openems_setup_protocol_production_lot_portal,access_openems_setup_protocol_production_lot_portal,openems.model_openems_setup_protocol_production_lot,base.group_portal,1,0,0,0 +access_openems_setup_protocol_production_lot_user,access_openems_setup_protocol_production_lot_user,openems.model_openems_setup_protocol_production_lot,base.group_user,1,0,0,0 +access_openems_setup_protocol_production_lot_manager,access_openems_setup_protocol_production_lot_manager,openems.model_openems_setup_protocol_production_lot,openems.group_openems_manager,1,1,1,1 +access_openems_setup_protocol_item_portal,access_openems_setup_protocol_item_portal,openems.model_openems_setup_protocol_item,base.group_portal,1,0,0,0 +access_openems_setup_protocol_item_user,access_openems_setup_protocol_item_user,openems.model_openems_setup_protocol_item,base.group_user,1,0,0,0 +access_openems_setup_protocol_item_manager,access_openems_setup_protocol_item_manager,openems.model_openems_setup_protocol_item,openems.group_openems_manager,1,1,1,1 +access_openems_production_lot_portal,access_openems_production_lot_portal,stock.model_stock_lot,base.group_portal,1,0,0,0 +access_openems_production_lot_user,access_openems_production_lot_user,stock.model_stock_lot,base.group_user,1,0,0,0 +access_openems_production_lot_manager,access_openems_production_lot_manager,stock.model_stock_lot,openems.group_openems_manager,1,0,0,0 diff --git a/addons/openems/security/openems.xml b/addons/openems/security/openems.xml new file mode 100644 index 0000000..ef87c2f --- /dev/null +++ b/addons/openems/security/openems.xml @@ -0,0 +1,54 @@ + + + + OpenEMS + 30 + + + + Read access + Members of this group have reading access to all devices + + + + + Manager + Members of this group can manage all devices + + + + + + + Website: Show only approved devices to Portal and User + + ['|', ('user_role_ids.user_id','in',[user.id]), ('alerting_settings.user_id','in',[user.id])] + + + + + + + + + Website: Show all devices to readers group + + [(1,'=',1)] + + + + + + + + diff --git a/addons/openems/setup/.setuptools-odoo-make-default-ignore b/addons/openems/setup/.setuptools-odoo-make-default-ignore new file mode 100644 index 0000000..207e615 --- /dev/null +++ b/addons/openems/setup/.setuptools-odoo-make-default-ignore @@ -0,0 +1,2 @@ +# addons listed in this file are ignored by +# setuptools-odoo-make-default (one addon per line) diff --git a/addons/openems/setup/README b/addons/openems/setup/README new file mode 100644 index 0000000..a63d633 --- /dev/null +++ b/addons/openems/setup/README @@ -0,0 +1,2 @@ +To learn more about this directory, please visit +https://pypi.python.org/pypi/setuptools-odoo diff --git a/addons/openems/static/description/icon.png b/addons/openems/static/description/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..ee0aed1a0d5b623df9c4f3ead2a8d92ab7efc315 GIT binary patch literal 53271 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

`b%zWJVoybJJC+al7(vmUoDSw-d(zU?;>j| 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 + + + + Device: Tree + openems.device + + + + + + + + + + + + + + + + + Device: Search + openems.device + + + + + + + + + + + + + + + + + + + + + Device: Form + openems.device + +

+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + +
+ + + + + + Device DeviceUserRole: Tree + openems.device_user_role + + + + + + + + + + Devices + ir.actions.act_window + openems.device + tree,form + + + + + + Device Configuration Updates + openems.openemsconfigupdate + + + + Device Configuration Updates: Tree + openems.openemsconfigupdate + + + + + + + + + + + Device Configuration Updates: Form + openems.openemsconfigupdate + +
+ + + + + + + +
+
+
+ + + + Systemmessages + openems.systemmessage + + + + Device Systemmessage: Tree + openems.systemmessage + + + + + + + + + + + Device Systemmessage: Form + openems.systemmessage + +
+ + + + + + + +
+
+
+ + + + + + + + + diff --git a/addons/openems/views/partner.xml b/addons/openems/views/partner.xml new file mode 100644 index 0000000..874530e --- /dev/null +++ b/addons/openems/views/partner.xml @@ -0,0 +1,28 @@ + + + + OpenEMS Partner: Form + res.partner + + + + + + + + + + + + + + + + + + + + + + + diff --git a/addons/openems/views/setup_protocol.xml b/addons/openems/views/setup_protocol.xml new file mode 100644 index 0000000..bf2eee2 --- /dev/null +++ b/addons/openems/views/setup_protocol.xml @@ -0,0 +1,82 @@ + + + + SetupProtocol: Form + openems.setup_protocol + +
+ + +
+ + +
+ + + diff --git a/addons/web_m2x_options/static/src/components/form.esm.js b/addons/web_m2x_options/static/src/components/form.esm.js new file mode 100644 index 0000000..ecb37d2 --- /dev/null +++ b/addons/web_m2x_options/static/src/components/form.esm.js @@ -0,0 +1,404 @@ +/** @odoo-module **/ + +import { + Many2ManyTagsField, + Many2ManyTagsFieldColorEditable, +} from "@web/views/fields/many2many_tags/many2many_tags_field"; + +import {Dialog} from "@web/core/dialog/dialog"; +import {FormController} from "@web/views/form/form_controller"; +import {FormViewDialog} from "@web/views/view_dialogs/form_view_dialog"; +import {Many2OneAvatarField} from "@web/views/fields/many2one_avatar/many2one_avatar_field"; +import {Many2OneBarcodeField} from "@web/views/fields/many2one_barcode/many2one_barcode_field"; +import {Many2OneField} from "@web/views/fields/many2one/many2one_field"; +import {ReferenceField} from "@web/views/fields/reference/reference_field"; +import {X2ManyField} from "@web/views/fields/x2many/x2many_field"; +import {isX2Many} from "@web/views/utils"; +import {is_option_set} from "@web_m2x_options/components/relational_utils.esm"; +import {patch} from "@web/core/utils/patch"; +import {sprintf} from "@web/core/utils/strings"; +import {useService} from "@web/core/utils/hooks"; + +const {Component} = owl; + +/** + * Patch Many2ManyTagsField + **/ +patch(Many2ManyTagsField.prototype, "web_m2x_options.Many2ManyTagsField", { + setup() { + this._super(...arguments); + this.actionService = useService("action"); + }, + /** + * @override + */ + getTagProps(record) { + const props = this._super(...arguments); + props.onClick = (ev) => this.onMany2ManyBadgeClick(ev, record); + return props; + }, + async onMany2ManyBadgeClick(event, record) { + var self = this; + if (self.props.open) { + var context = self.context; + var id = record.data.id; + if (self.props.readonly) { + event.preventDefault(); + event.stopPropagation(); + const action = await self.orm.call( + self.props.relation, + "get_formview_action", + [[id]], + {context: context} + ); + self.actionService.doAction(action); + } else { + const view_id = await self.orm.call( + self.props.relation, + "get_formview_id", + [[id]], + {context: context} + ); + + const write_access = await self.orm.call( + self.props.relation, + "check_access_rights", + [], + {operation: "write", raise_exception: false} + ); + var can_write = self.props.canWrite; + self.dialog.add(FormViewDialog, { + resModel: self.props.relation, + resId: id, + context: context, + title: self.env._t("Open: ") + self.string, + viewId: view_id, + mode: !can_write || !write_access ? "readonly" : "edit", + onRecordSaved: () => self.props.value.model.load(), + }); + } + } + }, +}); + +Many2ManyTagsField.props = { + ...Many2ManyTagsField.props, + open: {type: Boolean, optional: true}, + canWrite: {type: Boolean, optional: true}, + nodeOptions: {type: Object, optional: true}, +}; + +const Many2ManyTagsFieldExtractProps = Many2ManyTagsField.extractProps; +Many2ManyTagsField.extractProps = ({attrs, field}) => { + const canOpen = Boolean(attrs.options.open); + const canWrite = attrs.can_write && Boolean(JSON.parse(attrs.can_write)); + return Object.assign(Many2ManyTagsFieldExtractProps({attrs, field}), { + open: canOpen, + canWrite: canWrite, + nodeOptions: attrs.options, + }); +}; + +/** + * Many2ManyTagsFieldColorEditable + **/ +patch( + Many2ManyTagsFieldColorEditable.prototype, + "web_m2x_options.Many2ManyTagsFieldColorEditable", + { + async onBadgeClick(event, record) { + if (this.props.canEditColor && !this.props.open) { + this._super(...arguments); + } + if (this.props.open) { + Many2ManyTagsField.prototype.onMany2ManyBadgeClick.bind(this)( + event, + record + ); + } + }, + } +); + +Many2ManyTagsFieldColorEditable.props = { + ...Many2ManyTagsFieldColorEditable.props, + open: {type: Boolean, optional: true}, + canWrite: {type: Boolean, optional: true}, + nodeOptions: {type: Object, optional: true}, +}; + +/** + * CreateConfirmationDialog + * New customized component for Many2One Field + **/ + +class CreateConfirmationDialog extends Component { + get title() { + return sprintf(this.env._t("New: %s"), this.props.name); + } + + async onCreate() { + await this.props.create(); + this.props.close(); + } + async onCreateEdit() { + await this.props.createEdit(); + this.props.close(); + } +} +CreateConfirmationDialog.components = {Dialog}; +CreateConfirmationDialog.template = + "web_m2x_options.Many2OneField.CreateConfirmationDialog"; + +/** + * Many2OneField + **/ + +patch(Many2OneField.prototype, "web_m2x_options.Many2OneField", { + setup() { + this._super(...arguments); + this.ir_options = Component.env.session.web_m2x_options; + }, + /** + * @override + */ + get Many2XAutocompleteProps() { + const props = this._super(...arguments); + return { + ...props, + searchLimit: this.props.searchLimit, + searchMore: this.props.searchMore, + canCreate: this.props.canCreate, + nodeOptions: this.props.nodeOptions, + }; + }, + + async openConfirmationDialog(request) { + var m2o_dialog_opt = + is_option_set(this.props.nodeOptions.m2o_dialog) || + (_.isUndefined(this.props.nodeOptions.m2o_dialog) && + is_option_set(this.ir_options["web_m2x_options.m2o_dialog"])) || + (_.isUndefined(this.props.nodeOptions.m2o_dialog) && + _.isUndefined(this.ir_options["web_m2x_options.m2o_dialog"])); + if (this.props.canCreate && this.state.isFloating && m2o_dialog_opt) { + return new Promise((resolve, reject) => { + this.addDialog(CreateConfirmationDialog, { + value: request, + name: this.props.string, + create: async () => { + try { + await this.quickCreate(request); + resolve(); + } catch (e) { + reject(e); + } + }, + createEdit: async () => { + try { + await this.quickCreate(request); + await this.props.record.model.load(); + this.openMany2X({ + resId: this.props.value[0], + context: this.user_context, + }); + resolve(); + } catch (e) { + reject(e); + } + }, + }); + }); + } + }, +}); + +const Many2OneFieldExtractProps = Many2OneField.extractProps; +Many2OneField.extractProps = ({attrs, field}) => { + return Object.assign(Many2OneFieldExtractProps({attrs, field}), { + searchLimit: attrs.options.limit, + searchMore: attrs.options.search_more, + nodeOptions: attrs.options, + }); +}; + +Many2OneField.props = { + ...Many2OneField.props, + searchMore: {type: Boolean, optional: true}, + nodeOptions: {type: Object, optional: true}, +}; + +/** + * FIXME: find better way to extend props in Many2OneField + * Override ReferenceField + * Since extracted/added props: nodeOptions and searchMore into Many2OneField props + * and this component inherited props from Many2OneField + * So, must override props here to avoid constraint validateProps (props schema) in owl core + */ + +ReferenceField.props = { + ...ReferenceField.props, + searchMore: {type: Boolean, optional: true}, + nodeOptions: {type: Object, optional: true}, +}; + +/** + * FIXME: find better way to extend props in Many2OneField + * Override Many2OneBarcodeField + * Since extracted/added props: nodeOptions and searchMore into Many2OneField props + * and this component inherited props from Many2OneField + * So, must override props here to avoid constraint validateProps (props schema) in owl core + */ + +Many2OneBarcodeField.props = { + ...Many2OneBarcodeField.props, + searchMore: {type: Boolean, optional: true}, + nodeOptions: {type: Object, optional: true}, +}; + +/** + * FIXME: find better way to extend props in Many2OneField + * Override Many2OneAvatarField + * Since extracted/added props: nodeOptions and searchMore into Many2OneField props + * and this component inherited props from Many2OneField + * So, must override props here to avoid constraint validateProps (props schema) in owl core + */ +Many2OneAvatarField.props = { + ...Many2OneAvatarField.props, + searchMore: {type: Boolean, optional: true}, + nodeOptions: {type: Object, optional: true}, +}; + +/** + * FIXME: find better way to extend props in Many2OneField + * Override mailing_m2o_filter + * Since extracted/added props: nodeOptions and searchMore into Many2OneField props + * and this component inherited props from Many2OneField + * So, must override props here to avoid constraint validateProps (props schema) in owl core + * This component is in module mass_mailing as optional module, + * So need to import dynamic way + */ +try { + (async () => { + // Make sure component mailing_m2o_filter in mass mailing module loaded + const installed_mass_mailing = await odoo.ready( + "@mass_mailing/js/mailing_m2o_filter" + ); + if (installed_mass_mailing) { + const {FieldMany2OneMailingFilter} = await odoo.runtimeImport( + "@mass_mailing/js/mailing_m2o_filter" + ); + FieldMany2OneMailingFilter.props = { + ...FieldMany2OneMailingFilter.props, + searchMore: {type: Boolean, optional: true}, + nodeOptions: {type: Object, optional: true}, + }; + } + })(); +} catch { + console.log( + "Ignore overriding props of component mailing_m2o_filter since the module is not installed" + ); +} + +/** + * X2ManyField + **/ +patch(X2ManyField.prototype, "web_m2x_options.X2ManyField", { + /** + * @override + */ + async openRecord(record) { + var self = this; + var open = this.props.open; + if (open && self.props.readonly) { + var res_id = record.data.id; + const action = await self.env.model.orm.call( + self.props.value.resModel, + "get_formview_action", + [[res_id]] + ); + return self.env.model.actionService.doAction(action); + } + return this._super.apply(this, arguments); + }, +}); + +const X2ManyFieldExtractProps = X2ManyField.extractProps; +X2ManyField.extractProps = ({attrs}) => { + const canOpen = Boolean(attrs.options.open); + return Object.assign(X2ManyFieldExtractProps({attrs}), { + open: canOpen, + }); +}; + +X2ManyField.props = { + ...X2ManyField.props, + open: {type: Boolean, optional: true}, +}; + +/** + * FormController + **/ +patch(FormController.prototype, "web_m2x_options.FormController", { + /** + * @override + */ + setup() { + var self = this; + this._super(...arguments); + + /** Due to problem of 2 onWillStart in native web core + * (see: https://github.com/odoo/odoo/blob/16.0/addons/web/static/src/views/model.js#L142) + * do the trick to override beforeLoadResolver here to customize viewLimit + */ + this.superBeforeLoadResolver = this.beforeLoadResolver; + this.beforeLoadResolver = async () => { + await self._setSubViewLimit(); + self.superBeforeLoadResolver(); + }; + }, + /** + * @override + * add more method to add subview limit on formview + */ + async _setSubViewLimit() { + const ir_options = Component.env.session.web_m2x_options; + + const activeFields = this.archInfo.activeFields, + fields = this.props.fields, + isSmall = this.user; + + var limit = ir_options["web_m2x_options.field_limit_entries"]; + if (!_.isUndefined(limit)) { + limit = parseInt(limit, 10); + } + + for (const fieldName in activeFields) { + const field = fields[fieldName]; + if (!isX2Many(field)) { + // What follows only concerns x2many fields + continue; + } + const fieldInfo = activeFields[fieldName]; + if (fieldInfo.modifiers.invisible === true) { + // No need to fetch the sub view if the field is always invisible + continue; + } + + if (!fieldInfo.FieldComponent.useSubView) { + // The FieldComponent used to render the field doesn't need a sub view + continue; + } + + let viewType = fieldInfo.viewMode || "list,kanban"; + viewType = viewType.replace("tree", "list"); + if (viewType.includes(",")) { + viewType = isSmall ? "kanban" : "list"; + } + fieldInfo.viewMode = viewType; + if (fieldInfo.views[viewType] && limit) { + fieldInfo.views[viewType].limit = limit; + } + } + }, +}); diff --git a/addons/web_m2x_options/static/src/components/relational_utils.esm.js b/addons/web_m2x_options/static/src/components/relational_utils.esm.js new file mode 100644 index 0000000..1fbe39e --- /dev/null +++ b/addons/web_m2x_options/static/src/components/relational_utils.esm.js @@ -0,0 +1,221 @@ +/** @odoo-module **/ + +import {Many2XAutocomplete} from "@web/views/fields/relational_utils"; +import {patch} from "@web/core/utils/patch"; +import {sprintf} from "@web/core/utils/strings"; +const {Component} = owl; + +export function is_option_set(option) { + if (_.isUndefined(option)) return false; + if (typeof option === "string") return option === "true" || option === "True"; + if (typeof option === "boolean") return option; + return false; +} + +patch(Many2XAutocomplete.prototype, "web_m2x_options.Many2XAutocomplete", { + setup() { + this._super(...arguments); + this.ir_options = Component.env.session.web_m2x_options; + }, + + async loadOptionsSource(request) { + if (this.lastProm) { + this.lastProm.abort(false); + } + // Add options limit used to change number of selections record + // returned. + if (!_.isUndefined(this.ir_options["web_m2x_options.limit"])) { + this.props.searchLimit = parseInt( + this.ir_options["web_m2x_options.limit"], + 10 + ); + this.limit = this.props.searchLimit; + } + + if (typeof this.props.nodeOptions.limit === "number") { + this.props.searchLimit = this.props.nodeOptions.limit; + this.limit = this.props.searchLimit; + } + + // Add options field_color and colors to color item(s) depending on field_color value + this.field_color = this.props.nodeOptions.field_color; + this.colors = this.props.nodeOptions.colors; + + this.lastProm = this.orm.call(this.props.resModel, "name_search", [], { + name: request, + operator: "ilike", + args: this.props.getDomain(), + limit: this.props.searchLimit + 1, + context: this.props.context, + }); + const records = await this.lastProm; + + var options = records.map((result) => ({ + value: result[0], + id: result[0], + label: result[1].split("\n")[0], + })); + + // Limit results if there is a custom limit options + if (this.limit) { + options = options.slice(0, this.props.searchLimit); + } + + // Search result value colors + if (this.colors && this.field_color) { + var value_ids = options.map((result) => result.value); + const objects = await this.orm.call( + this.props.resModel, + "search_read", + [], + { + domain: [["id", "in", value_ids]], + fields: [this.field_color], + } + ); + for (var index in objects) { + for (var index_value in options) { + if (options[index_value].id === objects[index].id) { + // Find value in values by comparing ids + var option = options[index_value]; + // Find color with field value as key + var color = + this.colors[objects[index][this.field_color]] || "black"; + option.style = "color:" + color; + break; + } + } + } + } + + // Quick create + // Note: Create should be before `search_more` (reserve native order) + // One more reason: when calling `onInputBlur`, native select the first option (activeSourceOption) + // which triggers m2o_dialog if m2o_dialog=true + var create_enabled = + this.props.quickCreate && !this.props.nodeOptions.no_create; + + var raw_result = _.map(records, function (x) { + return x[1]; + }); + var quick_create = is_option_set(this.props.nodeOptions.create), + quick_create_undef = _.isUndefined(this.props.nodeOptions.create), + m2x_create_undef = _.isUndefined(this.ir_options["web_m2x_options.create"]), + m2x_create = is_option_set(this.ir_options["web_m2x_options.create"]); + var show_create = + (!this.props.nodeOptions && (m2x_create_undef || m2x_create)) || + (this.props.nodeOptions && + (quick_create || + (quick_create_undef && (m2x_create_undef || m2x_create)))); + if ( + create_enabled && + !this.props.nodeOptions.no_quick_create && + request.length > 0 && + !_.contains(raw_result, request) && + show_create + ) { + options.push({ + label: sprintf(this.env._t(`Create "%s"`), request), + classList: "o_m2o_dropdown_option o_m2o_dropdown_option_create", + action: async (params) => { + try { + await this.props.quickCreate(request, params); + } catch { + const context = this.getCreationContext(request); + return this.openMany2X({context}); + } + }, + }); + } + + // Search more... + // Resolution order: + // 1- check if "search_more" is set locally in node's options + // 2- if set locally, apply its value + // 3- if not set locally, check if it's set globally via ir.config_parameter + // 4- if set globally, apply its value + // 5- if not set globally either, check if returned values are more than node's limit + var search_more = false; + if (!_.isUndefined(this.props.nodeOptions.search_more)) { + search_more = is_option_set(this.props.nodeOptions.search_more); + } else if (!_.isUndefined(this.ir_options["web_m2x_options.search_more"])) { + search_more = is_option_set(this.ir_options["web_m2x_options.search_more"]); + } else { + search_more = + !this.props.noSearchMore && this.props.searchLimit < records.length; + } + if (search_more) { + options.push({ + label: this.env._t("Search More..."), + action: this.onSearchMore.bind(this, request), + classList: "o_m2o_dropdown_option o_m2o_dropdown_option_search_more", + }); + } + + // Create and Edit + const canCreateEdit = + "createEdit" in this.activeActions + ? this.activeActions.createEdit + : this.activeActions.create; + if ( + !request.length && + !this.props.value && + (this.props.quickCreate || canCreateEdit) + ) { + options.push({ + label: this.env._t("Start typing..."), + classList: "o_m2o_start_typing", + unselectable: true, + }); + } + + // Create and edit ... + var create_edit = + is_option_set(this.props.nodeOptions.create) || + is_option_set(this.props.nodeOptions.create_edit), + create_edit_undef = + _.isUndefined(this.props.nodeOptions.create) && + _.isUndefined(this.props.nodeOptions.create_edit), + m2x_create_edit_undef = _.isUndefined( + this.ir_options["web_m2x_options.create_edit"] + ), + m2x_create_edit = is_option_set( + this.ir_options["web_m2x_options.create_edit"] + ); + var show_create_edit = + (!this.props.nodeOptions && (m2x_create_edit_undef || m2x_create_edit)) || + (this.props.nodeOptions && + (create_edit || + (create_edit_undef && (m2x_create_edit_undef || m2x_create_edit)))); + if ( + create_enabled && + !this.props.nodeOptions.no_create_edit && + show_create_edit && + request.length && + canCreateEdit + ) { + const context = this.getCreationContext(request); + options.push({ + label: this.env._t("Create and edit..."), + classList: "o_m2o_dropdown_option o_m2o_dropdown_option_create_edit", + action: () => this.openMany2X({context}), + }); + } + + // No records + if (!records.length && !this.activeActions.create) { + options.push({ + label: this.env._t("No records"), + classList: "o_m2o_no_result", + unselectable: true, + }); + } + + return options; + }, +}); + +Many2XAutocomplete.defaultProps = { + ...Many2XAutocomplete.defaultProps, + nodeOptions: {}, +}; diff --git a/addons/web_m2x_options/tests/__init__.py b/addons/web_m2x_options/tests/__init__.py new file mode 100644 index 0000000..b472ff3 --- /dev/null +++ b/addons/web_m2x_options/tests/__init__.py @@ -0,0 +1,2 @@ +# Copyright 2020 initOS GmbH. +from . import test_ir_config_parameter diff --git a/addons/web_m2x_options/tests/test_ir_config_parameter.py b/addons/web_m2x_options/tests/test_ir_config_parameter.py new file mode 100644 index 0000000..eae00c7 --- /dev/null +++ b/addons/web_m2x_options/tests/test_ir_config_parameter.py @@ -0,0 +1,28 @@ +# Copyright 2020 initOS GmbH. +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). + +from odoo.tests import common + + +class TestIrConfigParameter(common.TransactionCase): + @classmethod + def setUpClass(cls): + super(TestIrConfigParameter, cls).setUpClass() + cls.env["ir.config_parameter"].set_param("web_m2x_options.limit", 10) + cls.env["ir.config_parameter"].set_param("web_m2x_options.create_edit", "True") + cls.env["ir.config_parameter"].set_param("web_m2x_options.create", "True") + cls.env["ir.config_parameter"].set_param("web_m2x_options.search_more", "False") + cls.env["ir.config_parameter"].set_param("web_m2x_options.m2o_dialog", "True") + + def test_web_m2x_options_key(self): + web_m2x_options = self.env["ir.config_parameter"].get_web_m2x_options() + self.assertIn("web_m2x_options.limit", web_m2x_options) + self.assertNotIn("web_m2x_options.m2o_dialog_test", web_m2x_options) + + def test_web_m2x_options_value(self): + web_m2x_options = self.env["ir.config_parameter"].get_web_m2x_options() + self.assertEqual(web_m2x_options["web_m2x_options.limit"], "10") + self.assertTrue(bool(web_m2x_options["web_m2x_options.create_edit"])) + self.assertTrue(bool(web_m2x_options["web_m2x_options.create"])) + self.assertEqual(web_m2x_options["web_m2x_options.search_more"], "False") + self.assertTrue(bool(web_m2x_options["web_m2x_options.m2o_dialog"])) From d1a52de2b5f4dcec6c46941111da05475b097751 Mon Sep 17 00:00:00 2001 From: belloafeez Date: Thu, 1 Aug 2024 11:31:11 +0100 Subject: [PATCH 05/54] updated esc task deploy Signed-off-by: belloafeez --- odoo/add-ons.sh | 0 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 odoo/add-ons.sh diff --git a/odoo/add-ons.sh b/odoo/add-ons.sh deleted file mode 100644 index e69de29..0000000 From 4a03e91112aa907da35ea840b5218491c129c9ac Mon Sep 17 00:00:00 2001 From: belloafeez Date: Fri, 2 Aug 2024 09:46:29 +0100 Subject: [PATCH 06/54] udtaed --- .github/workflows/openems-deployment-td.json | 4 +- docker-compose.yml | 84 ++++++++++----- iac/ecs.tf | 4 +- odoo/Dockerfile | 104 ++++++++++++++++++- odoo/Odoo.config | 16 +++ 5 files changed, 179 insertions(+), 33 deletions(-) diff --git a/.github/workflows/openems-deployment-td.json b/.github/workflows/openems-deployment-td.json index e0c5975..6e49c48 100644 --- a/.github/workflows/openems-deployment-td.json +++ b/.github/workflows/openems-deployment-td.json @@ -91,7 +91,7 @@ }, { "name": "PASSWORD", - "value": "odoo16@2022" + "value": "odoo" }, { "name": "HOST", @@ -129,7 +129,7 @@ }, { "name": "POSTGRES_PASSWORD", - "value": "odoo16@2022 " + "value": "odoo" }, { "name": "POSTGRES_DB", diff --git a/docker-compose.yml b/docker-compose.yml index 3b7ba85..c7eaeea 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -22,20 +22,7 @@ services: build: context: ./openems-edge image: openems-edge:latest - - db: - build: - context: ./odoo-database - image: odoo-db - user: root - environment: - - POSTGRES_USER=odoo - - POSTGRES_PASSWORD=odoo16@2022 - - POSTGRES_DB=postgres - restart: always # run as a service - volumes: - - ./postgresql:/var/lib/postgresql/data - + odoo16: build: context: ./odoo @@ -44,23 +31,70 @@ services: depends_on: - db ports: - - "10016:8069" - - "20016:8072" # live chat - tty: true - command: -- + - "8069:8069" + volumes: + - odoo-web-data:/var/lib/odoo + - ./config:/etc/odoo + - ./addons:/mnt/extra-addons environment: - HOST=db - USER=odoo - - PASSWORD=odoo16@2022 + - PASSWORD=odoo # Replace 'odoo-password' with your actual password + db: + build: + context: ./odoo-database + image: odoo-db + user: root + environment: + - POSTGRES_DB=postgres + - POSTGRES_PASSWORD=odoo # Replace 'odoo-password' with your actual password + - POSTGRES_USER=odoo + - PGDATA=/var/lib/postgresql/data/pgdata volumes: - #- /etc/timezone:/etc/timezone:ro - #- /etc/localtime:/etc/localtime:ro - # - ./entrypoint.sh:/entrypoint.sh # if you want to install additional Python packages, uncomment this line! - - ./addons:/mnt/extra-addons - - ./etc:/etc/odoo - restart: always + - odoo-db-data:/var/lib/postgresql/data/pgdata +volumes: + odoo-web-data: + odoo-db-data: + # db: + # build: + # context: ./odoo-database + # image: odoo-db + # user: root + # environment: + # - POSTGRES_USER=odoo + # - POSTGRES_PASSWORD=odoo16@2022 + # - POSTGRES_DB=postgres + # restart: always # run as a service + # volumes: + # - ./postgresql:/var/lib/postgresql/data + + # odoo16: + # build: + # context: ./odoo + # image: odoo + # user: root + # depends_on: + # - db + # ports: + # - "10016:8069" + # - "20016:8072" # live chat + # tty: true + # command: -- + # environment: + # - HOST=db + # - USER=odoo + # - PASSWORD=odoo16@2022 + # volumes: + # #- /etc/timezone:/etc/timezone:ro + # #- /etc/localtime:/etc/localtime:ro + # # - ./entrypoint.sh:/entrypoint.sh # if you want to install additional Python packages, uncomment this line! + # - ./addons:/mnt/extra-addons + # - ./etc:/etc/odoo + # restart: always + + # openems-database: # build: diff --git a/iac/ecs.tf b/iac/ecs.tf index acc0c94..bf8ff0e 100644 --- a/iac/ecs.tf +++ b/iac/ecs.tf @@ -138,7 +138,7 @@ resource "aws_ecs_task_definition" "ecs_task_definition" { }, { name = "PASSWORD", - value = "odoo16@2022" + value = "odoo" } ] @@ -169,7 +169,7 @@ resource "aws_ecs_task_definition" "ecs_task_definition" { }, { name = "POSTGRES_PASSWORD", - value = "odoo16@2022 " + value = "odoo" }, { name = "POSTGRES_DB", diff --git a/odoo/Dockerfile b/odoo/Dockerfile index 23bcdbd..7481bed 100644 --- a/odoo/Dockerfile +++ b/odoo/Dockerfile @@ -1,7 +1,103 @@ -# Use Odoo 16.0 as the base image -FROM odoo:16.0 +FROM debian:bullseye-slim +SHELL ["/bin/bash", "-xo", "pipefail", "-c"] -# Expose port 8069 for Odoo web interface -EXPOSE 8069 \ No newline at end of file +# Generate locale C.UTF-8 for postgres and general locale data +ENV LANG C.UTF-8 + +# Retrieve the target architecture to install the correct wkhtmltopdf package +ARG TARGETARCH + +# Install some deps, lessc and less-plugin-clean-css, and wkhtmltopdf +RUN apt-get update && \ + apt-get install -y --no-install-recommends \ + ca-certificates \ + curl \ + dirmngr \ + fonts-noto-cjk \ + gnupg \ + libssl-dev \ + node-less \ + npm \ + python3-magic \ + python3-num2words \ + python3-odf \ + python3-pdfminer \ + python3-pip \ + python3-phonenumbers \ + python3-pyldap \ + python3-qrcode \ + python3-renderpm \ + python3-setuptools \ + python3-slugify \ + python3-vobject \ + python3-watchdog \ + python3-xlrd \ + python3-xlwt \ + xz-utils && \ + if [ -z "${TARGETARCH}" ]; then \ + TARGETARCH="$(dpkg --print-architecture)"; \ + fi; \ + WKHTMLTOPDF_ARCH=${TARGETARCH} && \ + case ${TARGETARCH} in \ + "amd64") WKHTMLTOPDF_ARCH=amd64 && WKHTMLTOPDF_SHA=9df8dd7b1e99782f1cfa19aca665969bbd9cc159 ;; \ + "arm64") WKHTMLTOPDF_SHA=58c84db46b11ba0e14abb77a32324b1c257f1f22 ;; \ + "ppc64le" | "ppc64el") WKHTMLTOPDF_ARCH=ppc64el && WKHTMLTOPDF_SHA=7ed8f6dcedf5345a3dd4eeb58dc89704d862f9cd ;; \ + esac \ + && curl -o wkhtmltox.deb -sSL https://github.com/wkhtmltopdf/packaging/releases/download/0.12.6.1-3/wkhtmltox_0.12.6.1-3.bullseye_${WKHTMLTOPDF_ARCH}.deb \ + && echo ${WKHTMLTOPDF_SHA} wkhtmltox.deb | sha1sum -c - \ + && apt-get install -y --no-install-recommends ./wkhtmltox.deb \ + && rm -rf /var/lib/apt/lists/* wkhtmltox.deb + +# install latest postgresql-client +RUN echo 'deb http://apt.postgresql.org/pub/repos/apt/ bullseye-pgdg main' > /etc/apt/sources.list.d/pgdg.list \ + && GNUPGHOME="$(mktemp -d)" \ + && export GNUPGHOME \ + && repokey='B97B0AFCAA1A47F044F244A07FCC7D46ACCC4CF8' \ + && gpg --batch --keyserver keyserver.ubuntu.com --recv-keys "${repokey}" \ + && gpg --batch --armor --export "${repokey}" > /etc/apt/trusted.gpg.d/pgdg.gpg.asc \ + && gpgconf --kill all \ + && rm -rf "$GNUPGHOME" \ + && apt-get update \ + && apt-get install --no-install-recommends -y postgresql-client \ + && rm -f /etc/apt/sources.list.d/pgdg.list \ + && rm -rf /var/lib/apt/lists/* + +# Install rtlcss (on Debian buster) +RUN npm install -g rtlcss + +# Install Odoo +ENV ODOO_VERSION 16.0 +ARG ODOO_RELEASE=20240624 +ARG ODOO_SHA=a51d6f097b24096d38959f4cd97ae5fb2cd2807b +RUN curl -o odoo.deb -sSL http://nightly.odoo.com/${ODOO_VERSION}/nightly/deb/odoo_${ODOO_VERSION}.${ODOO_RELEASE}_all.deb \ + && echo "${ODOO_SHA} odoo.deb" | sha1sum -c - \ + && apt-get update \ + && apt-get -y install --no-install-recommends ./odoo.deb \ + && rm -rf /var/lib/apt/lists/* odoo.deb + +# Copy entrypoint script and Odoo configuration file +COPY ./entrypoint.sh / +COPY ./odoo.conf /etc/odoo/ + +# Set permissions and Mount /var/lib/odoo to allow restoring filestore and /mnt/extra-addons for users addons +RUN chown odoo /etc/odoo/odoo.conf \ + && mkdir -p /mnt/extra-addons \ + && chown -R odoo /mnt/extra-addons +VOLUME ["/var/lib/odoo", "/mnt/extra-addons"] + +COPY ./extra-addons /mnt/extra-addons +# Expose Odoo services +EXPOSE 8069 8071 8072 + +# Set the default config file +ENV ODOO_RC /etc/odoo/odoo.conf + +COPY wait-for-psql.py /usr/local/bin/wait-for-psql.py + +# Set default user when running the container +USER odoo + +ENTRYPOINT ["/entrypoint.sh"] +CMD ["odoo"] \ No newline at end of file diff --git a/odoo/Odoo.config b/odoo/Odoo.config index e69de29..75705c9 100644 --- a/odoo/Odoo.config +++ b/odoo/Odoo.config @@ -0,0 +1,16 @@ +# Place in openems-backend/config.d/Metadata +:org.apache.felix.configadmin.revision:=L"2" +database="postgres" +debugMode="ON" +odooHost="localhost" +odooPassword="admin" +odooPort=I"8069" +odooProtocol="HTTP" +odooUid=I"2" +pgConnectionPoolSize=I"40" +pgHost="localhost" +pgPassword="odoo" +pgPort=I"5432" +pgUser="odoo" +poolSize=I"30" +service.pid="Metadata.Odoo" \ No newline at end of file From 4eb879a2b25cf57c7ecdf4e2bbafc77ab3c86292 Mon Sep 17 00:00:00 2001 From: belloafeez Date: Thu, 1 Aug 2024 08:35:34 +0100 Subject: [PATCH 07/54] Signed-off-by: belloafeez Added all files for odoo Signed-off-by: belloafeez --- odoo/Odoo.config | 0 odoo/add-ons.sh | 0 odoo/entrypoint.sh | 49 +++++++++++++++++++++++++++++++++++++++++++ odoo/odoo.conf | 37 ++++++++++++++++++++++++++++++++ odoo/wait-for-psql.py | 32 ++++++++++++++++++++++++++++ 5 files changed, 118 insertions(+) create mode 100644 odoo/Odoo.config create mode 100644 odoo/add-ons.sh create mode 100644 odoo/entrypoint.sh create mode 100644 odoo/odoo.conf create mode 100644 odoo/wait-for-psql.py diff --git a/odoo/Odoo.config b/odoo/Odoo.config new file mode 100644 index 0000000..e69de29 diff --git a/odoo/add-ons.sh b/odoo/add-ons.sh new file mode 100644 index 0000000..e69de29 diff --git a/odoo/entrypoint.sh b/odoo/entrypoint.sh new file mode 100644 index 0000000..f802bcb --- /dev/null +++ b/odoo/entrypoint.sh @@ -0,0 +1,49 @@ +#!/bin/bash + +set -e + +if [ -v PASSWORD_FILE ]; then + PASSWORD="$(< $PASSWORD_FILE)" +fi + +# set the postgres database host, port, user and password according to the environment +# and pass them as arguments to the odoo process if not present in the config file +: ${HOST:=${DB_PORT_5432_TCP_ADDR:='db'}} +: ${PORT:=${DB_PORT_5432_TCP_PORT:=5432}} +: ${USER:=${DB_ENV_POSTGRES_USER:=${POSTGRES_USER:='odoo'}}} +: ${PASSWORD:=${DB_ENV_POSTGRES_PASSWORD:=${POSTGRES_PASSWORD:='odoo'}}} + +DB_ARGS=() +function check_config() { + param="$1" + value="$2" + if grep -q -E "^\s*\b${param}\b\s*=" "$ODOO_RC" ; then + value=$(grep -E "^\s*\b${param}\b\s*=" "$ODOO_RC" |cut -d " " -f3|sed 's/["\n\r]//g') + fi; + DB_ARGS+=("--${param}") + DB_ARGS+=("${value}") +} +check_config "db_host" "$HOST" +check_config "db_port" "$PORT" +check_config "db_user" "$USER" +check_config "db_password" "$PASSWORD" + +case "$1" in + -- | odoo) + shift + if [[ "$1" == "scaffold" ]] ; then + exec odoo "$@" + else + wait-for-psql.py ${DB_ARGS[@]} --timeout=30 + exec odoo "$@" "${DB_ARGS[@]}" + fi + ;; + -*) + wait-for-psql.py ${DB_ARGS[@]} --timeout=30 + exec odoo "$@" "${DB_ARGS[@]}" + ;; + *) + exec "$@" +esac + +exit 1 diff --git a/odoo/odoo.conf b/odoo/odoo.conf new file mode 100644 index 0000000..28f70c1 --- /dev/null +++ b/odoo/odoo.conf @@ -0,0 +1,37 @@ +[options] +addons_path = /mnt/extra-addons +data_dir = /var/lib/odoo +; admin_passwd = admin +; csv_internal_sep = , +; db_maxconn = 64 +; db_name = False +; db_template = template1 +; dbfilter = .* +; debug_mode = False +; email_from = False +; limit_memory_hard = 2684354560 +; limit_memory_soft = 2147483648 +; limit_request = 8192 +; limit_time_cpu = 60 +; limit_time_real = 120 +; list_db = True +; log_db = False +; log_handler = [':INFO'] +; log_level = info +; logfile = None +; longpolling_port = 8072 +; max_cron_threads = 2 +; osv_memory_age_limit = 1.0 +; osv_memory_count_limit = False +; smtp_password = False +; smtp_port = 25 +; smtp_server = localhost +; smtp_ssl = False +; smtp_user = False +; workers = 0 +; xmlrpc = True +; xmlrpc_interface = +; xmlrpc_port = 8069 +; xmlrpcs = True +; xmlrpcs_interface = +; xmlrpcs_port = 8071 diff --git a/odoo/wait-for-psql.py b/odoo/wait-for-psql.py new file mode 100644 index 0000000..a55f440 --- /dev/null +++ b/odoo/wait-for-psql.py @@ -0,0 +1,32 @@ +#!/usr/bin/env python3 +import argparse +import psycopg2 +import sys +import time + + +if __name__ == '__main__': + arg_parser = argparse.ArgumentParser() + arg_parser.add_argument('--db_host', required=True) + arg_parser.add_argument('--db_port', required=True) + arg_parser.add_argument('--db_user', required=True) + arg_parser.add_argument('--db_password', required=True) + arg_parser.add_argument('--timeout', type=int, default=5) + + args = arg_parser.parse_args() + + start_time = time.time() + while (time.time() - start_time) < args.timeout: + try: + conn = psycopg2.connect(user=args.db_user, host=args.db_host, port=args.db_port, password=args.db_password, dbname='postgres') + error = '' + break + except psycopg2.OperationalError as e: + error = e + else: + conn.close() + time.sleep(1) + + if error: + print("Database connection failure: %s" % error, file=sys.stderr) + sys.exit(1) From ce673abf6095b57691fd1590b76db2668440b421 Mon Sep 17 00:00:00 2001 From: belloafeez Date: Thu, 1 Aug 2024 09:49:27 +0100 Subject: [PATCH 08/54] docker compose updated Signed-off-by: belloafeez --- docker-compose.yml | 84 ++++++++++++++++++++++++++++++++-------------- 1 file changed, 59 insertions(+), 25 deletions(-) diff --git a/docker-compose.yml b/docker-compose.yml index 3b7ba85..c7eaeea 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -22,20 +22,7 @@ services: build: context: ./openems-edge image: openems-edge:latest - - db: - build: - context: ./odoo-database - image: odoo-db - user: root - environment: - - POSTGRES_USER=odoo - - POSTGRES_PASSWORD=odoo16@2022 - - POSTGRES_DB=postgres - restart: always # run as a service - volumes: - - ./postgresql:/var/lib/postgresql/data - + odoo16: build: context: ./odoo @@ -44,23 +31,70 @@ services: depends_on: - db ports: - - "10016:8069" - - "20016:8072" # live chat - tty: true - command: -- + - "8069:8069" + volumes: + - odoo-web-data:/var/lib/odoo + - ./config:/etc/odoo + - ./addons:/mnt/extra-addons environment: - HOST=db - USER=odoo - - PASSWORD=odoo16@2022 + - PASSWORD=odoo # Replace 'odoo-password' with your actual password + db: + build: + context: ./odoo-database + image: odoo-db + user: root + environment: + - POSTGRES_DB=postgres + - POSTGRES_PASSWORD=odoo # Replace 'odoo-password' with your actual password + - POSTGRES_USER=odoo + - PGDATA=/var/lib/postgresql/data/pgdata volumes: - #- /etc/timezone:/etc/timezone:ro - #- /etc/localtime:/etc/localtime:ro - # - ./entrypoint.sh:/entrypoint.sh # if you want to install additional Python packages, uncomment this line! - - ./addons:/mnt/extra-addons - - ./etc:/etc/odoo - restart: always + - odoo-db-data:/var/lib/postgresql/data/pgdata +volumes: + odoo-web-data: + odoo-db-data: + # db: + # build: + # context: ./odoo-database + # image: odoo-db + # user: root + # environment: + # - POSTGRES_USER=odoo + # - POSTGRES_PASSWORD=odoo16@2022 + # - POSTGRES_DB=postgres + # restart: always # run as a service + # volumes: + # - ./postgresql:/var/lib/postgresql/data + + # odoo16: + # build: + # context: ./odoo + # image: odoo + # user: root + # depends_on: + # - db + # ports: + # - "10016:8069" + # - "20016:8072" # live chat + # tty: true + # command: -- + # environment: + # - HOST=db + # - USER=odoo + # - PASSWORD=odoo16@2022 + # volumes: + # #- /etc/timezone:/etc/timezone:ro + # #- /etc/localtime:/etc/localtime:ro + # # - ./entrypoint.sh:/entrypoint.sh # if you want to install additional Python packages, uncomment this line! + # - ./addons:/mnt/extra-addons + # - ./etc:/etc/odoo + # restart: always + + # openems-database: # build: From 8f94e3d4e721888520e12879c81db2b9edea0a1c Mon Sep 17 00:00:00 2001 From: belloafeez Date: Thu, 1 Aug 2024 11:31:11 +0100 Subject: [PATCH 09/54] updated esc task deploy Signed-off-by: belloafeez --- odoo/add-ons.sh | 0 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 odoo/add-ons.sh diff --git a/odoo/add-ons.sh b/odoo/add-ons.sh deleted file mode 100644 index e69de29..0000000 From cb37465ad017f79d7217e2a935e3976e7c91806b Mon Sep 17 00:00:00 2001 From: belloafeez Date: Thu, 1 Aug 2024 10:24:53 +0100 Subject: [PATCH 10/54] docker compose update Signed-off-by: belloafeez --- SECURITY.md | 14 -- ] | 13 -- docker-compose.yml | 84 +++------ entrypoint.sh | 51 ------ etc/odoo.conf | 400 ------------------------------------------- etc/requirements.txt | 8 - run.sh | 19 -- 7 files changed, 25 insertions(+), 564 deletions(-) delete mode 100644 SECURITY.md delete mode 100644 ] delete mode 100644 entrypoint.sh delete mode 100644 etc/odoo.conf delete mode 100644 etc/requirements.txt delete mode 100644 run.sh diff --git a/SECURITY.md b/SECURITY.md deleted file mode 100644 index 29fab47..0000000 --- a/SECURITY.md +++ /dev/null @@ -1,14 +0,0 @@ -# Security Policy - -See https://github.com/energy-iot/docs/security/policy - -## Supported Versions - -All versions of Energy IoT Open source strive to keep up of critical and high vulnarabilities patches when available. - -https://github.com/OpenEMS/openems/releases/tag/2024.2.0 -https://github.com/OpenEMS/openems/releases/tag/2023.11.0 - -## Reporting a Vulnerability - -See https://github.com/energy-iot/docs/security/policy diff --git a/] b/] deleted file mode 100644 index 5c11fac..0000000 --- a/] +++ /dev/null @@ -1,13 +0,0 @@ - - -Signed-off-by: belloafeez - -# Please enter the commit message for your changes. Lines starting -# with '#' will be ignored, and an empty message aborts the commit. -# -# On branch axmsoftware-new -# Changes to be committed: -# modified: .github/workflows/deploy-pipeline.yml - - -destroy pipeline diff --git a/docker-compose.yml b/docker-compose.yml index c7eaeea..3b7ba85 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -22,7 +22,20 @@ services: build: context: ./openems-edge image: openems-edge:latest - + + db: + build: + context: ./odoo-database + image: odoo-db + user: root + environment: + - POSTGRES_USER=odoo + - POSTGRES_PASSWORD=odoo16@2022 + - POSTGRES_DB=postgres + restart: always # run as a service + volumes: + - ./postgresql:/var/lib/postgresql/data + odoo16: build: context: ./odoo @@ -31,70 +44,23 @@ services: depends_on: - db ports: - - "8069:8069" - volumes: - - odoo-web-data:/var/lib/odoo - - ./config:/etc/odoo - - ./addons:/mnt/extra-addons + - "10016:8069" + - "20016:8072" # live chat + tty: true + command: -- environment: - HOST=db - USER=odoo - - PASSWORD=odoo # Replace 'odoo-password' with your actual password - db: - build: - context: ./odoo-database - image: odoo-db - user: root - environment: - - POSTGRES_DB=postgres - - POSTGRES_PASSWORD=odoo # Replace 'odoo-password' with your actual password - - POSTGRES_USER=odoo - - PGDATA=/var/lib/postgresql/data/pgdata + - PASSWORD=odoo16@2022 volumes: - - odoo-db-data:/var/lib/postgresql/data/pgdata -volumes: - odoo-web-data: - odoo-db-data: - - # db: - # build: - # context: ./odoo-database - # image: odoo-db - # user: root - # environment: - # - POSTGRES_USER=odoo - # - POSTGRES_PASSWORD=odoo16@2022 - # - POSTGRES_DB=postgres - # restart: always # run as a service - # volumes: - # - ./postgresql:/var/lib/postgresql/data + #- /etc/timezone:/etc/timezone:ro + #- /etc/localtime:/etc/localtime:ro + # - ./entrypoint.sh:/entrypoint.sh # if you want to install additional Python packages, uncomment this line! + - ./addons:/mnt/extra-addons + - ./etc:/etc/odoo + restart: always - # odoo16: - # build: - # context: ./odoo - # image: odoo - # user: root - # depends_on: - # - db - # ports: - # - "10016:8069" - # - "20016:8072" # live chat - # tty: true - # command: -- - # environment: - # - HOST=db - # - USER=odoo - # - PASSWORD=odoo16@2022 - # volumes: - # #- /etc/timezone:/etc/timezone:ro - # #- /etc/localtime:/etc/localtime:ro - # # - ./entrypoint.sh:/entrypoint.sh # if you want to install additional Python packages, uncomment this line! - # - ./addons:/mnt/extra-addons - # - ./etc:/etc/odoo - # restart: always - - # openems-database: # build: diff --git a/entrypoint.sh b/entrypoint.sh deleted file mode 100644 index bde63c8..0000000 --- a/entrypoint.sh +++ /dev/null @@ -1,51 +0,0 @@ -#!/bin/bash - -set -e - -# set the postgres database host, port, user and password according to the environment -# and pass them as arguments to the odoo process if not present in the config file -: ${HOST:=${DB_PORT_5432_TCP_ADDR:='db'}} -: ${PORT:=${DB_PORT_5432_TCP_PORT:=5432}} -: ${USER:=${DB_ENV_POSTGRES_USER:=${POSTGRES_USER:='odoo'}}} -: ${PASSWORD:=${DB_ENV_POSTGRES_PASSWORD:=${POSTGRES_PASSWORD:='odoo16@2022'}}} - -# install python packages -pip3 install pip --upgrade -pip3 install -r /etc/odoo/requirements.txt - -# sed -i 's|raise werkzeug.exceptions.BadRequest(msg)|self.jsonrequest = {}|g' /usr/lib/python3/dist-packages/odoo/http.py - -DB_ARGS=() -function check_config() { - param="$1" - value="$2" - if grep -q -E "^\s*\b${param}\b\s*=" "$ODOO_RC" ; then - value=$(grep -E "^\s*\b${param}\b\s*=" "$ODOO_RC" |cut -d " " -f3|sed 's/["\n\r]//g') - fi; - DB_ARGS+=("--${param}") - DB_ARGS+=("${value}") -} -check_config "db_host" "$HOST" -check_config "db_port" "$PORT" -check_config "db_user" "$USER" -check_config "db_password" "$PASSWORD" - -case "$1" in - -- | odoo) - shift - if [[ "$1" == "scaffold" ]] ; then - exec odoo "$@" - else - wait-for-psql.py ${DB_ARGS[@]} --timeout=30 - exec odoo "$@" "${DB_ARGS[@]}" - fi - ;; - -*) - wait-for-psql.py ${DB_ARGS[@]} --timeout=30 - exec odoo "$@" "${DB_ARGS[@]}" - ;; - *) - exec "$@" -esac - -exit 1 \ No newline at end of file diff --git a/etc/odoo.conf b/etc/odoo.conf deleted file mode 100644 index f7b2fc6..0000000 --- a/etc/odoo.conf +++ /dev/null @@ -1,400 +0,0 @@ -[options] -; =================== -; | Common options) | -; =================== -; ------ -; -c / --config | specify alternate config file -; ------ -; config = - -; ------ -; -s / --save | save configuration to ~/.odoorc (or to ~/.openerp_serverrc if it exists) -; ------ -; save = - -; ------ -; -i / --init | install one or more modules (comma-separated list, use "all" for all modules), requires -d -; ------ -; init = - -; ------ -; -u / --update | update one or more modules (comma-separated list, use "all" for all modules). Requires -d. -; ------ -; update = - -; ------ -; --without-demo | disable loading demo data for modules to be installed (comma-separated, use "all" for all modules). Requires -d and -i. Default is %default -; ------ -; without_demo = - -; ------ -; -P / --import-partial | Use this for big data importation, if it crashes you will be able to continue at the current state. Provide a filename to store intermediate importation states. -; ------ -; import_partial = - -; ------ -; --pidfile | file where the server pid will be stored -; ------ -; pidfile = - -; ------ -; --addons-path | type = string | specify additional addons paths (separated by commas). -; ------ -addons_path = /mnt/extra-addons - -; ------ -; --upgrade-path | type = string | specify an additional upgrade path. -; ------ -; upgrade_path = - -; ------ -; --load | Comma-separated list of server-wide modules. -; ------ -; server_wide_modules = base,web - -; ------ -; -D / --data-dir | Directory where to store Odoo data -; ------ -data_dir = /etc/odoo - -admin_passwd = openemspassword - -; ============================== -; | HTTP Service Configuration | -; ============================== -; ------ -; --http-interface | Listen interface address for HTTP services. Keep empty to listen on all interfaces (0.0.0.0) -; ------ -; http_interface = - -; ------ -; -p / --http-port | type = int | Listen port for the main HTTP service -; ------ -; http_port = 8069 - -; ------ -; --longpolling-port | type = int | Listen port for the longpolling HTTP service -; ------ -; longpolling_port = 8072 - -; ------ -; --no-http | Disable the HTTP and Longpolling services entirely -; ------ -; http_enable = True - -; ------ -; --proxy-mode | Activate reverse proxy WSGI wrappers (headers rewriting) Only enable this when running behind a trusted web proxy! -; ------ -; proxy_mode = - -; ------ -; --xmlrpc-interface | SUPPRESSHELP -; ------ -; http_interface = - -; ------ -; --xmlrpc-port | type = int | SUPPRESSHELP -; ------ -; http_port = - -; ------ -; --no-xmlrpc | SUPPRESSHELP -; ------ -; http_enable = - -; =============================== -; | Web interface Configuration | -; =============================== -; ------ -; --db-filter | Regular expressions for filtering available databases for Web UI. The expression can use %d (domain) and %h (host) placeholders. -; ------ -; dbfilter = - -; ========================= -; | Testing Configuration | -; ========================= -; ------ -; --test-file | Launch a python test file. -; ------ -; test_file = - -; ------ -; --test-enable | Enable unit tests. -; ------ -; test_enable = - -; ------ -; --test-tags | Comma-separated list of spec to filter which tests to execute. Enable unit tests if set. A filter spec has the format: [-][tag][/module][:class][.method] The '-' specifies if we want to include or exclude tests matching this spec. The tag will match tags added on a class with a @tagged decorator. By default tag value is 'standard' when not given on include mode. '*' will match all tags. Tag will also match module name (deprecated, use /module) The module, class, and method will respectively match the module name, test class name and test method name. examples: :TestClass.test_func,/test_module,external -; ------ -; test_tags = - -; ------ -; --screencasts | Screencasts will go in DIR/{db_name}/screencasts. -; ------ -; screencasts = - -; ------ -; --screenshots | Screenshots will go in DIR/{db_name}/screenshots. Defaults to /etc/odoo/odoo_tests. -; ------ -; screenshots = /etc/odoo/odoo_tests - -; ========================= -; | Logging Configuration | -; ========================= -; ------ -; --logfile | file where the server log will be stored -; ------ -logfile = /etc/odoo/odoo-server.log - -; ------ -; --syslog | Send the log to the syslog server -; ------ -; syslog = - -; ------ -; --log-handler | setup a handler at LEVEL for a given PREFIX. An empty PREFIX indicates the root logger. This option can be repeated. Example: "odoo.orm:DEBUG" or "werkzeug:CRITICAL" (default: ":INFO") -; ------ -; None = :INFO - -; ------ -; --log-request | shortcut for --log-handler=odoo.http.rpc.request:DEBUG -; ------ -; log_handler = - -; ------ -; --log-response | shortcut for --log-handler=odoo.http.rpc.response:DEBUG -; ------ -; log_handler = - -; ------ -; --log-web | shortcut for --log-handler=odoo.http:DEBUG -; ------ -; log_handler = - -; ------ -; --log-sql | shortcut for --log-handler=odoo.sql_db:DEBUG -; ------ -; log_handler = - -; ------ -; --log-db | Logging database -; ------ -; log_db = - -; ------ -; --log-db-level | Logging database level -; ------ -; log_db_level = warning - -; ------ -; --log-level | type = choice | choices = ['info', 'debug_rpc', 'warn', 'test', 'critical', 'runbot', 'debug_sql', 'error', 'debug', 'debug_rpc_answer', 'notset'] | specify the level of the logging. Accepted values: ['info', 'debug_rpc', 'warn', 'test', 'critical', 'runbot', 'debug_sql', 'error', 'debug', 'debug_rpc_answer', 'notset']. -; ------ -; log_level = info - -; ====================== -; | SMTP Configuration | -; ====================== -; ------ -; --email-from | specify the SMTP email address for sending email -; ------ -; email_from = - -; ------ -; --smtp | specify the SMTP server for sending email -; ------ -; smtp_server = localhost - -; ------ -; --smtp-port | type = int | specify the SMTP port -; ------ -; smtp_port = 25 - -; ------ -; --smtp-ssl | if passed, SMTP connections will be encrypted with SSL (STARTTLS) -; ------ -; smtp_ssl = - -; ------ -; --smtp-user | specify the SMTP username for sending email -; ------ -; smtp_user = - -; ------ -; --smtp-password | specify the SMTP password for sending email -; ------ -; smtp_password = - -; ============================ -; | Database related options | -; ============================ -; ------ -; -d / --database | specify the database name -; ------ -; db_name = - -; ------ -; -r / --db_user | specify the database user name -; ------ -; db_user = - -; ------ -; -w / --db_password | specify the database password -; ------ -; db_password = - -; ------ -; --pg_path | specify the pg executable path -; ------ -; pg_path = - -; ------ -; --db_host | specify the database host -; ------ -; db_host = - -; ------ -; --db_port | type = int | specify the database port -; ------ -; db_port = - -; ------ -; --db_sslmode | type = choice | choices = ['disable', 'allow', 'prefer', 'require', 'verify-ca', 'verify-full'] | specify the database ssl connection mode (see PostgreSQL documentation) -; ------ -; db_sslmode = prefer - -; ------ -; --db_maxconn | type = int | specify the maximum number of physical connections to PostgreSQL -; ------ -; db_maxconn = 64 - -; ------ -; --db-template | specify a custom database template to create a new database -; ------ -; db_template = template0 - -; ======================== -; | Internationalisation | -; ======================== -; ------ -; --load-language | specifies the languages for the translations you want to be loaded -; ------ -; load_language = - -; ------ -; -l / --language | specify the language of the translation file. Use it with --i18n-export or --i18n-import -; ------ -; language = - -; ------ -; --i18n-export | export all sentences to be translated to a CSV file, a PO file or a TGZ archive and exit -; ------ -; translate_out = - -; ------ -; --i18n-import | import a CSV or a PO file with translations and exit. The '-l' option is required. -; ------ -; translate_in = - -; ------ -; --i18n-overwrite | overwrites existing translation terms on updating a module or importing a CSV or a PO file. -; ------ -; overwrite_existing_translations = - -; ------ -; --modules | specify modules to export. Use in combination with --i18n-export -; ------ -; translate_modules = - -; ============================ -; | Security-related options | -; ============================ -; ------ -; --no-database-list | Disable the ability to obtain or view the list of databases. Also disable access to the database manager and selector, so be sure to set a proper --database parameter first -; ------ -; list_db = True - -; ==================== -; | Advanced options | -; ==================== -; ------ -; --dev | type = string | Enable developer mode. Param: List of options separated by comma. Options : all, [pudb|wdb|ipdb|pdb], reload, qweb, werkzeug, xml -; ------ -dev_mode = reload - -; ------ -; --shell-interface | type = string | Specify a preferred REPL to use in shell mode. Supported REPLs are: [ipython|ptpython|bpython|python] -; ------ -; shell_interface = - -; ------ -; --stop-after-init | stop the server after its initialization -; ------ -; stop_after_init = - -; ------ -; --osv-memory-count-limit | type = int | Force a limit on the maximum number of records kept in the virtual osv_memory tables. The default is False, which means no count-based limit. -; ------ -; osv_memory_count_limit = - -; ------ -; --transient-age-limit | type = float | Time limit (decimal value in hours) records created with a TransientModel (mosly wizard) are kept in the database. Default to 1 hour. -; ------ -; transient_age_limit = 1.0 - -; ------ -; --osv-memory-age-limit | type = float | Deprecated alias to the transient-age-limit option -; ------ -; osv_memory_age_limit = - -; ------ -; --max-cron-threads | type = int | Maximum number of threads processing concurrently cron jobs (default 2). -; ------ -; max_cron_threads = 2 - -; ------ -; --unaccent | Try to enable the unaccent extension when creating new databases. -; ------ -; unaccent = - -; ------ -; --geoip-db | Absolute path to the GeoIP database file. -; ------ -; geoip_database = /usr/share/GeoIP/GeoLite2-City.mmdb - -; =========================== -; | Multiprocessing options | -; =========================== -; ------ -; --workers | type = int | Specify the number of workers, 0 disable prefork mode. -; ------ -; workers = - -; ------ -; --limit-memory-soft | type = int | Maximum allowed virtual memory per worker (in bytes), when reached the worker be reset after the current request (default 2048MiB). -; ------ -; limit_memory_soft = 2147483648 - -; ------ -; --limit-memory-hard | type = int | Maximum allowed virtual memory per worker (in bytes), when reached, any memory allocation will fail (default 2560MiB). -; ------ -; limit_memory_hard = 2684354560 - -; ------ -; --limit-time-cpu | type = int | Maximum allowed CPU time per request (default 60). -; ------ -; limit_time_cpu = 60 - -; ------ -; --limit-time-real | type = int | Maximum allowed Real time per request (default 120). -; ------ -; limit_time_real = 120 - -; ------ -; --limit-time-real-cron | type = int | Maximum allowed Real time per cron job. (default: --limit-time-real). Set to 0 for no limit. -; ------ -; limit_time_real_cron = -1 - -; ------ -; --limit-request | type = int | Maximum number of request to be processed per worker (default 8192). -; ------ -; limit_request = 8192 diff --git a/etc/requirements.txt b/etc/requirements.txt deleted file mode 100644 index 6853d72..0000000 --- a/etc/requirements.txt +++ /dev/null @@ -1,8 +0,0 @@ -# ----------------------- -# | Add Python packages | -# ----------------------- -# To install below packages at startup, uncomment this line in "docker-compose.yml" file! -# - ./entrypoint.sh:/entrypoint.sh -# then down the docker container ($ docker-compose down) and up it again ($ docker-compose up -d). -# ----------------------- -# paramiko==2.7.2 # for auto_backup module diff --git a/run.sh b/run.sh deleted file mode 100644 index 47ccd36..0000000 --- a/run.sh +++ /dev/null @@ -1,19 +0,0 @@ -#!/bin/bash -DESTINATION=$1 -PORT=$2 -CHAT=$3 -# clone Odoo directory -git clone --depth=1 https://github.com/minhng92/odoo-16-docker-compose $DESTINATION -rm -rf $DESTINATION/.git -# set permission -mkdir -p $DESTINATION/postgresql -sudo chmod -R 777 $DESTINATION -# config -if grep -qF "fs.inotify.max_user_watches" /etc/sysctl.conf; then echo $(grep -F "fs.inotify.max_user_watches" /etc/sysctl.conf); else echo "fs.inotify.max_user_watches = 524288" | sudo tee -a /etc/sysctl.conf; fi -sudo sysctl -p -sed -i 's/10016/'$PORT'/g' $DESTINATION/docker-compose.yml -sed -i 's/20016/'$CHAT'/g' $DESTINATION/docker-compose.yml -# run Odoo -docker-compose -f $DESTINATION/docker-compose.yml up -d - -echo 'Started Odoo @ http://localhost:'$PORT' | Master Password: minhng.info | Live chat port: '$CHAT From ab3ebf16f9a75d8b3103b9c4d4bbc692d60da84a Mon Sep 17 00:00:00 2001 From: belloafeez Date: Fri, 2 Aug 2024 09:46:29 +0100 Subject: [PATCH 11/54] udtaed Signed-off-by: belloafeez --- .github/workflows/openems-deployment-td.json | 4 +- docker-compose.yml | 84 ++++++++++----- iac/ecs.tf | 4 +- odoo/Dockerfile | 104 ++++++++++++++++++- odoo/Odoo.config | 16 +++ 5 files changed, 179 insertions(+), 33 deletions(-) diff --git a/.github/workflows/openems-deployment-td.json b/.github/workflows/openems-deployment-td.json index e0c5975..6e49c48 100644 --- a/.github/workflows/openems-deployment-td.json +++ b/.github/workflows/openems-deployment-td.json @@ -91,7 +91,7 @@ }, { "name": "PASSWORD", - "value": "odoo16@2022" + "value": "odoo" }, { "name": "HOST", @@ -129,7 +129,7 @@ }, { "name": "POSTGRES_PASSWORD", - "value": "odoo16@2022 " + "value": "odoo" }, { "name": "POSTGRES_DB", diff --git a/docker-compose.yml b/docker-compose.yml index 3b7ba85..c7eaeea 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -22,20 +22,7 @@ services: build: context: ./openems-edge image: openems-edge:latest - - db: - build: - context: ./odoo-database - image: odoo-db - user: root - environment: - - POSTGRES_USER=odoo - - POSTGRES_PASSWORD=odoo16@2022 - - POSTGRES_DB=postgres - restart: always # run as a service - volumes: - - ./postgresql:/var/lib/postgresql/data - + odoo16: build: context: ./odoo @@ -44,23 +31,70 @@ services: depends_on: - db ports: - - "10016:8069" - - "20016:8072" # live chat - tty: true - command: -- + - "8069:8069" + volumes: + - odoo-web-data:/var/lib/odoo + - ./config:/etc/odoo + - ./addons:/mnt/extra-addons environment: - HOST=db - USER=odoo - - PASSWORD=odoo16@2022 + - PASSWORD=odoo # Replace 'odoo-password' with your actual password + db: + build: + context: ./odoo-database + image: odoo-db + user: root + environment: + - POSTGRES_DB=postgres + - POSTGRES_PASSWORD=odoo # Replace 'odoo-password' with your actual password + - POSTGRES_USER=odoo + - PGDATA=/var/lib/postgresql/data/pgdata volumes: - #- /etc/timezone:/etc/timezone:ro - #- /etc/localtime:/etc/localtime:ro - # - ./entrypoint.sh:/entrypoint.sh # if you want to install additional Python packages, uncomment this line! - - ./addons:/mnt/extra-addons - - ./etc:/etc/odoo - restart: always + - odoo-db-data:/var/lib/postgresql/data/pgdata +volumes: + odoo-web-data: + odoo-db-data: + # db: + # build: + # context: ./odoo-database + # image: odoo-db + # user: root + # environment: + # - POSTGRES_USER=odoo + # - POSTGRES_PASSWORD=odoo16@2022 + # - POSTGRES_DB=postgres + # restart: always # run as a service + # volumes: + # - ./postgresql:/var/lib/postgresql/data + + # odoo16: + # build: + # context: ./odoo + # image: odoo + # user: root + # depends_on: + # - db + # ports: + # - "10016:8069" + # - "20016:8072" # live chat + # tty: true + # command: -- + # environment: + # - HOST=db + # - USER=odoo + # - PASSWORD=odoo16@2022 + # volumes: + # #- /etc/timezone:/etc/timezone:ro + # #- /etc/localtime:/etc/localtime:ro + # # - ./entrypoint.sh:/entrypoint.sh # if you want to install additional Python packages, uncomment this line! + # - ./addons:/mnt/extra-addons + # - ./etc:/etc/odoo + # restart: always + + # openems-database: # build: diff --git a/iac/ecs.tf b/iac/ecs.tf index acc0c94..bf8ff0e 100644 --- a/iac/ecs.tf +++ b/iac/ecs.tf @@ -138,7 +138,7 @@ resource "aws_ecs_task_definition" "ecs_task_definition" { }, { name = "PASSWORD", - value = "odoo16@2022" + value = "odoo" } ] @@ -169,7 +169,7 @@ resource "aws_ecs_task_definition" "ecs_task_definition" { }, { name = "POSTGRES_PASSWORD", - value = "odoo16@2022 " + value = "odoo" }, { name = "POSTGRES_DB", diff --git a/odoo/Dockerfile b/odoo/Dockerfile index 23bcdbd..7481bed 100644 --- a/odoo/Dockerfile +++ b/odoo/Dockerfile @@ -1,7 +1,103 @@ -# Use Odoo 16.0 as the base image -FROM odoo:16.0 +FROM debian:bullseye-slim +SHELL ["/bin/bash", "-xo", "pipefail", "-c"] -# Expose port 8069 for Odoo web interface -EXPOSE 8069 \ No newline at end of file +# Generate locale C.UTF-8 for postgres and general locale data +ENV LANG C.UTF-8 + +# Retrieve the target architecture to install the correct wkhtmltopdf package +ARG TARGETARCH + +# Install some deps, lessc and less-plugin-clean-css, and wkhtmltopdf +RUN apt-get update && \ + apt-get install -y --no-install-recommends \ + ca-certificates \ + curl \ + dirmngr \ + fonts-noto-cjk \ + gnupg \ + libssl-dev \ + node-less \ + npm \ + python3-magic \ + python3-num2words \ + python3-odf \ + python3-pdfminer \ + python3-pip \ + python3-phonenumbers \ + python3-pyldap \ + python3-qrcode \ + python3-renderpm \ + python3-setuptools \ + python3-slugify \ + python3-vobject \ + python3-watchdog \ + python3-xlrd \ + python3-xlwt \ + xz-utils && \ + if [ -z "${TARGETARCH}" ]; then \ + TARGETARCH="$(dpkg --print-architecture)"; \ + fi; \ + WKHTMLTOPDF_ARCH=${TARGETARCH} && \ + case ${TARGETARCH} in \ + "amd64") WKHTMLTOPDF_ARCH=amd64 && WKHTMLTOPDF_SHA=9df8dd7b1e99782f1cfa19aca665969bbd9cc159 ;; \ + "arm64") WKHTMLTOPDF_SHA=58c84db46b11ba0e14abb77a32324b1c257f1f22 ;; \ + "ppc64le" | "ppc64el") WKHTMLTOPDF_ARCH=ppc64el && WKHTMLTOPDF_SHA=7ed8f6dcedf5345a3dd4eeb58dc89704d862f9cd ;; \ + esac \ + && curl -o wkhtmltox.deb -sSL https://github.com/wkhtmltopdf/packaging/releases/download/0.12.6.1-3/wkhtmltox_0.12.6.1-3.bullseye_${WKHTMLTOPDF_ARCH}.deb \ + && echo ${WKHTMLTOPDF_SHA} wkhtmltox.deb | sha1sum -c - \ + && apt-get install -y --no-install-recommends ./wkhtmltox.deb \ + && rm -rf /var/lib/apt/lists/* wkhtmltox.deb + +# install latest postgresql-client +RUN echo 'deb http://apt.postgresql.org/pub/repos/apt/ bullseye-pgdg main' > /etc/apt/sources.list.d/pgdg.list \ + && GNUPGHOME="$(mktemp -d)" \ + && export GNUPGHOME \ + && repokey='B97B0AFCAA1A47F044F244A07FCC7D46ACCC4CF8' \ + && gpg --batch --keyserver keyserver.ubuntu.com --recv-keys "${repokey}" \ + && gpg --batch --armor --export "${repokey}" > /etc/apt/trusted.gpg.d/pgdg.gpg.asc \ + && gpgconf --kill all \ + && rm -rf "$GNUPGHOME" \ + && apt-get update \ + && apt-get install --no-install-recommends -y postgresql-client \ + && rm -f /etc/apt/sources.list.d/pgdg.list \ + && rm -rf /var/lib/apt/lists/* + +# Install rtlcss (on Debian buster) +RUN npm install -g rtlcss + +# Install Odoo +ENV ODOO_VERSION 16.0 +ARG ODOO_RELEASE=20240624 +ARG ODOO_SHA=a51d6f097b24096d38959f4cd97ae5fb2cd2807b +RUN curl -o odoo.deb -sSL http://nightly.odoo.com/${ODOO_VERSION}/nightly/deb/odoo_${ODOO_VERSION}.${ODOO_RELEASE}_all.deb \ + && echo "${ODOO_SHA} odoo.deb" | sha1sum -c - \ + && apt-get update \ + && apt-get -y install --no-install-recommends ./odoo.deb \ + && rm -rf /var/lib/apt/lists/* odoo.deb + +# Copy entrypoint script and Odoo configuration file +COPY ./entrypoint.sh / +COPY ./odoo.conf /etc/odoo/ + +# Set permissions and Mount /var/lib/odoo to allow restoring filestore and /mnt/extra-addons for users addons +RUN chown odoo /etc/odoo/odoo.conf \ + && mkdir -p /mnt/extra-addons \ + && chown -R odoo /mnt/extra-addons +VOLUME ["/var/lib/odoo", "/mnt/extra-addons"] + +COPY ./extra-addons /mnt/extra-addons +# Expose Odoo services +EXPOSE 8069 8071 8072 + +# Set the default config file +ENV ODOO_RC /etc/odoo/odoo.conf + +COPY wait-for-psql.py /usr/local/bin/wait-for-psql.py + +# Set default user when running the container +USER odoo + +ENTRYPOINT ["/entrypoint.sh"] +CMD ["odoo"] \ No newline at end of file diff --git a/odoo/Odoo.config b/odoo/Odoo.config index e69de29..75705c9 100644 --- a/odoo/Odoo.config +++ b/odoo/Odoo.config @@ -0,0 +1,16 @@ +# Place in openems-backend/config.d/Metadata +:org.apache.felix.configadmin.revision:=L"2" +database="postgres" +debugMode="ON" +odooHost="localhost" +odooPassword="admin" +odooPort=I"8069" +odooProtocol="HTTP" +odooUid=I"2" +pgConnectionPoolSize=I"40" +pgHost="localhost" +pgPassword="odoo" +pgPort=I"5432" +pgUser="odoo" +poolSize=I"30" +service.pid="Metadata.Odoo" \ No newline at end of file From 281a7ccc0cc37c0adda1e8204b10d8aafe0cd822 Mon Sep 17 00:00:00 2001 From: belloafeez Date: Thu, 1 Aug 2024 11:01:24 +0100 Subject: [PATCH 12/54] updated odoo addons Signed-off-by: belloafeez --- addons/openems/.gitignore | 3 + addons/openems/__init__.py | 1 + addons/openems/__manifest__.py | 40 + addons/openems/controllers/__init__.py | 1 + addons/openems/controllers/alerting.py | 86 + addons/openems/controllers/const.py | 5 + addons/openems/controllers/openems_backend.py | 276 +++ addons/openems/controllers/setup_protocol.py | 142 ++ addons/openems/controllers/user.py | 32 + addons/openems/data/OpenEMS-Logo.jpg | Bin 0 -> 152320 bytes addons/openems/data/demo.xml | 12 + addons/openems/data/ir_config_parameter.xml | 9 + addons/openems/data/res_partner_category.xml | 11 + addons/openems/i18n/de.po | 1666 +++++++++++++++++ addons/openems/i18n/openems.pot | 1666 +++++++++++++++++ .../openems/mail/openems/alerting_offline.xml | 275 +++ .../mail/openems/alerting_sum_state.xml | 268 +++ .../mail/openems/setup_protocol_customer.xml | 170 ++ .../mail/openems/setup_protocol_installer.xml | 173 ++ .../mail/openems/user_registration.xml | 197 ++ .../migrations/16.0.1.0.1/post-migrate.py | 9 + .../migrations/16.0.1.0.1/pre-migrate.py | 7 + addons/openems/models/__init__.py | 1 + addons/openems/models/device.py | 321 ++++ addons/openems/models/partner.py | 12 + addons/openems/models/setup_protocol.py | 49 + addons/openems/models/stock_production_lot.py | 23 + addons/openems/models/user.py | 37 + addons/openems/report/setup_protocol.xml | 311 +++ addons/openems/security/ir.model.access.csv | 31 + addons/openems/security/openems.xml | 54 + .../.setuptools-odoo-make-default-ignore | 2 + addons/openems/setup/README | 2 + addons/openems/static/description/icon.png | Bin 0 -> 53271 bytes addons/openems/static/mail/OpenEMS-Logo.jpg | Bin 0 -> 152320 bytes addons/openems/views/device.xml | 320 ++++ addons/openems/views/partner.xml | 28 + addons/openems/views/setup_protocol.xml | 82 + .../views/stock_production_lot_views.xml | 13 + addons/openems/views/user.xml | 25 + addons/partner_firstname/README.rst | 146 ++ addons/partner_firstname/__init__.py | 2 + addons/partner_firstname/__manifest__.py | 30 + addons/partner_firstname/exceptions.py | 12 + addons/partner_firstname/hooks.py | 9 + addons/partner_firstname/i18n/am.po | 130 ++ addons/partner_firstname/i18n/ar.po | 131 ++ addons/partner_firstname/i18n/bg.po | 130 ++ addons/partner_firstname/i18n/bs.po | 131 ++ addons/partner_firstname/i18n/ca.po | 139 ++ addons/partner_firstname/i18n/cs.po | 130 ++ addons/partner_firstname/i18n/da.po | 135 ++ addons/partner_firstname/i18n/de.po | 136 ++ addons/partner_firstname/i18n/el_GR.po | 131 ++ addons/partner_firstname/i18n/en_GB.po | 131 ++ addons/partner_firstname/i18n/es.po | 136 ++ addons/partner_firstname/i18n/es_CR.po | 131 ++ addons/partner_firstname/i18n/es_EC.po | 131 ++ addons/partner_firstname/i18n/es_MX.po | 131 ++ addons/partner_firstname/i18n/es_VE.po | 131 ++ addons/partner_firstname/i18n/et.po | 130 ++ addons/partner_firstname/i18n/eu.po | 130 ++ addons/partner_firstname/i18n/fi.po | 130 ++ addons/partner_firstname/i18n/fr.po | 138 ++ addons/partner_firstname/i18n/fr_CA.po | 131 ++ addons/partner_firstname/i18n/fr_CH.po | 131 ++ addons/partner_firstname/i18n/gl.po | 130 ++ addons/partner_firstname/i18n/hr.po | 132 ++ addons/partner_firstname/i18n/hr_HR.po | 132 ++ addons/partner_firstname/i18n/hu.po | 138 ++ addons/partner_firstname/i18n/it.po | 136 ++ addons/partner_firstname/i18n/ja.po | 130 ++ addons/partner_firstname/i18n/lt.po | 131 ++ addons/partner_firstname/i18n/lv.po | 131 ++ addons/partner_firstname/i18n/mk.po | 130 ++ addons/partner_firstname/i18n/mn.po | 130 ++ addons/partner_firstname/i18n/nb.po | 131 ++ addons/partner_firstname/i18n/nb_NO.po | 131 ++ addons/partner_firstname/i18n/nl.po | 130 ++ addons/partner_firstname/i18n/nl_BE.po | 131 ++ addons/partner_firstname/i18n/nl_NL.po | 138 ++ .../i18n/partner_firstname.pot | 124 ++ addons/partner_firstname/i18n/pl.po | 132 ++ addons/partner_firstname/i18n/pt.po | 130 ++ addons/partner_firstname/i18n/pt_BR.po | 138 ++ addons/partner_firstname/i18n/pt_PT.po | 131 ++ addons/partner_firstname/i18n/ro.po | 131 ++ addons/partner_firstname/i18n/ru.po | 132 ++ addons/partner_firstname/i18n/sk.po | 130 ++ addons/partner_firstname/i18n/sl.po | 131 ++ addons/partner_firstname/i18n/sr@latin.po | 132 ++ addons/partner_firstname/i18n/sv.po | 130 ++ addons/partner_firstname/i18n/th.po | 130 ++ addons/partner_firstname/i18n/tr.po | 130 ++ addons/partner_firstname/i18n/tr_TR.po | 131 ++ addons/partner_firstname/i18n/vi.po | 130 ++ addons/partner_firstname/i18n/zh_CN.po | 131 ++ addons/partner_firstname/i18n/zh_TW.po | 131 ++ addons/partner_firstname/models/__init__.py | 3 + .../models/base_config_settings.py | 71 + .../partner_firstname/models/res_partner.py | 270 +++ addons/partner_firstname/models/res_users.py | 49 + addons/partner_firstname/readme/CONFIGURE.rst | 14 + .../partner_firstname/readme/CONTRIBUTORS.rst | 23 + .../partner_firstname/readme/DESCRIPTION.rst | 2 + addons/partner_firstname/readme/ROADMAP.rst | 3 + addons/partner_firstname/readme/USAGE.rst | 13 + .../static/description/icon.png | Bin 0 -> 9455 bytes .../static/description/index.html | 488 +++++ addons/partner_firstname/tests/__init__.py | 12 + addons/partner_firstname/tests/base.py | 65 + .../tests/test_config_settings.py | 35 + addons/partner_firstname/tests/test_copy.py | 95 + addons/partner_firstname/tests/test_create.py | 79 + .../partner_firstname/tests/test_defaults.py | 64 + addons/partner_firstname/tests/test_delete.py | 38 + addons/partner_firstname/tests/test_empty.py | 73 + addons/partner_firstname/tests/test_name.py | 119 ++ addons/partner_firstname/tests/test_order.py | 38 + .../tests/test_partner_form.py | 106 ++ .../partner_firstname/tests/test_user_form.py | 51 + .../views/base_config_view.xml | 28 + .../partner_firstname/views/res_partner.xml | 105 ++ addons/partner_firstname/views/res_user.xml | 25 + addons/web_m2x_options/README.rst | 217 +++ addons/web_m2x_options/__init__.py | 1 + addons/web_m2x_options/__manifest__.py | 21 + addons/web_m2x_options/i18n/ar.po | 133 ++ addons/web_m2x_options/i18n/de.po | 159 ++ addons/web_m2x_options/i18n/es.po | 145 ++ addons/web_m2x_options/i18n/es_BO.po | 116 ++ addons/web_m2x_options/i18n/fi.po | 132 ++ addons/web_m2x_options/i18n/fr.po | 158 ++ addons/web_m2x_options/i18n/hr.po | 150 ++ addons/web_m2x_options/i18n/it.po | 133 ++ addons/web_m2x_options/i18n/nl.po | 162 ++ addons/web_m2x_options/i18n/nl_NL.po | 125 ++ addons/web_m2x_options/i18n/pt_BR.po | 156 ++ addons/web_m2x_options/i18n/sl.po | 133 ++ addons/web_m2x_options/i18n/tr.po | 132 ++ .../web_m2x_options/i18n/web_m2x_options.pot | 115 ++ addons/web_m2x_options/i18n/zh_CN.po | 153 ++ addons/web_m2x_options/models/__init__.py | 2 + .../models/ir_config_parameter.py | 18 + addons/web_m2x_options/models/ir_http.py | 11 + .../web_m2x_options/readme/CONTRIBUTORS.rst | 16 + addons/web_m2x_options/readme/CREDITS.rst | 1 + addons/web_m2x_options/readme/DESCRIPTION.rst | 10 + addons/web_m2x_options/readme/ROADMAP.rst | 6 + addons/web_m2x_options/readme/USAGE.rst | 95 + .../static/description/icon.png | Bin 0 -> 9455 bytes .../static/description/index.html | 412 ++++ .../static/src/components/base.xml | 46 + .../static/src/components/form.esm.js | 404 ++++ .../src/components/relational_utils.esm.js | 221 +++ addons/web_m2x_options/tests/__init__.py | 2 + .../tests/test_ir_config_parameter.py | 28 + 157 files changed, 19020 insertions(+) create mode 100644 addons/openems/.gitignore create mode 100644 addons/openems/__init__.py create mode 100644 addons/openems/__manifest__.py create mode 100644 addons/openems/controllers/__init__.py create mode 100644 addons/openems/controllers/alerting.py create mode 100644 addons/openems/controllers/const.py create mode 100644 addons/openems/controllers/openems_backend.py create mode 100644 addons/openems/controllers/setup_protocol.py create mode 100644 addons/openems/controllers/user.py create mode 100644 addons/openems/data/OpenEMS-Logo.jpg create mode 100644 addons/openems/data/demo.xml create mode 100644 addons/openems/data/ir_config_parameter.xml create mode 100644 addons/openems/data/res_partner_category.xml create mode 100644 addons/openems/i18n/de.po create mode 100644 addons/openems/i18n/openems.pot create mode 100644 addons/openems/mail/openems/alerting_offline.xml create mode 100644 addons/openems/mail/openems/alerting_sum_state.xml create mode 100644 addons/openems/mail/openems/setup_protocol_customer.xml create mode 100644 addons/openems/mail/openems/setup_protocol_installer.xml create mode 100644 addons/openems/mail/openems/user_registration.xml create mode 100644 addons/openems/migrations/16.0.1.0.1/post-migrate.py create mode 100644 addons/openems/migrations/16.0.1.0.1/pre-migrate.py create mode 100644 addons/openems/models/__init__.py create mode 100644 addons/openems/models/device.py create mode 100644 addons/openems/models/partner.py create mode 100644 addons/openems/models/setup_protocol.py create mode 100644 addons/openems/models/stock_production_lot.py create mode 100644 addons/openems/models/user.py create mode 100644 addons/openems/report/setup_protocol.xml create mode 100644 addons/openems/security/ir.model.access.csv create mode 100644 addons/openems/security/openems.xml create mode 100644 addons/openems/setup/.setuptools-odoo-make-default-ignore create mode 100644 addons/openems/setup/README create mode 100644 addons/openems/static/description/icon.png create mode 100644 addons/openems/static/mail/OpenEMS-Logo.jpg create mode 100644 addons/openems/views/device.xml create mode 100644 addons/openems/views/partner.xml create mode 100644 addons/openems/views/setup_protocol.xml create mode 100644 addons/openems/views/stock_production_lot_views.xml create mode 100644 addons/openems/views/user.xml create mode 100644 addons/partner_firstname/README.rst create mode 100644 addons/partner_firstname/__init__.py create mode 100644 addons/partner_firstname/__manifest__.py create mode 100644 addons/partner_firstname/exceptions.py create mode 100644 addons/partner_firstname/hooks.py create mode 100644 addons/partner_firstname/i18n/am.po create mode 100644 addons/partner_firstname/i18n/ar.po create mode 100644 addons/partner_firstname/i18n/bg.po create mode 100644 addons/partner_firstname/i18n/bs.po create mode 100644 addons/partner_firstname/i18n/ca.po create mode 100644 addons/partner_firstname/i18n/cs.po create mode 100644 addons/partner_firstname/i18n/da.po create mode 100644 addons/partner_firstname/i18n/de.po create mode 100644 addons/partner_firstname/i18n/el_GR.po create mode 100644 addons/partner_firstname/i18n/en_GB.po create mode 100644 addons/partner_firstname/i18n/es.po create mode 100644 addons/partner_firstname/i18n/es_CR.po create mode 100644 addons/partner_firstname/i18n/es_EC.po create mode 100644 addons/partner_firstname/i18n/es_MX.po create mode 100644 addons/partner_firstname/i18n/es_VE.po create mode 100644 addons/partner_firstname/i18n/et.po create mode 100644 addons/partner_firstname/i18n/eu.po create mode 100644 addons/partner_firstname/i18n/fi.po create mode 100644 addons/partner_firstname/i18n/fr.po create mode 100644 addons/partner_firstname/i18n/fr_CA.po create mode 100644 addons/partner_firstname/i18n/fr_CH.po create mode 100644 addons/partner_firstname/i18n/gl.po create mode 100644 addons/partner_firstname/i18n/hr.po create mode 100644 addons/partner_firstname/i18n/hr_HR.po create mode 100644 addons/partner_firstname/i18n/hu.po create mode 100644 addons/partner_firstname/i18n/it.po create mode 100644 addons/partner_firstname/i18n/ja.po create mode 100644 addons/partner_firstname/i18n/lt.po create mode 100644 addons/partner_firstname/i18n/lv.po create mode 100644 addons/partner_firstname/i18n/mk.po create mode 100644 addons/partner_firstname/i18n/mn.po create mode 100644 addons/partner_firstname/i18n/nb.po create mode 100644 addons/partner_firstname/i18n/nb_NO.po create mode 100644 addons/partner_firstname/i18n/nl.po create mode 100644 addons/partner_firstname/i18n/nl_BE.po create mode 100644 addons/partner_firstname/i18n/nl_NL.po create mode 100644 addons/partner_firstname/i18n/partner_firstname.pot create mode 100644 addons/partner_firstname/i18n/pl.po create mode 100644 addons/partner_firstname/i18n/pt.po create mode 100644 addons/partner_firstname/i18n/pt_BR.po create mode 100644 addons/partner_firstname/i18n/pt_PT.po create mode 100644 addons/partner_firstname/i18n/ro.po create mode 100644 addons/partner_firstname/i18n/ru.po create mode 100644 addons/partner_firstname/i18n/sk.po create mode 100644 addons/partner_firstname/i18n/sl.po create mode 100644 addons/partner_firstname/i18n/sr@latin.po create mode 100644 addons/partner_firstname/i18n/sv.po create mode 100644 addons/partner_firstname/i18n/th.po create mode 100644 addons/partner_firstname/i18n/tr.po create mode 100644 addons/partner_firstname/i18n/tr_TR.po create mode 100644 addons/partner_firstname/i18n/vi.po create mode 100644 addons/partner_firstname/i18n/zh_CN.po create mode 100644 addons/partner_firstname/i18n/zh_TW.po create mode 100644 addons/partner_firstname/models/__init__.py create mode 100644 addons/partner_firstname/models/base_config_settings.py create mode 100644 addons/partner_firstname/models/res_partner.py create mode 100644 addons/partner_firstname/models/res_users.py create mode 100644 addons/partner_firstname/readme/CONFIGURE.rst create mode 100644 addons/partner_firstname/readme/CONTRIBUTORS.rst create mode 100644 addons/partner_firstname/readme/DESCRIPTION.rst create mode 100644 addons/partner_firstname/readme/ROADMAP.rst create mode 100644 addons/partner_firstname/readme/USAGE.rst create mode 100644 addons/partner_firstname/static/description/icon.png create mode 100644 addons/partner_firstname/static/description/index.html create mode 100644 addons/partner_firstname/tests/__init__.py create mode 100644 addons/partner_firstname/tests/base.py create mode 100644 addons/partner_firstname/tests/test_config_settings.py create mode 100644 addons/partner_firstname/tests/test_copy.py create mode 100644 addons/partner_firstname/tests/test_create.py create mode 100644 addons/partner_firstname/tests/test_defaults.py create mode 100644 addons/partner_firstname/tests/test_delete.py create mode 100644 addons/partner_firstname/tests/test_empty.py create mode 100644 addons/partner_firstname/tests/test_name.py create mode 100644 addons/partner_firstname/tests/test_order.py create mode 100644 addons/partner_firstname/tests/test_partner_form.py create mode 100644 addons/partner_firstname/tests/test_user_form.py create mode 100644 addons/partner_firstname/views/base_config_view.xml create mode 100644 addons/partner_firstname/views/res_partner.xml create mode 100644 addons/partner_firstname/views/res_user.xml create mode 100644 addons/web_m2x_options/README.rst create mode 100644 addons/web_m2x_options/__init__.py create mode 100644 addons/web_m2x_options/__manifest__.py create mode 100644 addons/web_m2x_options/i18n/ar.po create mode 100644 addons/web_m2x_options/i18n/de.po create mode 100644 addons/web_m2x_options/i18n/es.po create mode 100644 addons/web_m2x_options/i18n/es_BO.po create mode 100644 addons/web_m2x_options/i18n/fi.po create mode 100644 addons/web_m2x_options/i18n/fr.po create mode 100644 addons/web_m2x_options/i18n/hr.po create mode 100644 addons/web_m2x_options/i18n/it.po create mode 100644 addons/web_m2x_options/i18n/nl.po create mode 100644 addons/web_m2x_options/i18n/nl_NL.po create mode 100644 addons/web_m2x_options/i18n/pt_BR.po create mode 100644 addons/web_m2x_options/i18n/sl.po create mode 100644 addons/web_m2x_options/i18n/tr.po create mode 100644 addons/web_m2x_options/i18n/web_m2x_options.pot create mode 100644 addons/web_m2x_options/i18n/zh_CN.po create mode 100644 addons/web_m2x_options/models/__init__.py create mode 100644 addons/web_m2x_options/models/ir_config_parameter.py create mode 100644 addons/web_m2x_options/models/ir_http.py create mode 100644 addons/web_m2x_options/readme/CONTRIBUTORS.rst create mode 100644 addons/web_m2x_options/readme/CREDITS.rst create mode 100644 addons/web_m2x_options/readme/DESCRIPTION.rst create mode 100644 addons/web_m2x_options/readme/ROADMAP.rst create mode 100644 addons/web_m2x_options/readme/USAGE.rst create mode 100644 addons/web_m2x_options/static/description/icon.png create mode 100644 addons/web_m2x_options/static/description/index.html create mode 100644 addons/web_m2x_options/static/src/components/base.xml create mode 100644 addons/web_m2x_options/static/src/components/form.esm.js create mode 100644 addons/web_m2x_options/static/src/components/relational_utils.esm.js create mode 100644 addons/web_m2x_options/tests/__init__.py create mode 100644 addons/web_m2x_options/tests/test_ir_config_parameter.py diff --git a/addons/openems/.gitignore b/addons/openems/.gitignore new file mode 100644 index 0000000..e41d5e2 --- /dev/null +++ b/addons/openems/.gitignore @@ -0,0 +1,3 @@ +.swp +.swo +**/__pycache__ diff --git a/addons/openems/__init__.py b/addons/openems/__init__.py new file mode 100644 index 0000000..72d3ea6 --- /dev/null +++ b/addons/openems/__init__.py @@ -0,0 +1 @@ +from . import controllers, models diff --git a/addons/openems/__manifest__.py b/addons/openems/__manifest__.py new file mode 100644 index 0000000..232ebf1 --- /dev/null +++ b/addons/openems/__manifest__.py @@ -0,0 +1,40 @@ +{ + "name": "OpenEMS", + "summary": "Everything related to OpenEMS (Open Energy Management System)", + "version": "16.0.1.0.1", + "author": "OpenEMS Association e.V.", + "maintainer": "OpenEMS Association e.V.", + "contributors": [ + "Stefan Feilmeier " + "Maximilian Lang " + ], + "website": "https://openems.io", + "license": "AGPL-3", + "category": "Specific Industry Applications", + "depends": ["base", "web", "mail", "crm", "resource", "stock", "web_m2x_options", "partner_firstname"], + "data": [ + "data/ir_config_parameter.xml", + "data/res_partner_category.xml", + "security/openems.xml", + "security/ir.model.access.csv", + "report/setup_protocol.xml", + "views/device.xml", + "views/partner.xml", + "views/setup_protocol.xml", + "views/user.xml", + "views/stock_production_lot_views.xml", + "mail/openems/alerting_offline.xml", + "mail/openems/alerting_sum_state.xml", + "mail/openems/setup_protocol_customer.xml", + "mail/openems/setup_protocol_installer.xml", + "mail/openems/user_registration.xml", + ], + "demo": ["data/demo.xml"], + "js": [], + "css": [], + "qweb": [], + "images": [], + "test": [], + "installable": True, + "application": True, +} diff --git a/addons/openems/controllers/__init__.py b/addons/openems/controllers/__init__.py new file mode 100644 index 0000000..3e863cd --- /dev/null +++ b/addons/openems/controllers/__init__.py @@ -0,0 +1 @@ +from . import openems_backend, setup_protocol, user, alerting diff --git a/addons/openems/controllers/alerting.py b/addons/openems/controllers/alerting.py new file mode 100644 index 0000000..7a848f2 --- /dev/null +++ b/addons/openems/controllers/alerting.py @@ -0,0 +1,86 @@ +import logging +from datetime import datetime +from enum import Enum + +from odoo import http +from odoo.http import request + +class SumState(Enum): + FAULT = 0 + WARNING = 1 + +class Message: + sentAt: datetime + edgeId: str + userIds: list[int] + + def __init__(self, sentAt: datetime, edgeId: str, userIds: list[int]) -> None: + self.sentAt = sentAt + self.edgeId = edgeId + self.userIds = userIds + +class SumStateMessage(Message): + state: SumState + + def __init__(self, sentAt: datetime, edgeId: str, userIds: list[int], state: SumState) -> None: + super().__init__(sentAt, edgeId, userIds) + self.state = state + +class Alerting(http.Controller): + __logger = logging.getLogger("Alerting") + + @http.route("/openems_backend/mail/alerting_sum_state", type="json", auth="user") + def sum_state_alerting(self, sentAt: str, params: list[dict]): + msgs = self.__get_sum_state_params(sentAt, params) + update_func = lambda role, at: { role.write({"sum_state_last_notification": at})} + + if len(msgs) == 0: + self.__logger.error("Scheduled SumState-Alerting-Mail without any recipients!!!") + + template = request.env.ref('openems.alerting_sum_state') + for msg in msgs: + self.__send_mails(template, msg, update_func) + + return {} + + @http.route("/openems_backend/mail/alerting_offline", type="json", auth="user") + def offline_alerting(self, sentAt: str, params: list[dict]): + msgs = self.__get_offline_params(sentAt, params) + update_func = lambda role, at: { role.write({"offline_last_notification": at})} + + template = request.env.ref("openems.alerting_offline") + for msg in msgs: + self.__send_mails(template, msg, update_func) + + return {} + + def __get_offline_params(self, sentAt, params) -> list[Message]: + msgs = list() + sent = datetime.strptime(sentAt, "%Y-%m-%d %H:%M:%S") + for param in params: + edgeId = param["edgeId"] + recipients = param["recipients"] + msgs.append(Message(sent, edgeId, recipients)); + return msgs + + def __get_sum_state_params(self, sentAt, params) -> list[SumStateMessage]: + msgs = list() + sent = datetime.strptime(sentAt, "%Y-%m-%d %H:%M:%S") + for param in params: + edgeId = param["edgeId"] + recipients = param["recipients"] + state = param["state"] + msgs.append(SumStateMessage(sent, edgeId, recipients, state)); + return msgs + + def __send_mails(self, template, msg: Message, update_func): + roles = http.request.env['openems.alerting'].search( + [('user_id','in',msg.userIds),('device_id','=',msg.edgeId)] + ) + + for role in roles: + try: + template.send_mail(res_id=role.id, force_send=True) + update_func(role, msg.sentAt) + except Exception as err: + self.__logger.error("[" + str(err) + "] Unable to send template[" + str(template.name) +"] to edgeUser[user=" + str(role.id) + ", edge=" + str(msg.edgeId)+ "]") \ No newline at end of file diff --git a/addons/openems/controllers/const.py b/addons/openems/controllers/const.py new file mode 100644 index 0000000..c6fbc01 --- /dev/null +++ b/addons/openems/controllers/const.py @@ -0,0 +1,5 @@ +from odoo.modules.module import get_module_resource + +import base64 + +OPENEMS_LOGO_BASE64 = base64.b64encode(open(get_module_resource('openems', 'data', 'OpenEMS-Logo.jpg') , "rb").read()) \ No newline at end of file diff --git a/addons/openems/controllers/openems_backend.py b/addons/openems/controllers/openems_backend.py new file mode 100644 index 0000000..d0dcb80 --- /dev/null +++ b/addons/openems/controllers/openems_backend.py @@ -0,0 +1,276 @@ +from odoo import http + + +class OpenemsBackend(http.Controller): + @http.route("/openems_backend/info", auth="user", type="json") + def index(self): + # Get user + user_id = http.request.env.context.get("uid") + res_users = http.request.env["res.users"].sudo() + user_rec = res_users.search_read( + [("id", "=", user_id)], + ["login", "name", "groups_id", "global_role", "openems_language"], + )[0] + res_users.browse([user_id]) + + # Get res group model + res_groups_model = http.request.env["res.groups"].sudo() + + # Get Manager and Reader group + manager_group = res_groups_model.env.ref("openems.group_openems_manager") + reader_group = res_groups_model.env.ref("openems.group_openems_reader") + + manager_group_id = manager_group["id"] + reader_group_id = reader_group["id"] + + # Get user attributes + global_role = user_rec["global_role"] + if manager_group_id in user_rec["groups_id"]: + # Manager group + global_role = "admin" + + # return empty device (use pagination) list if user is manager or reader + if manager_group_id in user_rec["groups_id"] or reader_group_id in user_rec["groups_id"]: + return { + "user": { + "id": user_rec["id"], + "login": user_rec["login"], + "name": user_rec["name"], + "global_role": global_role, + "language": user_rec["openems_language"], + "has_multiple_edges": True + }, + "devices": [], + } + + # Get specific Device roles + device_user_role_model = http.request.env["openems.device_user_role"] + user_role_ids = device_user_role_model.search_read( + [("user_id", "=", user_id)], ["id", "role"] + ) + + # Get Devices + device_model = http.request.env["openems.device"] + devices = device_model.search_read( + [], ["id", "name", "user_role_ids", "comment", "producttype", + "lastmessage", "first_setup_protocol_date", "openems_sum_state_level"] + ) + + devs = [] + for device_rec in devices: + # Set user role per group + role = "guest" + if manager_group_id in user_rec["groups_id"]: + # Manager group + role = "admin" + elif reader_group_id in user_rec["groups_id"]: + # Reader group + role = "guest" + + # Set specific user role + for device_role_id in device_rec["user_role_ids"]: + for user_role_id in user_role_ids: + if device_role_id == user_role_id["id"]: + role = user_role_id["role"] + + # Prepare result + dev = { + "id": device_rec["id"], + "name": device_rec["name"], + "comment": device_rec["comment"], + "producttype": device_rec["producttype"], + "role": role, + "lastmessage": device_rec["lastmessage"], + "openems_sum_state_level": device_rec["openems_sum_state_level"] + } + + if device_rec["first_setup_protocol_date"]: + dev["first_setup_protocol_date"] = device_rec[ + "first_setup_protocol_date" + ] + + devs.append(dev) + + return { + "user": { + "id": user_rec["id"], + "login": user_rec["login"], + "name": user_rec["name"], + "global_role": global_role, + "language": user_rec["openems_language"], + "has_multiple_edges": len(devs) > 1 + }, + "devices": devs, + } + + @http.route("/openems_backend/get_edge_with_role", auth="user", type="json") + def get_edge_with_role(self, edge_id: str): + user_id = http.request.env.context.get("uid") + res_users = http.request.env["res.users"].sudo() + user_rec = res_users.search_read( + [("id", "=", user_id)], + ["login", "name", "groups_id"], + )[0] + + # Get res group model + res_groups_model = http.request.env["res.groups"].sudo() + + # Get Manager and Reader group + manager_group = res_groups_model.env.ref("openems.group_openems_manager") + reader_group = res_groups_model.env.ref("openems.group_openems_reader") + + manager_group_id = manager_group["id"] + reader_group_id = reader_group["id"] + + # get devices for which the user has permissions + device_model = http.request.env["openems.device"] + devices = device_model.search_read( + [("name", "=", edge_id)], + ["id", "name", "comment", "producttype", "lastmessage", "first_setup_protocol_date", "openems_sum_state_level"]) + + if len(devices) != 1: + return {} + + device = devices[0] + + # Get specific Device roles + device_user_role_model = http.request.env["openems.device_user_role"] + device_user_roles = device_user_role_model.search_read( + [("user_id", "=", user_id), + ("device_id", "=", device["id"])], ["id", "role"] + ) + + # Set user role per group + role = "guest" + if manager_group_id in user_rec["groups_id"]: + # Manager group + role = "admin" + elif reader_group_id in user_rec["groups_id"]: + # Reader group + role = "guest" + + # Set specific user role + if len(device_user_roles) > 0: + role = device_user_roles[0]["role"] + + dev = { + "id": device["id"], + "name": device["name"], + "comment": device["comment"], + "producttype": device["producttype"], + "role": role, + "lastmessage": device["lastmessage"], + "openems_sum_state_level": device["openems_sum_state_level"] + } + if device["first_setup_protocol_date"]: + dev["first_setup_protocol_date"] = device["first_setup_protocol_date"] + + return dev + + @http.route("/openems_backend/get_edges", auth="user", type="json") + def get_edges(self, limit, page, query=None, searchParams=None): + # Get user + user_id = http.request.env.context.get("uid") + res_users = http.request.env["res.users"].sudo() + user_rec = res_users.search_read( + [("id", "=", user_id)], + ["login", "name", "groups_id", "global_role"], + )[0] + + # Get res group model + res_groups_model = http.request.env["res.groups"].sudo() + + # Get Manager and Reader group + manager_group = res_groups_model.env.ref("openems.group_openems_manager") + reader_group = res_groups_model.env.ref("openems.group_openems_reader") + + manager_group_id = manager_group["id"] + reader_group_id = reader_group["id"] + + # Get specific Device roles + device_user_role_model = http.request.env["openems.device_user_role"] + user_role_ids = device_user_role_model.search_read( + [("user_id", "=", user_id)], ["id", "role"] + ) + + domains = [] + logical_operators = [] + additional_domains = [] + if query: + logical_operators.extend(['|', '|']) + domains = [ + ("name", "ilike", query), + ("comment", "ilike", query), + ("producttype", "ilike", query)] + + if searchParams: + if searchParams.get("producttype"): + additional_domains.append( + ("producttype", "in", searchParams.get("producttype"))) + + if searchParams.get("sumState"): + sum_states = list(map(lambda s: s.lower(), searchParams.get("sumState"))) + additional_domains.append( + ("openems_sum_state_level", "in", sum_states)) + + if "isOnline" in searchParams: + additional_domains.append( + ("openems_is_connected", "=", searchParams.get("isOnline"))) + + if len(additional_domains) > 1: + for _ in range(len(additional_domains) - 1): + logical_operators.insert(0, '&') + + # insert 'and' if both are not 'None' + if query and searchParams: + logical_operators.insert(0, '&') + + domains.extend(additional_domains) + logical_operators.extend(domains) + + # Get Devices + device_model = http.request.env["openems.device"] + devices = device_model.search_read( + logical_operators, + ["id", "name", "user_role_ids", "comment", "producttype", + "lastmessage", "first_setup_protocol_date", "openems_sum_state_level"], + limit=limit, offset=(page * limit) + ) + devs = [] + for device_rec in devices: + # Set user role per group + role = "guest" + if manager_group_id in user_rec["groups_id"]: + # Manager group + role = "admin" + elif reader_group_id in user_rec["groups_id"]: + # Reader group + role = "guest" + + # Set specific user role + for device_role_id in device_rec["user_role_ids"]: + for user_role_id in user_role_ids: + if device_role_id == user_role_id["id"]: + role = user_role_id["role"] + + # Prepare result + dev = { + "id": device_rec["id"], + "name": device_rec["name"], + "comment": device_rec["comment"], + "producttype": device_rec["producttype"], + "role": role, + "lastmessage": device_rec["lastmessage"], + "openems_sum_state_level": device_rec["openems_sum_state_level"] + } + + if device_rec["first_setup_protocol_date"]: + dev["first_setup_protocol_date"] = device_rec[ + "first_setup_protocol_date" + ] + + devs.append(dev) + + return { + "devices": devs, + } diff --git a/addons/openems/controllers/setup_protocol.py b/addons/openems/controllers/setup_protocol.py new file mode 100644 index 0000000..d64b18e --- /dev/null +++ b/addons/openems/controllers/setup_protocol.py @@ -0,0 +1,142 @@ +import base64 + +from odoo import http +from odoo.http import request + + +class SetupProtocol(http.Controller): + @http.route("/openems_backend/sendSetupProtocolEmail", type="json", auth="user") + def index(self, setupProtocolId, edgeId): + setup_protocol_model = request.env["openems.setup_protocol"] + setup_protocol_record = setup_protocol_model.search_read( + [("id", "=", setupProtocolId)] + ) + if len(setup_protocol_record) != 1: + raise ValueError("Setup protocol not found for id [" + edgeId + "]") + + device_model = request.env["openems.device"] + device_rec = device_model.search_read([("name", "=", edgeId)]) + if len(device_rec) != 1: + raise ValueError("Device not found for id [" + edgeId + "]") + + name = ( + "IBN-" + + edgeId + + "-" + + setup_protocol_record[0]["create_date"].strftime("%d.%m.%Y") + + ".pdf" + ) + + data = request.env.ref( + "openems.action_openems_setup_protocol_report" + )._render_qweb_pdf([setupProtocolId]) + ibnPdf = request.env["ir.attachment"].create( + { + "res_model": "openems.device", + "res_id": device_rec[0]["id"], + "name": name, + "store_fname": name, + "datas": base64.b64encode(data[0]), + } + ) + + templates = self.getTemplates(device_rec[0]['oem'], ibnPdf) + + templates['installer'].send_mail(setupProtocolId, force_send=True) + templates['customer'].send_mail(setupProtocolId, force_send=True) + + return {} + + def getTemplates(self, oem: str, protocol): + templates = {'customer': None, 'installer': None} + + templates['customer'] = request.env.ref( + "openems.setup_protocol_email_customer") + templates['installer'] = request.env.ref( + "openems.setup_protocol_email_installer") + + logo = request.env.ref("openems.attachment_logo_openems") + + templates['customer'].attachment_ids = [ + (6, 0, [protocol.id, logo.id])] + templates['installer'].attachment_ids = [ + (6, 0, [protocol.id, logo.id])] + + return templates + + @http.route('/openems_backend/get_latest_setup_protocol', type='json', auth='user') + def get_latest_setup_protocol(self, edge_name): + # search for device + device_model = request.env['openems.device'] + device = device_model.search([('name', '=', edge_name)]) + + response = dict() + if not len(device.setup_protocol_ids) > 0: + return response + + latest_protocol = device.setup_protocol_ids[0] + + # build customer object + customer = latest_protocol.customer_id + customer_values = dict({ + "firstname": customer['firstname'], + "lastname": customer['lastname'], + "email": customer['email'], + "phone": customer['phone'], + "address": { + "street": customer['street'], + "city": customer['city'], + "zip": customer['zip'], + "country": customer['country_id']['name'] + } + }) + + # check company for customer + customer_company = customer['commercial_company_name'] + if customer_company: + customer_values.update({ + "company": { + "name": customer['commercial_company_name'] + } + }) + response.update({"customer": customer_values}) + + # check different location is available + location = latest_protocol['different_location_id'] + if location: + location_values = dict({ + "firstname": location['firstname'], + "lastname": location['lastname'], + "email": location['email'], + "phone": location['phone'], + "address": { + "street": location['street'], + "city": location['city'], + "zip": location['zip'], + "country": location['country_id']['name'] + } + }) + + # check company for different location + different_location_company = location['commercial_company_name'] + if different_location_company: + location_values.update({ + "company": { + "name": location['commercial_company_name'] + } + }) + response.update({"location": location_values}) + + # build items object + items = list() + for item in latest_protocol.item_ids: + items.append({ + "view": item['view'], + "field": item['field'], + "category": item['category'], + "name": item['name'], + "value": item['value'] + }) + response.update({"items": items}) + + return response diff --git a/addons/openems/controllers/user.py b/addons/openems/controllers/user.py new file mode 100644 index 0000000..75ec137 --- /dev/null +++ b/addons/openems/controllers/user.py @@ -0,0 +1,32 @@ +from odoo import http +from odoo.http import request + +class User(http.Controller): + @http.route("/openems_backend/sendRegistrationEmail", type="json", auth="user") + def index(self, userId, password=None, oem: str = ''): + user_model = request.env["res.users"] + user_record = user_model.search_read([("id", "=", userId)], ["partner_id"]) + if len(user_record) != 1: + raise ValueError("User not found for id [" + userId + "]") + + partner = user_record[0] + partner_id = partner.get("partner_id") + if partner_id is None: + raise ValueError("User has no partner") + + if password is None: + password = "*****" + # load template + template = self.getTemplate(oem) + # set mail values + email_values = { + 'password': password + } + # send mail + template.with_context(email_values).send_mail( + res_id=partner_id[0], force_send=True) + return {} + + def getTemplate(self, oem: str): + template = request.env.ref("openems.registration_email") + return template diff --git a/addons/openems/data/OpenEMS-Logo.jpg b/addons/openems/data/OpenEMS-Logo.jpg new file mode 100644 index 0000000000000000000000000000000000000000..13ae0fba6120a7472998decceef335398be01035 GIT binary patch literal 152320 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

`b%zWJVoybJJC+al7(vmUoDSw-d(zU?;>j| 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 + + + + + edge0 + OpenEMS Edge #0 + DEMO_API_KEY + + + + diff --git a/addons/openems/data/ir_config_parameter.xml b/addons/openems/data/ir_config_parameter.xml new file mode 100644 index 0000000..b1da5cf --- /dev/null +++ b/addons/openems/data/ir_config_parameter.xml @@ -0,0 +1,9 @@ + + + + + edge_monitoring_url + http://localhost:8082/device/ + + + diff --git a/addons/openems/data/res_partner_category.xml b/addons/openems/data/res_partner_category.xml new file mode 100644 index 0000000..f56c0e0 --- /dev/null +++ b/addons/openems/data/res_partner_category.xml @@ -0,0 +1,11 @@ + + + + + Created via IBN + + + Customer + + + diff --git a/addons/openems/i18n/de.po b/addons/openems/i18n/de.po new file mode 100644 index 0000000..cc4c660 --- /dev/null +++ b/addons/openems/i18n/de.po @@ -0,0 +1,1666 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * openems +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 16.0-20240218\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2024-02-18 11:57+0000\n" +"PO-Revision-Date: 2024-02-18 11:57+0000\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: openems +#: model:mail.template,body_html:openems.setup_protocol_email_installer +msgid "" +"\n" +"\n" +"\n" +"\n" +"\n" +" OpenEMS setup protocol \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +"\n" +"\n" +"\n" +"

\n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +"
\n" +" \n" +"
\n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +"
\n" +" \n" +"
\n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +"
\n" +"

\n" +"

\n" +" \n" +"
\n" +"
Dear \n" +" ,\n" +"
\n" +"
\n" +"
please find the setup protocol for your customer attached.\n" +"
\n" +"
\n" +"
Best Regards
\n" +"
\n" +"
OpenEMS Association e.V.
\n" +"
\n" +"
\n" +" \n" +"
\n" +"
\n" +" \n" +"
\n" +"
\n" +"\n" +"\n" +"\n" +" \n" +" " +msgstr "" + +#. module: openems +#: model:mail.template,body_html:openems.registration_email +msgid "" +"\n" +"\n" +"\n" +"\n" +"\n" +" Registrierung erfolgreich \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +"\n" +"\n" +"\n" +"
\n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +"
\n" +" \n" +"
\n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +"
\n" +" \n" +"
\n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +"
\n" +"

\n" +"

\n" +" \n" +"
\n" +"
Guten Tag \n" +" ,\n" +"
\n" +"
\n" +"
Ihr Zugang zu OpenEMS UI wurde erstellt.
\n" +"
\n" +"
Sie können sich auf OpenEMS UI einloggen, um auf das Online-Monitoring zuzugreifen.
\n" +"
\n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +"
Ihre Zugangsdaten:
E-Mail\n" +" \n" +"
Passwort\n" +" \n" +"
\n" +"
\n" +"
Best Regards
\n" +"
\n" +"
OpenEMS Association e.V.
\n" +"
\n" +"
\n" +" \n" +"
\n" +"
\n" +" \n" +"
\n" +"
\n" +"\n" +"\n" +"\n" +" \n" +" " +msgstr "" + +#. module: openems +#: model:mail.template,body_html:openems.setup_protocol_email_customer +msgid "" +"\n" +"\n" +"\n" +"\n" +"\n" +" Your OpenEMS Edge setup protocol \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +"\n" +"\n" +"\n" +"
\n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +"
\n" +" \n" +"
\n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +"
\n" +" \n" +"
\n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +"
\n" +"

\n" +"

\n" +" \n" +"
\n" +"
Welcome to OpenEMS,
\n" +"
\n" +"
please find your setup protocol for OpenEMS Edge attached.
\n" +"
\n" +"
Best Regards
\n" +"
\n" +"
OpenEMS Association e.V.
\n" +"
\n" +"
\n" +" \n" +"
\n" +"
\n" +" \n" +"
\n" +"
\n" +"\n" +"\n" +"\n" +" \n" +" " +msgstr "" + +#. module: openems +#: model:mail.template,body_html:openems.alerting_email_generic +msgid "" +"\n" +"\n" +"\n" +"\n" +"\n" +" OpenEMS Alert - Edge is offline\n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +"\n" +"\n" +"\n" +"
\n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +"
\n" +" \n" +"
\n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +"
\n" +" \n" +"
\n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +"
\n" +"

\n" +"

\n" +" \n" +"
\n" +"
Dear \n" +" ,\n" +"
\n" +"
\n" +"
Your OpenEMS Edge with number is offline since:
\n" +"
\n" +"
\n" +" \n" +" \n" +" \n" +" \n" +" \n" +" (UTC)\n" +" \n" +"
\n" +"
\n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +"
Info
\n" +" Edge-Version\n" +" \n" +" \n" +"
\n" +" Type\n" +" \n" +" \n" +" \n" +"
\n" +"
\n" +"
Best Regards
\n" +"
\n" +"
OpenEMS Association e.V.
\n" +"
\n" +"
\n" +" \n" +"
\n" +"
\n" +" \n" +"
\n" +" \n" +"
\n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +"
\n" +" \n" +"
\n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +"
\n" +"
Wenn Sie keine E-Mail Benachrichtigung mehr wünschen, können Sie die Funktion hier deaktivieren.
\n" +"
\n" +"
Dies ist eine automatisch generierte Nachricht. Bitte antworten Sie nicht auf diese Nachricht!
\n" +"
\n" +"
\n" +" \n" +"
\n" +"
\n" +" \n" +"
\n" +"\n" +"\n" +"\n" +" \n" +" " +msgstr "" + +#. module: openems +#: model:ir.actions.report,print_report_name:openems.action_openems_setup_protocol_report +msgid "" +"('IBN-' + object.openems_device_id.name + '-' + " +"object.create_date.strftime('%d.%m.%Y'))" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__apikey +msgid "API-Key" +msgstr "" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.openems_device_form +msgid "Access Role in Online-Monitoring" +msgstr "Zugriffsrollen im Online-Monitoring" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__message_needaction +msgid "Action Needed" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__active +msgid "Active" +msgstr "" + +#. module: openems +#: model:ir.model.fields.selection,name:openems.selection__openems_device_user_role__role__admin +#: model:ir.model.fields.selection,name:openems.selection__res_users__global_role__admin +msgid "Admin" +msgstr "" + +#. module: openems +#: model:ir.ui.menu,name:openems.menu_openems_admin +msgid "Administration" +msgstr "" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.device_search_view +msgid "Archived" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__message_attachment_count +msgid "Attachment Count" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_res_users__branding_partner_id +msgid "Branding Partner" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol_item__category +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol_production_lot__category +msgid "Category" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__comment +msgid "Comment" +msgstr "" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.openems_device_form +msgid "Configuration" +msgstr "Konfiguration" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.openems_device_form +msgid "Configuration Updates" +msgstr "Konfigurationsänderungen" + +#. module: openems +#: model:ir.model,name:openems.model_res_partner +msgid "Contact" +msgstr "Kontakt" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__create_uid +#: model:ir.model.fields,field_description:openems.field_openems_device_tag__create_uid +#: model:ir.model.fields,field_description:openems.field_openems_device_user_role__create_uid +#: model:ir.model.fields,field_description:openems.field_openems_openemsconfigupdate__create_uid +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol__create_uid +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol_item__create_uid +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol_production_lot__create_uid +#: model:ir.model.fields,field_description:openems.field_openems_systemmessage__create_uid +msgid "Created by" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__create_date +#: model:ir.model.fields,field_description:openems.field_openems_device_tag__create_date +#: model:ir.model.fields,field_description:openems.field_openems_device_user_role__create_date +#: model:ir.model.fields,field_description:openems.field_openems_openemsconfigupdate__create_date +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol__create_date +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol_item__create_date +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol_production_lot__create_date +#: model:ir.model.fields,field_description:openems.field_openems_systemmessage__create_date +msgid "Created on" +msgstr "" + +#. module: openems +#: model:res.partner.category,name:openems.res_partner_category_created_via_ibn +msgid "Created via IBN" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_systemmessage__timestamp +msgid "Creation date" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol__customer_id +#: model:res.partner.category,name:openems.res_partner_category_customer +msgid "Customer" +msgstr "" + +#. module: openems +#: model:ir.model.fields.selection,name:openems.selection__res_users__openems_language__cz +msgid "Czech" +msgstr "" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.report_openems_setup_protocol_template +msgid "Datum:" +msgstr "" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.device_search_view +#: model_terms:ir.ui.view,arch_db:openems.openems_device_tree +msgid "Description" +msgstr "Bezeichnung" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.openems_openemsconfigupdate_tree +msgid "Details" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_stock_lot__device_id +#: model:ir.model.fields,field_description:openems.field_stock_lot__device_ids +msgid "Device" +msgstr "" + +#. module: openems +#: model:ir.actions.act_window,name:openems.action_openems_openemsconfigupdate +#: model:ir.ui.menu,name:openems.menu_openems_admin_openemsconfigupdate +msgid "Device Configuration Updates" +msgstr "" + +#. module: openems +#: model:ir.actions.act_window,name:openems.action_openems_device +#: model:ir.ui.menu,name:openems.menu_openems_content_devices +msgid "Devices" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol__different_location_id +msgid "Different Location" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__display_name +#: model:ir.model.fields,field_description:openems.field_openems_device_tag__display_name +#: model:ir.model.fields,field_description:openems.field_openems_device_user_role__display_name +#: model:ir.model.fields,field_description:openems.field_openems_openemsconfigupdate__display_name +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol__display_name +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol_item__display_name +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol_production_lot__display_name +#: model:ir.model.fields,field_description:openems.field_openems_systemmessage__display_name +msgid "Display Name" +msgstr "" + +#. module: openems +#: model:ir.model.fields.selection,name:openems.selection__res_users__openems_language__nl +msgid "Dutch" +msgstr "" + +#. module: openems +#: model:mail.template,name:openems.alerting_email_generic +msgid "E-Mail Alerting" +msgstr "" + +#. module: openems +#: model:mail.template,name:openems.registration_email +msgid "E-Mail Kunden Registrierung" +msgstr "" + +#. module: openems +#: model:mail.template,name:openems.setup_protocol_email_customer +msgid "E-Mail setup protocol for customer" +msgstr "" + +#. module: openems +#: model:mail.template,name:openems.setup_protocol_email_installer +msgid "E-Mail setup protocol for installer" +msgstr "" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.report_openems_setup_protocol_template +msgid "E-Mail-Adresse" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__emshardware +msgid "EMS Hardware" +msgstr "" + +#. module: openems +#: model:ir.model.fields.selection,name:openems.selection__res_users__openems_language__en +msgid "English" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol__item_ids +msgid "Entry Items" +msgstr "" + +#. module: openems +#: model:ir.model.fields.selection,name:openems.selection__openems_device__openems_sum_state_level__fault +msgid "Fault" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol_item__field +msgid "Field Identifier" +msgstr "" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.report_openems_setup_protocol_template +msgid "Firmenname" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__first_setup_protocol_date +msgid "First Setup Protocol Date" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__message_follower_ids +msgid "Followers" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__message_partner_ids +msgid "Followers (Partners)" +msgstr "" + +#. module: openems +#: model:ir.model.fields.selection,name:openems.selection__res_users__openems_language__fr +msgid "French" +msgstr "" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.openems_device_form +msgid "General" +msgstr "" + +#. module: openems +#: model:ir.model.fields.selection,name:openems.selection__res_users__openems_language__de +msgid "German" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_res_users__global_role +msgid "Global Role" +msgstr "" + +#. module: openems +#: model:ir.model.fields.selection,name:openems.selection__openems_device_user_role__role__guest +#: model:ir.model.fields.selection,name:openems.selection__res_users__global_role__guest +msgid "Guest" +msgstr "" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.openems_device_form +msgid "Hardware" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__has_message +msgid "Has Message" +msgstr "" + +#. module: openems +#: model:ir.model.fields.selection,name:openems.selection__res_users__openems_language__hu +msgid "Hungarian" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__id +#: model:ir.model.fields,field_description:openems.field_openems_device_tag__id +#: model:ir.model.fields,field_description:openems.field_openems_device_user_role__id +#: model:ir.model.fields,field_description:openems.field_openems_openemsconfigupdate__id +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol__id +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol_item__id +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol_production_lot__id +#: model:ir.model.fields,field_description:openems.field_openems_systemmessage__id +msgid "ID" +msgstr "" + +#. module: openems +#: model:ir.model.fields,help:openems.field_openems_device__message_needaction +msgid "If checked, new messages require your attention." +msgstr "" + +#. module: openems +#: model:ir.model.fields,help:openems.field_openems_device__message_has_error +#: model:ir.model.fields,help:openems.field_openems_device__message_has_sms_error +msgid "If checked, some messages have a delivery error." +msgstr "" + +#. module: openems +#: model:ir.model.fields.selection,name:openems.selection__openems_device__openems_sum_state_level__info +msgid "Info" +msgstr "" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.report_openems_setup_protocol_template +msgid "Installateur" +msgstr "" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.openems_device_form +msgid "Installation" +msgstr "Inbetriebnahme" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.openems_device_form +msgid "Installation Log" +msgstr "Inbetriebnahme Protokolle" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__setup_password +msgid "Installation key" +msgstr "Installateursschlüssel" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_res_partner__installer_setup_protocols_ids +#: model:ir.model.fields,field_description:openems.field_res_users__installer_setup_protocols_ids +msgid "Installed OpenEMS Edge" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol__installer_id +#: model:ir.model.fields.selection,name:openems.selection__openems_device_user_role__role__installer +#: model:ir.model.fields.selection,name:openems.selection__res_users__global_role__installer +msgid "Installer" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__internalnote +msgid "Internal note" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__message_is_follower +msgid "Is Follower" +msgstr "" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.openems_device_form +msgid "Is connected" +msgstr "" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.report_openems_setup_protocol_template +msgid "Kontaktdaten Endkunde" +msgstr "" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.report_openems_setup_protocol_template +msgid "Land" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device____last_update +#: model:ir.model.fields,field_description:openems.field_openems_device_tag____last_update +#: model:ir.model.fields,field_description:openems.field_openems_device_user_role____last_update +#: model:ir.model.fields,field_description:openems.field_openems_openemsconfigupdate____last_update +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol____last_update +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol_item____last_update +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol_production_lot____last_update +#: model:ir.model.fields,field_description:openems.field_openems_systemmessage____last_update +msgid "Last Modified on" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__write_uid +#: model:ir.model.fields,field_description:openems.field_openems_device_tag__write_uid +#: model:ir.model.fields,field_description:openems.field_openems_device_user_role__write_uid +#: model:ir.model.fields,field_description:openems.field_openems_openemsconfigupdate__write_uid +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol__write_uid +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol_item__write_uid +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol_production_lot__write_uid +#: model:ir.model.fields,field_description:openems.field_openems_systemmessage__write_uid +msgid "Last Updated by" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__write_date +#: model:ir.model.fields,field_description:openems.field_openems_device_tag__write_date +#: model:ir.model.fields,field_description:openems.field_openems_device_user_role__write_date +#: model:ir.model.fields,field_description:openems.field_openems_openemsconfigupdate__write_date +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol__write_date +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol_item__write_date +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol_production_lot__write_date +#: model:ir.model.fields,field_description:openems.field_openems_systemmessage__write_date +msgid "Last Updated on" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__lastupdate +msgid "Last data update" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__lastmessage +msgid "Last message" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device_user_role__last_notification +msgid "Last notification sent" +msgstr "" + +#. module: openems +#: model:ir.model,name:openems.model_stock_lot +msgid "Lot/Serial" +msgstr "Los/Serie" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__message_main_attachment_id +msgid "Main Attachment" +msgstr "" + +#. module: openems +#: model:res.groups,name:openems.group_openems_manager +msgid "Manager" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__manual_setup_date +msgid "Manual Setup Date" +msgstr "" + +#. module: openems +#: model:res.groups,comment:openems.group_openems_manager +msgid "Members of this group can manage all devices" +msgstr "" + +#. module: openems +#: model:res.groups,comment:openems.group_openems_reader +msgid "Members of this group have reading access to all devices" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_systemmessage__text +msgid "Message" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__message_has_error +msgid "Message Delivery error" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__message_ids +msgid "Messages" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__name +#: model:ir.model.fields,field_description:openems.field_openems_device_tag__name +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol_item__name +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol_production_lot__name +msgid "Name" +msgstr "" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.report_openems_setup_protocol_template +msgid "Name Installateur" +msgstr "" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.report_openems_setup_protocol_template +msgid "Name Kontaktperson" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__name_number +msgid "Name Number" +msgstr "" + +#. module: openems +#: model:ir.model.constraint,message:openems.constraint_openems_device_unique_name +msgid "Name needs to be unique" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device_user_role__time_to_wait +msgid "Notification" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__message_needaction_counter +msgid "Number of Actions" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__message_has_error_counter +msgid "Number of errors" +msgstr "" + +#. module: openems +#: model:ir.model.fields,help:openems.field_openems_device__message_needaction_counter +msgid "Number of messages requiring action" +msgstr "" + +#. module: openems +#: model:ir.model.fields,help:openems.field_openems_device__message_has_error_counter +msgid "Number of messages with delivery error" +msgstr "" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.openems_device_tree +msgid "OE Connected" +msgstr "" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.openems_device_tree +msgid "OE State" +msgstr "" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.openems_device_tree +msgid "OE Version" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__oem +msgid "OEM Branding" +msgstr "" + +#. module: openems +#: model:ir.model.fields.selection,name:openems.selection__openems_device__openems_sum_state_level__ok +msgid "Ok" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__monitoring_url +msgid "Online-Monitoring" +msgstr "" + +#. module: openems +#: model:ir.model.fields.selection,name:openems.selection__openems_device__oem__openems +#: model:ir.module.category,name:openems.module_category_openems +#: model:ir.ui.menu,name:openems.menu_openems +#: model_terms:ir.ui.view,arch_db:openems.openems_users_form +msgid "OpenEMS" +msgstr "" + +#. module: openems +#: model:mail.template,subject:openems.alerting_email_generic +msgid "OpenEMS Alert - Edge is offline" +msgstr "" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.report_openems_setup_protocol_template +msgid "OpenEMS Association e.V." +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__openems_config_components +msgid "OpenEMS Config" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__openems_config +msgid "OpenEMS Config Full" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__openems_config_update_ids +msgid "OpenEMS Config Updates" +msgstr "" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.openems_openemsconfigupdate_tree +msgid "OpenEMS Configuration Updates" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device_user_role__device_id +#: model:ir.model.fields,field_description:openems.field_openems_openemsconfigupdate__device_id +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol__device_id +#: model:ir.model.fields,field_description:openems.field_openems_systemmessage__device_id +#: model:ir.model.fields.selection,name:openems.selection__openems_device__producttype__openems-edge +#: model:ir.ui.menu,name:openems.menu_openems_content +msgid "OpenEMS Edge" +msgstr "" + +#. module: openems +#: model:ir.model,name:openems.model_openems_device +msgid "OpenEMS Edge Device" +msgstr "" + +#. module: openems +#: model:ir.model,name:openems.model_openems_openemsconfigupdate +msgid "OpenEMS Edge Device Configuration Update" +msgstr "" + +#. module: openems +#: model:ir.model,name:openems.model_openems_device_tag +msgid "OpenEMS Edge Device Tag" +msgstr "" + +#. module: openems +#: model:ir.model,name:openems.model_openems_device_user_role +msgid "OpenEMS Edge Device User Role" +msgstr "" + +#. module: openems +#: model:ir.model,name:openems.model_openems_setup_protocol_item +msgid "OpenEMS Edge Setup Protocol Entry Item" +msgstr "" + +#. module: openems +#: model:ir.model,name:openems.model_openems_setup_protocol_production_lot +msgid "OpenEMS Edge Setup Protocol Serial Number" +msgstr "" + +#. module: openems +#: model:ir.model,name:openems.model_openems_setup_protocol +msgid "OpenEMS Edge Setup Protocols (IBN)" +msgstr "" + +#. module: openems +#: model:ir.model,name:openems.model_openems_systemmessage +msgid "OpenEMS Edge Systemmessage" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__openems_is_connected +msgid "OpenEMS Is connected" +msgstr "" + +#. module: openems +#: model:ir.actions.report,name:openems.action_openems_setup_protocol_report +msgid "OpenEMS Setup Protocol" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__openems_sum_state_level +msgid "OpenEMS State" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__openems_version +#: model_terms:ir.ui.view,arch_db:openems.device_search_view +msgid "OpenEMS Version" +msgstr "" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.device_search_view +#: model_terms:ir.ui.view,arch_db:openems.openems_device_tree +msgid "OpenEMS-Number" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_res_users__openems_language +msgid "Openems Language" +msgstr "" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.report_openems_setup_protocol_template +msgid "Ort" +msgstr "" + +#. module: openems +#: model:ir.model.fields.selection,name:openems.selection__openems_device_user_role__role__owner +#: model:ir.model.fields.selection,name:openems.selection__res_users__global_role__owner +msgid "Owner" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_res_partner__customer_setup_protocols_ids +#: model:ir.model.fields,field_description:openems.field_res_users__customer_setup_protocols_ids +msgid "Owner of OpenEMS Edge" +msgstr "" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.report_openems_setup_protocol_template +msgid "PLZ" +msgstr "" + +#. module: openems +#: model:ir.model.fields,help:openems.field_openems_device__setup_password +msgid "Password for commissioning by the installer" +msgstr "Passwort für die Inbetriebnahme durch den Installateur" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.openems_setup_protocol_form +msgid "Print" +msgstr "" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.openems_device_form +msgid "Product" +msgstr "Produkt" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__producttype +msgid "Product type" +msgstr "" + +#. module: openems +#: model:res.groups,name:openems.group_openems_reader +msgid "Read access" +msgstr "" + +#. module: openems +#: model:mail.template,subject:openems.registration_email +msgid "Registrierung erfolgreich" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device_user_role__role +msgid "Role" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__user_role_ids +#: model:ir.model.fields,field_description:openems.field_res_users__device_role_ids +msgid "Roles" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__message_has_sms_error +msgid "SMS Delivery error" +msgstr "" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.openems_device_form +msgid "Security" +msgstr "Sicherheit" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol_production_lot__lot_id +msgid "Serial Number" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol__productionlot_ids +msgid "Serial Numbers" +msgstr "" + +#. module: openems +#: model:ir.model.constraint,message:openems.constraint_openems_device_unique_stock_production_lot_id +msgid "Serial number needs to be unique" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol_item__setup_protocol_id +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol_production_lot__setup_protocol_id +#: model_terms:ir.ui.view,arch_db:openems.report_openems_setup_protocol_template +msgid "Setup Protocol" +msgstr "" + +#. module: openems +#: model:ir.actions.act_window,name:openems.action_openems_admin_setup_protocol +#: model:ir.model.fields,field_description:openems.field_openems_device__setup_protocol_ids +#: model:ir.ui.menu,name:openems.menu_openems_admin_setup_protocol +#: model_terms:ir.ui.view,arch_db:openems.res_partner_form +msgid "Setup Protocols" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol_item__sequence +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol_production_lot__sequence +msgid "Sort" +msgstr "" + +#. module: openems +#: model:ir.model.fields.selection,name:openems.selection__res_users__openems_language__es +msgid "Spanish" +msgstr "" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.report_openems_setup_protocol_template +msgid "Speicherstandort" +msgstr "" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.openems_device_form +msgid "Status" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__stock_production_lot_id +msgid "Stock Production Lot" +msgstr "" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.report_openems_setup_protocol_template +msgid "Straße / Hausnummer" +msgstr "" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.openems_device_form +msgid "System Messages" +msgstr "" + +#. module: openems +#: model:ir.actions.act_window,name:openems.action_openems_systemmessage +#: model:ir.model.fields,field_description:openems.field_openems_device__systemmessage_ids +#: model:ir.ui.menu,name:openems.menu_openems_admin_systemmessages +msgid "Systemmessages" +msgstr "" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.openems_device_form +msgid "Systemstatus" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__tag_ids +msgid "Tags" +msgstr "" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.report_openems_setup_protocol_template +msgid "Telefonnummer" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_systemmessage__text_teaser +msgid "Text Teaser" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_openemsconfigupdate__details +msgid "Update Details" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_openemsconfigupdate__teaser +msgid "Update Details Teaser" +msgstr "" + +#. module: openems +#: model:ir.model,name:openems.model_res_users +#: model:ir.model.fields,field_description:openems.field_openems_device_user_role__user_id +msgid "User" +msgstr "Benutzer" + +#. module: openems +#: model:ir.model.constraint,message:openems.constraint_openems_device_user_role_device_user_uniq +msgid "User already exists for this device." +msgstr "" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.openems_systemmessage_tree +msgid "Users" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol_item__value +msgid "Value" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol_item__view +msgid "View Identifier" +msgstr "" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.report_openems_setup_protocol_template +msgid "Vor- Nachname" +msgstr "" + +#. module: openems +#: model:ir.model.fields.selection,name:openems.selection__openems_device__openems_sum_state_level__warning +msgid "Warning" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__website_message_ids +msgid "Website Messages" +msgstr "" + +#. module: openems +#: model:ir.model.fields,help:openems.field_openems_device__website_message_ids +msgid "Website communication history" +msgstr "" + +#. module: openems +#: model:mail.template,subject:openems.setup_protocol_email_customer +#: model:mail.template,subject:openems.setup_protocol_email_installer +msgid "Your OpenEMS setup protocol for {{object.openems_device_id.name}}" +msgstr "" diff --git a/addons/openems/i18n/openems.pot b/addons/openems/i18n/openems.pot new file mode 100644 index 0000000..c02fb93 --- /dev/null +++ b/addons/openems/i18n/openems.pot @@ -0,0 +1,1666 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * openems +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 16.0-20240218\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2024-02-18 11:56+0000\n" +"PO-Revision-Date: 2024-02-18 11:56+0000\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: openems +#: model:mail.template,body_html:openems.setup_protocol_email_installer +msgid "" +"\n" +"\n" +"\n" +"\n" +"\n" +" OpenEMS setup protocol \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +"\n" +"\n" +"\n" +"
\n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +"
\n" +" \n" +"
\n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +"
\n" +" \n" +"
\n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +"
\n" +"

\n" +"

\n" +" \n" +"
\n" +"
Dear \n" +" ,\n" +"
\n" +"
\n" +"
please find the setup protocol for your customer attached.\n" +"
\n" +"
\n" +"
Best Regards
\n" +"
\n" +"
OpenEMS Association e.V.
\n" +"
\n" +"
\n" +" \n" +"
\n" +"
\n" +" \n" +"
\n" +"
\n" +"\n" +"\n" +"\n" +" \n" +" " +msgstr "" + +#. module: openems +#: model:mail.template,body_html:openems.registration_email +msgid "" +"\n" +"\n" +"\n" +"\n" +"\n" +" Registrierung erfolgreich \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +"\n" +"\n" +"\n" +"
\n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +"
\n" +" \n" +"
\n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +"
\n" +" \n" +"
\n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +"
\n" +"

\n" +"

\n" +" \n" +"
\n" +"
Guten Tag \n" +" ,\n" +"
\n" +"
\n" +"
Ihr Zugang zu OpenEMS UI wurde erstellt.
\n" +"
\n" +"
Sie können sich auf OpenEMS UI einloggen, um auf das Online-Monitoring zuzugreifen.
\n" +"
\n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +"
Ihre Zugangsdaten:
E-Mail\n" +" \n" +"
Passwort\n" +" \n" +"
\n" +"
\n" +"
Best Regards
\n" +"
\n" +"
OpenEMS Association e.V.
\n" +"
\n" +"
\n" +" \n" +"
\n" +"
\n" +" \n" +"
\n" +"
\n" +"\n" +"\n" +"\n" +" \n" +" " +msgstr "" + +#. module: openems +#: model:mail.template,body_html:openems.setup_protocol_email_customer +msgid "" +"\n" +"\n" +"\n" +"\n" +"\n" +" Your OpenEMS Edge setup protocol \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +"\n" +"\n" +"\n" +"
\n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +"
\n" +" \n" +"
\n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +"
\n" +" \n" +"
\n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +"
\n" +"

\n" +"

\n" +" \n" +"
\n" +"
Welcome to OpenEMS,
\n" +"
\n" +"
please find your setup protocol for OpenEMS Edge attached.
\n" +"
\n" +"
Best Regards
\n" +"
\n" +"
OpenEMS Association e.V.
\n" +"
\n" +"
\n" +" \n" +"
\n" +"
\n" +" \n" +"
\n" +"
\n" +"\n" +"\n" +"\n" +" \n" +" " +msgstr "" + +#. module: openems +#: model:mail.template,body_html:openems.alerting_email_generic +msgid "" +"\n" +"\n" +"\n" +"\n" +"\n" +" OpenEMS Alert - Edge is offline\n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +"\n" +"\n" +"\n" +"
\n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +"
\n" +" \n" +"
\n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +"
\n" +" \n" +"
\n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +"
\n" +"

\n" +"

\n" +" \n" +"
\n" +"
Dear \n" +" ,\n" +"
\n" +"
\n" +"
Your OpenEMS Edge with number is offline since:
\n" +"
\n" +"
\n" +" \n" +" \n" +" \n" +" \n" +" \n" +" (UTC)\n" +" \n" +"
\n" +"
\n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +"
Info
\n" +" Edge-Version\n" +" \n" +" \n" +"
\n" +" Type\n" +" \n" +" \n" +" \n" +"
\n" +"
\n" +"
Best Regards
\n" +"
\n" +"
OpenEMS Association e.V.
\n" +"
\n" +"
\n" +" \n" +"
\n" +"
\n" +" \n" +"
\n" +" \n" +"
\n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +"
\n" +" \n" +"
\n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +"
\n" +"
Wenn Sie keine E-Mail Benachrichtigung mehr wünschen, können Sie die Funktion hier deaktivieren.
\n" +"
\n" +"
Dies ist eine automatisch generierte Nachricht. Bitte antworten Sie nicht auf diese Nachricht!
\n" +"
\n" +"
\n" +" \n" +"
\n" +"
\n" +" \n" +"
\n" +"\n" +"\n" +"\n" +" \n" +" " +msgstr "" + +#. module: openems +#: model:ir.actions.report,print_report_name:openems.action_openems_setup_protocol_report +msgid "" +"('IBN-' + object.openems_device_id.name + '-' + " +"object.create_date.strftime('%d.%m.%Y'))" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__apikey +msgid "API-Key" +msgstr "" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.openems_device_form +msgid "Access Role in Online-Monitoring" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__message_needaction +msgid "Action Needed" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__active +msgid "Active" +msgstr "" + +#. module: openems +#: model:ir.model.fields.selection,name:openems.selection__openems_device_user_role__role__admin +#: model:ir.model.fields.selection,name:openems.selection__res_users__global_role__admin +msgid "Admin" +msgstr "" + +#. module: openems +#: model:ir.ui.menu,name:openems.menu_openems_admin +msgid "Administration" +msgstr "" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.device_search_view +msgid "Archived" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__message_attachment_count +msgid "Attachment Count" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_res_users__branding_partner_id +msgid "Branding Partner" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol_item__category +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol_production_lot__category +msgid "Category" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__comment +msgid "Comment" +msgstr "" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.openems_device_form +msgid "Configuration" +msgstr "" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.openems_device_form +msgid "Configuration Updates" +msgstr "" + +#. module: openems +#: model:ir.model,name:openems.model_res_partner +msgid "Contact" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__create_uid +#: model:ir.model.fields,field_description:openems.field_openems_device_tag__create_uid +#: model:ir.model.fields,field_description:openems.field_openems_device_user_role__create_uid +#: model:ir.model.fields,field_description:openems.field_openems_openemsconfigupdate__create_uid +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol__create_uid +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol_item__create_uid +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol_production_lot__create_uid +#: model:ir.model.fields,field_description:openems.field_openems_systemmessage__create_uid +msgid "Created by" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__create_date +#: model:ir.model.fields,field_description:openems.field_openems_device_tag__create_date +#: model:ir.model.fields,field_description:openems.field_openems_device_user_role__create_date +#: model:ir.model.fields,field_description:openems.field_openems_openemsconfigupdate__create_date +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol__create_date +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol_item__create_date +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol_production_lot__create_date +#: model:ir.model.fields,field_description:openems.field_openems_systemmessage__create_date +msgid "Created on" +msgstr "" + +#. module: openems +#: model:res.partner.category,name:openems.res_partner_category_created_via_ibn +msgid "Created via IBN" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_systemmessage__timestamp +msgid "Creation date" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol__customer_id +#: model:res.partner.category,name:openems.res_partner_category_customer +msgid "Customer" +msgstr "" + +#. module: openems +#: model:ir.model.fields.selection,name:openems.selection__res_users__openems_language__cz +msgid "Czech" +msgstr "" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.report_openems_setup_protocol_template +msgid "Datum:" +msgstr "" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.device_search_view +#: model_terms:ir.ui.view,arch_db:openems.openems_device_tree +msgid "Description" +msgstr "" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.openems_openemsconfigupdate_tree +msgid "Details" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_stock_lot__device_id +#: model:ir.model.fields,field_description:openems.field_stock_lot__device_ids +msgid "Device" +msgstr "" + +#. module: openems +#: model:ir.actions.act_window,name:openems.action_openems_openemsconfigupdate +#: model:ir.ui.menu,name:openems.menu_openems_admin_openemsconfigupdate +msgid "Device Configuration Updates" +msgstr "" + +#. module: openems +#: model:ir.actions.act_window,name:openems.action_openems_device +#: model:ir.ui.menu,name:openems.menu_openems_content_devices +msgid "Devices" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol__different_location_id +msgid "Different Location" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__display_name +#: model:ir.model.fields,field_description:openems.field_openems_device_tag__display_name +#: model:ir.model.fields,field_description:openems.field_openems_device_user_role__display_name +#: model:ir.model.fields,field_description:openems.field_openems_openemsconfigupdate__display_name +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol__display_name +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol_item__display_name +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol_production_lot__display_name +#: model:ir.model.fields,field_description:openems.field_openems_systemmessage__display_name +msgid "Display Name" +msgstr "" + +#. module: openems +#: model:ir.model.fields.selection,name:openems.selection__res_users__openems_language__nl +msgid "Dutch" +msgstr "" + +#. module: openems +#: model:mail.template,name:openems.alerting_email_generic +msgid "E-Mail Alerting" +msgstr "" + +#. module: openems +#: model:mail.template,name:openems.registration_email +msgid "E-Mail Kunden Registrierung" +msgstr "" + +#. module: openems +#: model:mail.template,name:openems.setup_protocol_email_customer +msgid "E-Mail setup protocol for customer" +msgstr "" + +#. module: openems +#: model:mail.template,name:openems.setup_protocol_email_installer +msgid "E-Mail setup protocol for installer" +msgstr "" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.report_openems_setup_protocol_template +msgid "E-Mail-Adresse" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__emshardware +msgid "EMS Hardware" +msgstr "" + +#. module: openems +#: model:ir.model.fields.selection,name:openems.selection__res_users__openems_language__en +msgid "English" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol__item_ids +msgid "Entry Items" +msgstr "" + +#. module: openems +#: model:ir.model.fields.selection,name:openems.selection__openems_device__openems_sum_state_level__fault +msgid "Fault" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol_item__field +msgid "Field Identifier" +msgstr "" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.report_openems_setup_protocol_template +msgid "Firmenname" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__first_setup_protocol_date +msgid "First Setup Protocol Date" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__message_follower_ids +msgid "Followers" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__message_partner_ids +msgid "Followers (Partners)" +msgstr "" + +#. module: openems +#: model:ir.model.fields.selection,name:openems.selection__res_users__openems_language__fr +msgid "French" +msgstr "" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.openems_device_form +msgid "General" +msgstr "" + +#. module: openems +#: model:ir.model.fields.selection,name:openems.selection__res_users__openems_language__de +msgid "German" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_res_users__global_role +msgid "Global Role" +msgstr "" + +#. module: openems +#: model:ir.model.fields.selection,name:openems.selection__openems_device_user_role__role__guest +#: model:ir.model.fields.selection,name:openems.selection__res_users__global_role__guest +msgid "Guest" +msgstr "" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.openems_device_form +msgid "Hardware" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__has_message +msgid "Has Message" +msgstr "" + +#. module: openems +#: model:ir.model.fields.selection,name:openems.selection__res_users__openems_language__hu +msgid "Hungarian" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__id +#: model:ir.model.fields,field_description:openems.field_openems_device_tag__id +#: model:ir.model.fields,field_description:openems.field_openems_device_user_role__id +#: model:ir.model.fields,field_description:openems.field_openems_openemsconfigupdate__id +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol__id +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol_item__id +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol_production_lot__id +#: model:ir.model.fields,field_description:openems.field_openems_systemmessage__id +msgid "ID" +msgstr "" + +#. module: openems +#: model:ir.model.fields,help:openems.field_openems_device__message_needaction +msgid "If checked, new messages require your attention." +msgstr "" + +#. module: openems +#: model:ir.model.fields,help:openems.field_openems_device__message_has_error +#: model:ir.model.fields,help:openems.field_openems_device__message_has_sms_error +msgid "If checked, some messages have a delivery error." +msgstr "" + +#. module: openems +#: model:ir.model.fields.selection,name:openems.selection__openems_device__openems_sum_state_level__info +msgid "Info" +msgstr "" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.report_openems_setup_protocol_template +msgid "Installateur" +msgstr "" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.openems_device_form +msgid "Installation" +msgstr "" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.openems_device_form +msgid "Installation Log" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__setup_password +msgid "Installation key" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_res_partner__installer_setup_protocols_ids +#: model:ir.model.fields,field_description:openems.field_res_users__installer_setup_protocols_ids +msgid "Installed OpenEMS Edge" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol__installer_id +#: model:ir.model.fields.selection,name:openems.selection__openems_device_user_role__role__installer +#: model:ir.model.fields.selection,name:openems.selection__res_users__global_role__installer +msgid "Installer" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__internalnote +msgid "Internal note" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__message_is_follower +msgid "Is Follower" +msgstr "" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.openems_device_form +msgid "Is connected" +msgstr "" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.report_openems_setup_protocol_template +msgid "Kontaktdaten Endkunde" +msgstr "" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.report_openems_setup_protocol_template +msgid "Land" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device____last_update +#: model:ir.model.fields,field_description:openems.field_openems_device_tag____last_update +#: model:ir.model.fields,field_description:openems.field_openems_device_user_role____last_update +#: model:ir.model.fields,field_description:openems.field_openems_openemsconfigupdate____last_update +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol____last_update +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol_item____last_update +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol_production_lot____last_update +#: model:ir.model.fields,field_description:openems.field_openems_systemmessage____last_update +msgid "Last Modified on" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__write_uid +#: model:ir.model.fields,field_description:openems.field_openems_device_tag__write_uid +#: model:ir.model.fields,field_description:openems.field_openems_device_user_role__write_uid +#: model:ir.model.fields,field_description:openems.field_openems_openemsconfigupdate__write_uid +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol__write_uid +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol_item__write_uid +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol_production_lot__write_uid +#: model:ir.model.fields,field_description:openems.field_openems_systemmessage__write_uid +msgid "Last Updated by" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__write_date +#: model:ir.model.fields,field_description:openems.field_openems_device_tag__write_date +#: model:ir.model.fields,field_description:openems.field_openems_device_user_role__write_date +#: model:ir.model.fields,field_description:openems.field_openems_openemsconfigupdate__write_date +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol__write_date +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol_item__write_date +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol_production_lot__write_date +#: model:ir.model.fields,field_description:openems.field_openems_systemmessage__write_date +msgid "Last Updated on" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__lastupdate +msgid "Last data update" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__lastmessage +msgid "Last message" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device_user_role__last_notification +msgid "Last notification sent" +msgstr "" + +#. module: openems +#: model:ir.model,name:openems.model_stock_lot +msgid "Lot/Serial" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__message_main_attachment_id +msgid "Main Attachment" +msgstr "" + +#. module: openems +#: model:res.groups,name:openems.group_openems_manager +msgid "Manager" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__manual_setup_date +msgid "Manual Setup Date" +msgstr "" + +#. module: openems +#: model:res.groups,comment:openems.group_openems_manager +msgid "Members of this group can manage all devices" +msgstr "" + +#. module: openems +#: model:res.groups,comment:openems.group_openems_reader +msgid "Members of this group have reading access to all devices" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_systemmessage__text +msgid "Message" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__message_has_error +msgid "Message Delivery error" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__message_ids +msgid "Messages" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__name +#: model:ir.model.fields,field_description:openems.field_openems_device_tag__name +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol_item__name +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol_production_lot__name +msgid "Name" +msgstr "" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.report_openems_setup_protocol_template +msgid "Name Installateur" +msgstr "" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.report_openems_setup_protocol_template +msgid "Name Kontaktperson" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__name_number +msgid "Name Number" +msgstr "" + +#. module: openems +#: model:ir.model.constraint,message:openems.constraint_openems_device_unique_name +msgid "Name needs to be unique" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device_user_role__time_to_wait +msgid "Notification" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__message_needaction_counter +msgid "Number of Actions" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__message_has_error_counter +msgid "Number of errors" +msgstr "" + +#. module: openems +#: model:ir.model.fields,help:openems.field_openems_device__message_needaction_counter +msgid "Number of messages requiring action" +msgstr "" + +#. module: openems +#: model:ir.model.fields,help:openems.field_openems_device__message_has_error_counter +msgid "Number of messages with delivery error" +msgstr "" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.openems_device_tree +msgid "OE Connected" +msgstr "" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.openems_device_tree +msgid "OE State" +msgstr "" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.openems_device_tree +msgid "OE Version" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__oem +msgid "OEM Branding" +msgstr "" + +#. module: openems +#: model:ir.model.fields.selection,name:openems.selection__openems_device__openems_sum_state_level__ok +msgid "Ok" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__monitoring_url +msgid "Online-Monitoring" +msgstr "" + +#. module: openems +#: model:ir.model.fields.selection,name:openems.selection__openems_device__oem__openems +#: model:ir.module.category,name:openems.module_category_openems +#: model:ir.ui.menu,name:openems.menu_openems +#: model_terms:ir.ui.view,arch_db:openems.openems_users_form +msgid "OpenEMS" +msgstr "" + +#. module: openems +#: model:mail.template,subject:openems.alerting_email_generic +msgid "OpenEMS Alert - Edge is offline" +msgstr "" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.report_openems_setup_protocol_template +msgid "OpenEMS Association e.V." +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__openems_config_components +msgid "OpenEMS Config" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__openems_config +msgid "OpenEMS Config Full" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__openems_config_update_ids +msgid "OpenEMS Config Updates" +msgstr "" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.openems_openemsconfigupdate_tree +msgid "OpenEMS Configuration Updates" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device_user_role__device_id +#: model:ir.model.fields,field_description:openems.field_openems_openemsconfigupdate__device_id +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol__device_id +#: model:ir.model.fields,field_description:openems.field_openems_systemmessage__device_id +#: model:ir.model.fields.selection,name:openems.selection__openems_device__producttype__openems-edge +#: model:ir.ui.menu,name:openems.menu_openems_content +msgid "OpenEMS Edge" +msgstr "" + +#. module: openems +#: model:ir.model,name:openems.model_openems_device +msgid "OpenEMS Edge Device" +msgstr "" + +#. module: openems +#: model:ir.model,name:openems.model_openems_openemsconfigupdate +msgid "OpenEMS Edge Device Configuration Update" +msgstr "" + +#. module: openems +#: model:ir.model,name:openems.model_openems_device_tag +msgid "OpenEMS Edge Device Tag" +msgstr "" + +#. module: openems +#: model:ir.model,name:openems.model_openems_device_user_role +msgid "OpenEMS Edge Device User Role" +msgstr "" + +#. module: openems +#: model:ir.model,name:openems.model_openems_setup_protocol_item +msgid "OpenEMS Edge Setup Protocol Entry Item" +msgstr "" + +#. module: openems +#: model:ir.model,name:openems.model_openems_setup_protocol_production_lot +msgid "OpenEMS Edge Setup Protocol Serial Number" +msgstr "" + +#. module: openems +#: model:ir.model,name:openems.model_openems_setup_protocol +msgid "OpenEMS Edge Setup Protocols (IBN)" +msgstr "" + +#. module: openems +#: model:ir.model,name:openems.model_openems_systemmessage +msgid "OpenEMS Edge Systemmessage" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__openems_is_connected +msgid "OpenEMS Is connected" +msgstr "" + +#. module: openems +#: model:ir.actions.report,name:openems.action_openems_setup_protocol_report +msgid "OpenEMS Setup Protocol" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__openems_sum_state_level +msgid "OpenEMS State" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__openems_version +#: model_terms:ir.ui.view,arch_db:openems.device_search_view +msgid "OpenEMS Version" +msgstr "" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.device_search_view +#: model_terms:ir.ui.view,arch_db:openems.openems_device_tree +msgid "OpenEMS-Number" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_res_users__openems_language +msgid "Openems Language" +msgstr "" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.report_openems_setup_protocol_template +msgid "Ort" +msgstr "" + +#. module: openems +#: model:ir.model.fields.selection,name:openems.selection__openems_device_user_role__role__owner +#: model:ir.model.fields.selection,name:openems.selection__res_users__global_role__owner +msgid "Owner" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_res_partner__customer_setup_protocols_ids +#: model:ir.model.fields,field_description:openems.field_res_users__customer_setup_protocols_ids +msgid "Owner of OpenEMS Edge" +msgstr "" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.report_openems_setup_protocol_template +msgid "PLZ" +msgstr "" + +#. module: openems +#: model:ir.model.fields,help:openems.field_openems_device__setup_password +msgid "Password for commissioning by the installer" +msgstr "" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.openems_setup_protocol_form +msgid "Print" +msgstr "" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.openems_device_form +msgid "Product" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__producttype +msgid "Product type" +msgstr "" + +#. module: openems +#: model:res.groups,name:openems.group_openems_reader +msgid "Read access" +msgstr "" + +#. module: openems +#: model:mail.template,subject:openems.registration_email +msgid "Registrierung erfolgreich" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device_user_role__role +msgid "Role" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__user_role_ids +#: model:ir.model.fields,field_description:openems.field_res_users__device_role_ids +msgid "Roles" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__message_has_sms_error +msgid "SMS Delivery error" +msgstr "" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.openems_device_form +msgid "Security" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol_production_lot__lot_id +msgid "Serial Number" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol__productionlot_ids +msgid "Serial Numbers" +msgstr "" + +#. module: openems +#: model:ir.model.constraint,message:openems.constraint_openems_device_unique_stock_production_lot_id +msgid "Serial number needs to be unique" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol_item__setup_protocol_id +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol_production_lot__setup_protocol_id +#: model_terms:ir.ui.view,arch_db:openems.report_openems_setup_protocol_template +msgid "Setup Protocol" +msgstr "" + +#. module: openems +#: model:ir.actions.act_window,name:openems.action_openems_admin_setup_protocol +#: model:ir.model.fields,field_description:openems.field_openems_device__setup_protocol_ids +#: model:ir.ui.menu,name:openems.menu_openems_admin_setup_protocol +#: model_terms:ir.ui.view,arch_db:openems.res_partner_form +msgid "Setup Protocols" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol_item__sequence +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol_production_lot__sequence +msgid "Sort" +msgstr "" + +#. module: openems +#: model:ir.model.fields.selection,name:openems.selection__res_users__openems_language__es +msgid "Spanish" +msgstr "" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.report_openems_setup_protocol_template +msgid "Speicherstandort" +msgstr "" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.openems_device_form +msgid "Status" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__stock_production_lot_id +msgid "Stock Production Lot" +msgstr "" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.report_openems_setup_protocol_template +msgid "Straße / Hausnummer" +msgstr "" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.openems_device_form +msgid "System Messages" +msgstr "" + +#. module: openems +#: model:ir.actions.act_window,name:openems.action_openems_systemmessage +#: model:ir.model.fields,field_description:openems.field_openems_device__systemmessage_ids +#: model:ir.ui.menu,name:openems.menu_openems_admin_systemmessages +msgid "Systemmessages" +msgstr "" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.openems_device_form +msgid "Systemstatus" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__tag_ids +msgid "Tags" +msgstr "" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.report_openems_setup_protocol_template +msgid "Telefonnummer" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_systemmessage__text_teaser +msgid "Text Teaser" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_openemsconfigupdate__details +msgid "Update Details" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_openemsconfigupdate__teaser +msgid "Update Details Teaser" +msgstr "" + +#. module: openems +#: model:ir.model,name:openems.model_res_users +#: model:ir.model.fields,field_description:openems.field_openems_device_user_role__user_id +msgid "User" +msgstr "" + +#. module: openems +#: model:ir.model.constraint,message:openems.constraint_openems_device_user_role_device_user_uniq +msgid "User already exists for this device." +msgstr "" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.openems_systemmessage_tree +msgid "Users" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol_item__value +msgid "Value" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol_item__view +msgid "View Identifier" +msgstr "" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.report_openems_setup_protocol_template +msgid "Vor- Nachname" +msgstr "" + +#. module: openems +#: model:ir.model.fields.selection,name:openems.selection__openems_device__openems_sum_state_level__warning +msgid "Warning" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__website_message_ids +msgid "Website Messages" +msgstr "" + +#. module: openems +#: model:ir.model.fields,help:openems.field_openems_device__website_message_ids +msgid "Website communication history" +msgstr "" + +#. module: openems +#: model:mail.template,subject:openems.setup_protocol_email_customer +#: model:mail.template,subject:openems.setup_protocol_email_installer +msgid "Your OpenEMS setup protocol for {{object.openems_device_id.name}}" +msgstr "" diff --git a/addons/openems/mail/openems/alerting_offline.xml b/addons/openems/mail/openems/alerting_offline.xml new file mode 100644 index 0000000..2d2a38d --- /dev/null +++ b/addons/openems/mail/openems/alerting_offline.xml @@ -0,0 +1,275 @@ + + + + + E-Mail Offline-Alerting + + ]]> + {{object.user_id.partner_id.id}} + OpenEMS Alert - Edge is offline + + + + + OpenEMS Alert - Edge is offline + + + + + + + + + + + + + + + +
+ + + + + + +
+ +
+ + + + + + +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+

+

+ +
+
+ + + , + + Ms/Mr , + Customer, +
+
+
Your OpenEMS Edge with number is offline since: +
+
+
+ + + + + + + (UTC) + + +
+
+ + + + + + + + + + + + +
Info
+ OpenEMS-Version + + + + + UNKNOWN +
+ Type + + + + + + + +
+
+
Best Regards
+
+
OpenEMS Association e.V.
+
+
+ +
+
+ +
+ +
+ + + + + + +
+ +
+ + + + + + + + + + + + + + + +
+
If you do no longer wish to receive email notifications, you can disable the feature here .
+
+
This is an automatically generated message. Please do not reply to this message!
+
+ + + + + + +
+ OpenEMS Logo +
+
+

+

+ +
+
+ +
+
+ +
+ + + + ]]> +
+
+
+
diff --git a/addons/openems/mail/openems/alerting_sum_state.xml b/addons/openems/mail/openems/alerting_sum_state.xml new file mode 100644 index 0000000..5ac49f6 --- /dev/null +++ b/addons/openems/mail/openems/alerting_sum_state.xml @@ -0,0 +1,268 @@ + + + + + E-Mail SumState Alerting + + ]]> + {{object.user_id.partner_id.id}} + OpenEMS Alert - Edge is in {{object.device_id.openems_sum_state_level}} State + + + + + OpenEMS Alert - Edge is in fault + + + + + + + + + + + + + + + +
+ + + + + + +
+ +
+ + + + + + +
+ +
+ + + + + + + + + + + + + + + + + + + + + +
+

+

+ +
+
+ + + , + + Ms/Mr , + Customer, +
+
+
Your OpenEMS Edge with number is in a continuous + + + + + + + UNKNOWN + state! +
+
+ + + + + + + + + + + + +
Info
+ OpenEMS-Version + + + + + UNKNOWN +
+ Type + + + + + + + +
+
+
Best Regards
+
+
OpenEMS Association e.V.
+
+
+ +
+
+ +
+ +
+ + + + + + +
+ +
+ + + + + + + + + + + + + + + +
+
If you do no longer wish to receive email notifications, you can disable the feature here .
+
+
This is an automatically generated message. Please do not reply to this message!
+
+ + + + + + +
+ OpenEMS Logo +
+
+

+

+ +
+
+ +
+
+ +
+ + + + ]]> +
+
+
+
diff --git a/addons/openems/mail/openems/setup_protocol_customer.xml b/addons/openems/mail/openems/setup_protocol_customer.xml new file mode 100644 index 0000000..3b1e781 --- /dev/null +++ b/addons/openems/mail/openems/setup_protocol_customer.xml @@ -0,0 +1,170 @@ + + + + + E-Mail setup protocol for customer + + ]]> + {{object.customer_id.id}} + Your OpenEMS setup protocol for {{object.openems_device_id.name}} + false + + + + + Your OpenEMS Edge setup protocol + + + + + + + + + + + + + + + +
+ + + + + + +
+ +
+ + + + + + +
+ +
+ + + + + + + + + + + + + + + + + + +
+

+

+ +
+
Welcome to OpenEMS,
+
+
please find your setup protocol for OpenEMS Edge attached.
+
+
Best Regards
+
+
OpenEMS Association e.V.
+
+
+ +
+
+ +
+
+ + + + ]]> +
+
+
+
diff --git a/addons/openems/mail/openems/setup_protocol_installer.xml b/addons/openems/mail/openems/setup_protocol_installer.xml new file mode 100644 index 0000000..13afd9d --- /dev/null +++ b/addons/openems/mail/openems/setup_protocol_installer.xml @@ -0,0 +1,173 @@ + + + + + E-Mail setup protocol for installer + + ]]> + {{object.installer_id.id}} + Your OpenEMS setup protocol for {{object.openems_device_id.name}} + false + + + + + OpenEMS setup protocol + + + + + + + + + + + + + + + +
+ + + + + + +
+ +
+ + + + + + +
+ +
+ + + + + + + + + + + + + + + + + + +
+

+

+ +
+
Dear + , +
+
+
please find the setup protocol for your customer attached. +
+
+
Best Regards
+
+
OpenEMS Association e.V.
+
+
+ +
+
+ +
+
+ + + + ]]> +
+
+
+
diff --git a/addons/openems/mail/openems/user_registration.xml b/addons/openems/mail/openems/user_registration.xml new file mode 100644 index 0000000..cfd4183 --- /dev/null +++ b/addons/openems/mail/openems/user_registration.xml @@ -0,0 +1,197 @@ + + + + + E-Mail Kunden Registrierung + + ]]> + {{object.id}} + Registrierung erfolgreich + false + + + + + Registrierung erfolgreich + + + + + + + + + + + + + + + +
+ + + + + + +
+ +
+ + + + + + +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+

+

+ +
+
Guten Tag + , +
+
+
Ihr Zugang zu OpenEMS UI wurde erstellt.
+
+
Sie können sich auf OpenEMS UI einloggen, um auf das Online-Monitoring zuzugreifen.
+
+ + + + + + + + + + + + +
Ihre Zugangsdaten:
E-Mail + +
Passwort + +
+
+
Best Regards
+
+
OpenEMS Association e.V.
+
+
+ +
+
+ +
+
+ + + + ]]> +
+
+
+
diff --git a/addons/openems/migrations/16.0.1.0.1/post-migrate.py b/addons/openems/migrations/16.0.1.0.1/post-migrate.py new file mode 100644 index 0000000..1eab6fe --- /dev/null +++ b/addons/openems/migrations/16.0.1.0.1/post-migrate.py @@ -0,0 +1,9 @@ +def migrate(cr, version): + cr.execute(""" + INSERT INTO openems_alerting (device_id, device_name, user_id, user_login, offline_delay, warning_delay, fault_delay, offline_last_notification) + SELECT device_id, dev.name, user_id, usr.login, time_to_wait, 0, 0, last_notification + FROM openems_alerting_migrate AS migrate + LEFT JOIN openems_device AS dev ON dev.id = migrate.device_id + LEFT JOIN res_users AS usr ON usr.id = migrate.user_id + """) + cr.execute('DROP TABLE openems_alerting_migrate') diff --git a/addons/openems/migrations/16.0.1.0.1/pre-migrate.py b/addons/openems/migrations/16.0.1.0.1/pre-migrate.py new file mode 100644 index 0000000..341e4a5 --- /dev/null +++ b/addons/openems/migrations/16.0.1.0.1/pre-migrate.py @@ -0,0 +1,7 @@ +def migrate(cr, version): + cr.execute(""" + SELECT device_id, user_id, time_to_wait, last_notification + INTO openems_alerting_migrate + FROM openems_device_user_role + WHERE time_to_wait > 0; + """) diff --git a/addons/openems/models/__init__.py b/addons/openems/models/__init__.py new file mode 100644 index 0000000..c4a7e59 --- /dev/null +++ b/addons/openems/models/__init__.py @@ -0,0 +1 @@ +from . import device, partner, setup_protocol, user, stock_production_lot diff --git a/addons/openems/models/device.py b/addons/openems/models/device.py new file mode 100644 index 0000000..bdbda80 --- /dev/null +++ b/addons/openems/models/device.py @@ -0,0 +1,321 @@ +from odoo import api, fields, models, exceptions, _ +from datetime import datetime +from odoo.exceptions import ValidationError +import random +import re +import string + +class Device(models.Model): + _name = "openems.device" + _description = "OpenEMS Edge Device" + _inherit = "mail.thread" + _order = "name_number asc" + _sql_constraints = [ + ("unique_name", "unique(name)", "Name needs to be unique"), + ("unique_stock_production_lot_id", "unique(stock_production_lot_id)", + "Serial number needs to be unique") + ] + + name = fields.Char(required=True) + active = fields.Boolean("Active", default=True, tracking=True) + comment = fields.Char(tracking=True) + internalnote = fields.Text("Internal note", tracking=True) + tag_ids = fields.Many2many("openems.device_tag", string="Tags", tracking=True) + monitoring_url = fields.Char( + "Online-Monitoring", compute="_compute_monitoring_url", store=False + ) + stock_production_lot_id = fields.Many2one("stock.lot") + first_setup_protocol_date = fields.Datetime( + "First Setup Protocol Date", compute="_compute_first_setup_protocol" + ) + manual_setup_date = fields.Datetime("Manual Setup Date") + + @api.depends("setup_protocol_ids", "manual_setup_date") + def _compute_first_setup_protocol(self): + for rec in self: + if rec.manual_setup_date: + rec.first_setup_protocol_date = rec.manual_setup_date + elif len(rec.setup_protocol_ids) > 0: + rec.first_setup_protocol_date = rec.setup_protocol_ids[ + (len(rec.setup_protocol_ids) - 1) + ]["create_date"] + else: + rec.first_setup_protocol_date = None + + @api.depends("name") + def _compute_monitoring_url(self): + # Corrected the parameter key to 'edge_monitoring_url' + base_url = self.env["ir.config_parameter"].sudo().get_param("edge_monitoring_url", default='#') + for rec in self: + if isinstance(rec.name, str) and rec.name: + # Ensuring there is a '/' between base_url and rec.name if it's not already present + separator = '' if base_url.endswith('/') else '/' + rec.monitoring_url = base_url + separator + rec.name + "/live" + else: + rec.monitoring_url = base_url + + producttype = fields.Selection( + [ + ("openems-edge", "OpenEMS Edge"), + ], + "Product type", + tracking=True, + ) + emshardware = fields.Selection([], "EMS Hardware", tracking=True) + oem = fields.Selection( + [ + ("openems", "OpenEMS"), + ], + "OEM Branding", + default="openems", + ) + + # Settings + openems_config = fields.Text("OpenEMS Config Full") + openems_config_components = fields.Text("OpenEMS Config") + openems_version = fields.Char("OpenEMS Version", tracking=True) + + # Security + setup_password = fields.Char( + "Installation Key", + help="Password for commissioning by the installer", + ) + apikey = fields.Char("API-Key", required=True, tracking=True) + + # 'openems_sum_state_level' is updated by OpenEMS Backend + openems_sum_state_level = fields.Selection( + [("ok", "Ok"), ("info", "Info"), ("warning", "Warning"), ("fault", "Fault")], + "OpenEMS State", + ) + # 'openems_is_connected' is updated by OpenEMS Backend + openems_is_connected = fields.Boolean("OpenEMS Is connected") + + # System Status + lastmessage = fields.Datetime("Last message") + lastupdate = fields.Datetime("Last data update") + + # Verknüpfungen + systemmessage_ids = fields.One2many( + "openems.systemmessage", "device_id", string="System Messages" + ) + user_role_ids = fields.One2many( + "openems.device_user_role", "device_id", string="Roles", tracking=True + ) + alerting_settings = fields.One2many( + "openems.alerting", "device_id", string="Alerting", tracking=True + ) + openems_config_update_ids = fields.One2many( + "openems.openemsconfigupdate", "device_id", string="OpenEMS Config Updates" + ) + setup_protocol_ids = fields.One2many( + "openems.setup_protocol", "device_id", "Setup Protocols" + ) + + # Helper fields + name_number = fields.Integer(compute="_compute_name_number", store="True") + + @api.depends("name") + def _compute_name_number(self): + for rec in self: + rec.name_number = int(rec.name[4:]) if rec.name.startswith("edge") else -1 + + def _get_openems_state_number(self, string): + state = 0 + if string == "info": + state = 1 + elif string == "warning": + state = 2 + elif string == "fault": + state = 3 + return state + + def write(self, vals): + """Prohibit to change name field after creation.""" + if 'name' in vals: + for record in self: + if record.id and record.name != vals['name']: + self.env.cr.execute(""" + SELECT EXISTS ( + SELECT 1 FROM openems_device + WHERE name = %s AND id != %s + ) + """, (vals['name'], record.id)) + exists = self.env.cr.fetchone()[0] + if exists: + # This means there's already a device with the intended new name + raise exceptions.UserError( + "The name '{}' is already in use or does not follow the required pattern.".format( + vals['name'])) + + # If you simply want to prevent name changes, the following UserError suffices + raise exceptions.UserError("The name of the device cannot be changed after creation.") + return super(Device, self).write(vals) + + @api.model + def create(self, vals): + + # Generate setup password if not provided + if 'setup_password' not in vals or not vals['setup_password']: + vals['setup_password'] = self._generate_unique_setup_password() + + # Generate API key if not provided + if 'apikey' not in vals or not vals['apikey']: + vals['apikey'] = self._generate_api_key() + + return super(Device, self).create(vals) + + def _generate_unique_setup_password(self): + is_unique = False + setup_password = '' + while not is_unique: + # Generate a random setup password + raw_password = ''.join(random.choices(string.ascii_uppercase + string.digits, k=16)) + setup_password = '-'.join([raw_password[i:i + 4] for i in range(0, len(raw_password), 4)]) + # Check if the generated setup password already exists + existing = self.search_count([('setup_password', '=', setup_password)]) + # If the password does not exist, it is unique, and we can exit the loop + if existing == 0: + is_unique = True + return setup_password + + def _generate_api_key(self): + # Initialize a flag to indicate whether the generated key is unique + is_unique = False + api_key = '' + while not is_unique: + # Generate a random API key + api_key = ''.join(random.choices(string.ascii_letters + string.digits, k=20)) + # Check if the generated API key already exists + existing = self.search_count([('apikey', '=', api_key)]) + # If the key does not exist, it is unique, and we can exit the loop + if existing == 0: + is_unique = True + return api_key + + @api.onchange('setup_password') + def _check_setup_password_format(self): + for record in self: + if not record.setup_password: + continue + if not re.match(r"^[A-Z0-9]{4}-[A-Z0-9]{4}-[A-Z0-9]{4}-[A-Z0-9]{4}$", record.setup_password): + raise ValidationError("The device ID must be formatted as XXXX-XXXX-XXXX-XXXX") + + @api.onchange('apikey') + def _check_api_key_uniqueness(self): + for record in self: + if record.apikey: + # Prepare the domain for searching duplicates + domain = [('apikey', '=', record.apikey)] + # If the record is already saved (has a valid database ID), exclude it from the search + if record.id and isinstance(record.id, (int,)): + domain.append(('id', '!=', record.id)) + # Check if any other records with the same API key exist + existing = self.search_count(domain) + # If there are duplicates, raise a ValidationError + if existing: + raise ValidationError( + _("The API key already exists and must be unique. Please choose a different API key.")) + + +class DeviceTag(models.Model): + _name = "openems.device_tag" + _description = "OpenEMS Edge Device Tag" + name = fields.Char(required=True) + + +class DeviceUserRole(models.Model): + _name = "openems.device_user_role" + _description = "OpenEMS Edge Device User Role" + _sql_constraints = [ + ( + "device_user_uniq", + "unique(device_id, user_id)", + "User already exists for this device.", + ), + ] + device_id = fields.Many2one("openems.device", string="OpenEMS Edge") + user_id = fields.Many2one("res.users", string="User") + role = fields.Selection( + [ + ("admin", "Admin"), + ("installer", "Installer"), + ("owner", "Owner"), + ("guest", "Guest"), + ], + default="guest", + required=True, + ) + + +class OpenemsConfigUpdate(models.Model): + _name = "openems.openemsconfigupdate" + _description = "OpenEMS Edge Device Configuration Update" + _order = "create_date desc" + + device_id = fields.Many2one("openems.device", string="OpenEMS Edge") + teaser = fields.Text("Update Details Teaser") + details = fields.Html("Update Details") + + +class Systemmessage(models.Model): + _name = "openems.systemmessage" + _description = "OpenEMS Edge Systemmessage" + _order = "create_date desc" + + timestamp = fields.Datetime("Creation date") + device_id = fields.Many2one("openems.device", string="OpenEMS Edge") + text = fields.Text("Message") + text_teaser = fields.Char(compute="_compute_text_teaser") + + @api.depends("text") + def _compute_text_teaser(self): + for rec in self: + # get up to 100 characters from first line + rec.text_teaser = rec.text.splitlines()[0][0:100] if rec.text else False + +class Alerting(models.Model): + _name = "openems.alerting" + _description = "OpenEMS Edge AlertingSettings" + _sql_constraints = [ + ( + "device_user_uniq", + "unique(device_id, user_id)", + "User already has Alerting Settings.", + ), + ] + + device_id = fields.Many2one("openems.device", string="OpenEMS Edge") + user_id = fields.Many2one("res.users", string="User") + + offline_delay = fields.Integer(string="Offline Notification", default=1440) + warning_delay = fields.Integer(string="Warning Notification", default=1440) + fault_delay = fields.Integer(string="Fault Notification", default=1440) + + offline_last_notification = fields.Datetime(string="Last Offline notification sent") + sum_state_last_notification = fields.Datetime(string="Last SumState notification sent") + + device_name = fields.Text(compute="_compute_device_name", store="True") + user_login = fields.Text(compute="_compute_user_login", store="True") + + user_role = fields.Selection( + [("admin", "Admin"), ("installer", "Installer"), ("owner", "Owner"), ("guest", "Guest"),], + compute="_compute_user_role", store="False") + + @api.depends("device_id") + def _compute_device_name(self): + for rec in self: + rec.device_name = rec.device_id.name; + + @api.depends("user_id") + def _compute_user_login(self): + for rec in self: + rec.user_login = rec.user_id.login; + + @api.depends("user_id", "device_id") + def _compute_user_role(self): + for rec in self: + user_role: DeviceUserRole = rec.user_id.device_role_ids.search([('device_id','=',rec.device_id.id)]) + if user_role: + return user_role.role + else: + return rec.user_id.global_role diff --git a/addons/openems/models/partner.py b/addons/openems/models/partner.py new file mode 100644 index 0000000..37ab8e5 --- /dev/null +++ b/addons/openems/models/partner.py @@ -0,0 +1,12 @@ +from odoo import fields, models + + +class ResPartner(models.Model): + _inherit = "res.partner" + + installer_setup_protocols_ids = fields.One2many( + "openems.setup_protocol", "installer_id", "Installed OpenEMS Edge" + ) + customer_setup_protocols_ids = fields.One2many( + "openems.setup_protocol", "customer_id", "Owner of OpenEMS Edge" + ) diff --git a/addons/openems/models/setup_protocol.py b/addons/openems/models/setup_protocol.py new file mode 100644 index 0000000..548576e --- /dev/null +++ b/addons/openems/models/setup_protocol.py @@ -0,0 +1,49 @@ +from odoo import fields, models + + +class SetupProtocol(models.Model): + _name = "openems.setup_protocol" + _description = "OpenEMS Edge Setup Protocols (IBN)" + _order = "create_date desc" + + customer_id = fields.Many2one("res.partner", "Customer", required=True) + different_location_id = fields.Many2one("res.partner", "Different Location") + installer_id = fields.Many2one("res.partner", "Installer", required=True) + device_id = fields.Many2one("openems.device", "OpenEMS Edge", required=True) + productionlot_ids = fields.One2many( + "openems.setup_protocol_production_lot", "setup_protocol_id", "Serial Numbers" + ) + item_ids = fields.One2many( + "openems.setup_protocol_item", "setup_protocol_id", "Entry Items" + ) + + +class SetupProtocolProductionLot(models.Model): + _name = "openems.setup_protocol_production_lot" + _description = "OpenEMS Edge Setup Protocol Serial Number" + _order = "setup_protocol_id, category, sequence asc" + + sequence = fields.Integer("Sort") + category = fields.Char("Category") + name = fields.Char("Name") + lot_id = fields.Many2one("stock.production.lot", "Serial Number") + setup_protocol_id = fields.Many2one( + "openems.setup_protocol", "Setup Protocol", ondelete="cascade" + ) + + +class SetupProtocolItem(models.Model): + _name = "openems.setup_protocol_item" + _description = "OpenEMS Edge Setup Protocol Entry Item" + _order = "setup_protocol_id, category, sequence asc" + + sequence = fields.Integer("Sort") + category = fields.Char("Category") + name = fields.Char("Name") + value = fields.Char("Value") + setup_protocol_id = fields.Many2one( + "openems.setup_protocol", "Setup Protocol", ondelete="cascade" + ) + view = fields.Char("View Identifier") + field = fields.Char("Field Identifier") + diff --git a/addons/openems/models/stock_production_lot.py b/addons/openems/models/stock_production_lot.py new file mode 100644 index 0000000..37ebb22 --- /dev/null +++ b/addons/openems/models/stock_production_lot.py @@ -0,0 +1,23 @@ +from odoo import fields, models, api + + +class ProductionLot(models.Model): + _inherit = "stock.lot" + + device_id = fields.Many2one( + 'openems.device', compute='compute_device_id', inverse='device_inverse') + device_ids = fields.One2many('openems.device', 'stock_production_lot_id') + + @api.depends('device_ids') + def compute_device_id(self): + if len(self.device_ids) > 0: + self.device_id = self.device_ids[0] + + def device_inverse(self): + if len(self.device_ids) > 0: + if len(self.device_id.stock_production_lot_id) > 0: + raise ValueError("A serial number has already been assigned to the device") + + device = self.env['openems.device'].browse(self.device_ids[0].id) + device.stock_production_lot_id = False + self.device_id.stock_production_lot_id = self diff --git a/addons/openems/models/user.py b/addons/openems/models/user.py new file mode 100644 index 0000000..321dd87 --- /dev/null +++ b/addons/openems/models/user.py @@ -0,0 +1,37 @@ +from odoo import fields, models + + +class ResUsers(models.Model): + _inherit = "res.users" + + branding_partner_id = fields.Many2one("res.partner", string="Branding Partner") + global_role = fields.Selection( + [ + ("admin", "Admin"), + ("installer", "Installer"), + ("owner", "Owner"), + ("guest", "Guest"), + ], + default="guest", + required=True, + ) + device_role_ids = fields.One2many( + "openems.device_user_role", "user_id", string="Roles" + ) + alerting_settings = fields.One2many( + "openems.alerting", "user_id", string="Alerting" + ) + openems_language = fields.Selection( + [ + ("EN", "English"), + ("DE", "German"), + ("CZ", "Czech"), + ("NL", "Dutch"), + ("ES", "Spanish"), + ("FR", "French"), + ("HU", "Hungarian"), + ("JA", "Japanese"), + ], + default="DE", + required=True, + ) diff --git a/addons/openems/report/setup_protocol.xml b/addons/openems/report/setup_protocol.xml new file mode 100644 index 0000000..c9db4ec --- /dev/null +++ b/addons/openems/report/setup_protocol.xml @@ -0,0 +1,311 @@ + + + + OpenEMS Setup Protocol + openems.setup_protocol + qweb-pdf + openems.report_openems_setup_protocol_template + ('IBN-' + object.openems_device_id.name + '-' + object.create_date.strftime('%d.%m.%Y')) + + + diff --git a/addons/openems/security/ir.model.access.csv b/addons/openems/security/ir.model.access.csv new file mode 100644 index 0000000..1ccc0f1 --- /dev/null +++ b/addons/openems/security/ir.model.access.csv @@ -0,0 +1,31 @@ +id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink +access_openems_device_portal,access_openems_device_portal,openems.model_openems_device,base.group_portal,1,0,0,0 +access_openems_device_user,access_openems_device_user,openems.model_openems_device,base.group_user,1,0,0,0 +access_openems_device_manager,access_openems_device_manager,openems.model_openems_device,openems.group_openems_manager,1,1,1,0 +access_openems_device_tag_portal,access_openems_device_tag_portal,openems.model_openems_device_tag,base.group_portal,1,0,0,0 +access_openems_device_tag_user,access_openems_device_tag_user,openems.model_openems_device_tag,base.group_user,1,0,0,0 +access_openems_device_tag_manager,access_openems_device_tag_manager,openems.model_openems_device_tag,openems.group_openems_manager,1,1,1,1 +access_openems_device_user_role_portal,access_openems_device_user_role_portal,openems.model_openems_device_user_role,base.group_portal,1,0,0,0 +access_openems_device_user_role_user,access_openems_device_user_role_user,openems.model_openems_device_user_role,base.group_user,1,0,0,0 +access_openems_device_user_role_manager,access_openems_device_user_role_manager,openems.model_openems_device_user_role,openems.group_openems_manager,1,1,1,1 +access_openems_alerting_portal,access_openems_alerting_portal,openems.model_openems_alerting,base.group_portal,1,0,0,0 +access_openems_alerting_user,access_openems_alerting_user,openems.model_openems_alerting,base.group_user,1,0,0,0 +access_openems_alerting_manager,access_openems_alerting_manager,openems.model_openems_alerting,openems.group_openems_manager,1,1,1,1 +access_openems_systemmessage_portal,access_openems_systemmessage_portal,openems.model_openems_systemmessage,base.group_portal,1,0,0,0 +access_openems_systemmessage_user,access_openems_systemmessage_user,openems.model_openems_systemmessage,base.group_user,1,0,0,0 +access_openems_systemmessage_manager,access_openems_systemmessage_manager,openems.model_openems_systemmessage,openems.group_openems_manager,1,1,1,1 +access_openems_openemsconfigupdate_portal,access_openems_openemsconfigupdate_portal,openems.model_openems_openemsconfigupdate,base.group_portal,1,0,0,0 +access_openems_openemsconfigupdate_user,access_openems_openemsconfigupdate_user,openems.model_openems_openemsconfigupdate,base.group_user,1,0,0,0 +access_openems_openemsconfigupdate_manager,access_openems_openemsconfigupdate_manager,openems.model_openems_openemsconfigupdate,openems.group_openems_manager,1,1,1,1 +access_openems_setup_protocol_portal,access_openems_setup_protocol_portal,openems.model_openems_setup_protocol,base.group_portal,1,0,0,0 +access_openems_setup_protocol_user,access_openems_setup_protocol_user,openems.model_openems_setup_protocol,base.group_user,1,0,0,0 +access_openems_setup_protocol_manager,access_openems_setup_protocol_manager,openems.model_openems_setup_protocol,openems.group_openems_manager,1,1,1,1 +access_openems_setup_protocol_production_lot_portal,access_openems_setup_protocol_production_lot_portal,openems.model_openems_setup_protocol_production_lot,base.group_portal,1,0,0,0 +access_openems_setup_protocol_production_lot_user,access_openems_setup_protocol_production_lot_user,openems.model_openems_setup_protocol_production_lot,base.group_user,1,0,0,0 +access_openems_setup_protocol_production_lot_manager,access_openems_setup_protocol_production_lot_manager,openems.model_openems_setup_protocol_production_lot,openems.group_openems_manager,1,1,1,1 +access_openems_setup_protocol_item_portal,access_openems_setup_protocol_item_portal,openems.model_openems_setup_protocol_item,base.group_portal,1,0,0,0 +access_openems_setup_protocol_item_user,access_openems_setup_protocol_item_user,openems.model_openems_setup_protocol_item,base.group_user,1,0,0,0 +access_openems_setup_protocol_item_manager,access_openems_setup_protocol_item_manager,openems.model_openems_setup_protocol_item,openems.group_openems_manager,1,1,1,1 +access_openems_production_lot_portal,access_openems_production_lot_portal,stock.model_stock_lot,base.group_portal,1,0,0,0 +access_openems_production_lot_user,access_openems_production_lot_user,stock.model_stock_lot,base.group_user,1,0,0,0 +access_openems_production_lot_manager,access_openems_production_lot_manager,stock.model_stock_lot,openems.group_openems_manager,1,0,0,0 diff --git a/addons/openems/security/openems.xml b/addons/openems/security/openems.xml new file mode 100644 index 0000000..ef87c2f --- /dev/null +++ b/addons/openems/security/openems.xml @@ -0,0 +1,54 @@ + + + + OpenEMS + 30 + + + + Read access + Members of this group have reading access to all devices + + + + + Manager + Members of this group can manage all devices + + + + + + + Website: Show only approved devices to Portal and User + + ['|', ('user_role_ids.user_id','in',[user.id]), ('alerting_settings.user_id','in',[user.id])] + + + + + + + + + Website: Show all devices to readers group + + [(1,'=',1)] + + + + + + + + diff --git a/addons/openems/setup/.setuptools-odoo-make-default-ignore b/addons/openems/setup/.setuptools-odoo-make-default-ignore new file mode 100644 index 0000000..207e615 --- /dev/null +++ b/addons/openems/setup/.setuptools-odoo-make-default-ignore @@ -0,0 +1,2 @@ +# addons listed in this file are ignored by +# setuptools-odoo-make-default (one addon per line) diff --git a/addons/openems/setup/README b/addons/openems/setup/README new file mode 100644 index 0000000..a63d633 --- /dev/null +++ b/addons/openems/setup/README @@ -0,0 +1,2 @@ +To learn more about this directory, please visit +https://pypi.python.org/pypi/setuptools-odoo diff --git a/addons/openems/static/description/icon.png b/addons/openems/static/description/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..ee0aed1a0d5b623df9c4f3ead2a8d92ab7efc315 GIT binary patch literal 53271 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

`b%zWJVoybJJC+al7(vmUoDSw-d(zU?;>j| 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 + + + + Device: Tree + openems.device + + + + + + + + + + + + + + + + + Device: Search + openems.device + + + + + + + + + + + + + + + + + + + + + Device: Form + openems.device + +

+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + +
+ + + + + + Device DeviceUserRole: Tree + openems.device_user_role + + + + + + + + + + Devices + ir.actions.act_window + openems.device + tree,form + + + + + + Device Configuration Updates + openems.openemsconfigupdate + + + + Device Configuration Updates: Tree + openems.openemsconfigupdate + + + + + + + + + + + Device Configuration Updates: Form + openems.openemsconfigupdate + +
+ + + + + + + +
+
+
+ + + + Systemmessages + openems.systemmessage + + + + Device Systemmessage: Tree + openems.systemmessage + + + + + + + + + + + Device Systemmessage: Form + openems.systemmessage + +
+ + + + + + + +
+
+
+ + + + + + + + + diff --git a/addons/openems/views/partner.xml b/addons/openems/views/partner.xml new file mode 100644 index 0000000..874530e --- /dev/null +++ b/addons/openems/views/partner.xml @@ -0,0 +1,28 @@ + + + + OpenEMS Partner: Form + res.partner + + + + + + + + + + + + + + + + + + + + + + + diff --git a/addons/openems/views/setup_protocol.xml b/addons/openems/views/setup_protocol.xml new file mode 100644 index 0000000..bf2eee2 --- /dev/null +++ b/addons/openems/views/setup_protocol.xml @@ -0,0 +1,82 @@ + + + + SetupProtocol: Form + openems.setup_protocol + +
+ + +
+ + +
+ + + diff --git a/addons/web_m2x_options/static/src/components/form.esm.js b/addons/web_m2x_options/static/src/components/form.esm.js new file mode 100644 index 0000000..ecb37d2 --- /dev/null +++ b/addons/web_m2x_options/static/src/components/form.esm.js @@ -0,0 +1,404 @@ +/** @odoo-module **/ + +import { + Many2ManyTagsField, + Many2ManyTagsFieldColorEditable, +} from "@web/views/fields/many2many_tags/many2many_tags_field"; + +import {Dialog} from "@web/core/dialog/dialog"; +import {FormController} from "@web/views/form/form_controller"; +import {FormViewDialog} from "@web/views/view_dialogs/form_view_dialog"; +import {Many2OneAvatarField} from "@web/views/fields/many2one_avatar/many2one_avatar_field"; +import {Many2OneBarcodeField} from "@web/views/fields/many2one_barcode/many2one_barcode_field"; +import {Many2OneField} from "@web/views/fields/many2one/many2one_field"; +import {ReferenceField} from "@web/views/fields/reference/reference_field"; +import {X2ManyField} from "@web/views/fields/x2many/x2many_field"; +import {isX2Many} from "@web/views/utils"; +import {is_option_set} from "@web_m2x_options/components/relational_utils.esm"; +import {patch} from "@web/core/utils/patch"; +import {sprintf} from "@web/core/utils/strings"; +import {useService} from "@web/core/utils/hooks"; + +const {Component} = owl; + +/** + * Patch Many2ManyTagsField + **/ +patch(Many2ManyTagsField.prototype, "web_m2x_options.Many2ManyTagsField", { + setup() { + this._super(...arguments); + this.actionService = useService("action"); + }, + /** + * @override + */ + getTagProps(record) { + const props = this._super(...arguments); + props.onClick = (ev) => this.onMany2ManyBadgeClick(ev, record); + return props; + }, + async onMany2ManyBadgeClick(event, record) { + var self = this; + if (self.props.open) { + var context = self.context; + var id = record.data.id; + if (self.props.readonly) { + event.preventDefault(); + event.stopPropagation(); + const action = await self.orm.call( + self.props.relation, + "get_formview_action", + [[id]], + {context: context} + ); + self.actionService.doAction(action); + } else { + const view_id = await self.orm.call( + self.props.relation, + "get_formview_id", + [[id]], + {context: context} + ); + + const write_access = await self.orm.call( + self.props.relation, + "check_access_rights", + [], + {operation: "write", raise_exception: false} + ); + var can_write = self.props.canWrite; + self.dialog.add(FormViewDialog, { + resModel: self.props.relation, + resId: id, + context: context, + title: self.env._t("Open: ") + self.string, + viewId: view_id, + mode: !can_write || !write_access ? "readonly" : "edit", + onRecordSaved: () => self.props.value.model.load(), + }); + } + } + }, +}); + +Many2ManyTagsField.props = { + ...Many2ManyTagsField.props, + open: {type: Boolean, optional: true}, + canWrite: {type: Boolean, optional: true}, + nodeOptions: {type: Object, optional: true}, +}; + +const Many2ManyTagsFieldExtractProps = Many2ManyTagsField.extractProps; +Many2ManyTagsField.extractProps = ({attrs, field}) => { + const canOpen = Boolean(attrs.options.open); + const canWrite = attrs.can_write && Boolean(JSON.parse(attrs.can_write)); + return Object.assign(Many2ManyTagsFieldExtractProps({attrs, field}), { + open: canOpen, + canWrite: canWrite, + nodeOptions: attrs.options, + }); +}; + +/** + * Many2ManyTagsFieldColorEditable + **/ +patch( + Many2ManyTagsFieldColorEditable.prototype, + "web_m2x_options.Many2ManyTagsFieldColorEditable", + { + async onBadgeClick(event, record) { + if (this.props.canEditColor && !this.props.open) { + this._super(...arguments); + } + if (this.props.open) { + Many2ManyTagsField.prototype.onMany2ManyBadgeClick.bind(this)( + event, + record + ); + } + }, + } +); + +Many2ManyTagsFieldColorEditable.props = { + ...Many2ManyTagsFieldColorEditable.props, + open: {type: Boolean, optional: true}, + canWrite: {type: Boolean, optional: true}, + nodeOptions: {type: Object, optional: true}, +}; + +/** + * CreateConfirmationDialog + * New customized component for Many2One Field + **/ + +class CreateConfirmationDialog extends Component { + get title() { + return sprintf(this.env._t("New: %s"), this.props.name); + } + + async onCreate() { + await this.props.create(); + this.props.close(); + } + async onCreateEdit() { + await this.props.createEdit(); + this.props.close(); + } +} +CreateConfirmationDialog.components = {Dialog}; +CreateConfirmationDialog.template = + "web_m2x_options.Many2OneField.CreateConfirmationDialog"; + +/** + * Many2OneField + **/ + +patch(Many2OneField.prototype, "web_m2x_options.Many2OneField", { + setup() { + this._super(...arguments); + this.ir_options = Component.env.session.web_m2x_options; + }, + /** + * @override + */ + get Many2XAutocompleteProps() { + const props = this._super(...arguments); + return { + ...props, + searchLimit: this.props.searchLimit, + searchMore: this.props.searchMore, + canCreate: this.props.canCreate, + nodeOptions: this.props.nodeOptions, + }; + }, + + async openConfirmationDialog(request) { + var m2o_dialog_opt = + is_option_set(this.props.nodeOptions.m2o_dialog) || + (_.isUndefined(this.props.nodeOptions.m2o_dialog) && + is_option_set(this.ir_options["web_m2x_options.m2o_dialog"])) || + (_.isUndefined(this.props.nodeOptions.m2o_dialog) && + _.isUndefined(this.ir_options["web_m2x_options.m2o_dialog"])); + if (this.props.canCreate && this.state.isFloating && m2o_dialog_opt) { + return new Promise((resolve, reject) => { + this.addDialog(CreateConfirmationDialog, { + value: request, + name: this.props.string, + create: async () => { + try { + await this.quickCreate(request); + resolve(); + } catch (e) { + reject(e); + } + }, + createEdit: async () => { + try { + await this.quickCreate(request); + await this.props.record.model.load(); + this.openMany2X({ + resId: this.props.value[0], + context: this.user_context, + }); + resolve(); + } catch (e) { + reject(e); + } + }, + }); + }); + } + }, +}); + +const Many2OneFieldExtractProps = Many2OneField.extractProps; +Many2OneField.extractProps = ({attrs, field}) => { + return Object.assign(Many2OneFieldExtractProps({attrs, field}), { + searchLimit: attrs.options.limit, + searchMore: attrs.options.search_more, + nodeOptions: attrs.options, + }); +}; + +Many2OneField.props = { + ...Many2OneField.props, + searchMore: {type: Boolean, optional: true}, + nodeOptions: {type: Object, optional: true}, +}; + +/** + * FIXME: find better way to extend props in Many2OneField + * Override ReferenceField + * Since extracted/added props: nodeOptions and searchMore into Many2OneField props + * and this component inherited props from Many2OneField + * So, must override props here to avoid constraint validateProps (props schema) in owl core + */ + +ReferenceField.props = { + ...ReferenceField.props, + searchMore: {type: Boolean, optional: true}, + nodeOptions: {type: Object, optional: true}, +}; + +/** + * FIXME: find better way to extend props in Many2OneField + * Override Many2OneBarcodeField + * Since extracted/added props: nodeOptions and searchMore into Many2OneField props + * and this component inherited props from Many2OneField + * So, must override props here to avoid constraint validateProps (props schema) in owl core + */ + +Many2OneBarcodeField.props = { + ...Many2OneBarcodeField.props, + searchMore: {type: Boolean, optional: true}, + nodeOptions: {type: Object, optional: true}, +}; + +/** + * FIXME: find better way to extend props in Many2OneField + * Override Many2OneAvatarField + * Since extracted/added props: nodeOptions and searchMore into Many2OneField props + * and this component inherited props from Many2OneField + * So, must override props here to avoid constraint validateProps (props schema) in owl core + */ +Many2OneAvatarField.props = { + ...Many2OneAvatarField.props, + searchMore: {type: Boolean, optional: true}, + nodeOptions: {type: Object, optional: true}, +}; + +/** + * FIXME: find better way to extend props in Many2OneField + * Override mailing_m2o_filter + * Since extracted/added props: nodeOptions and searchMore into Many2OneField props + * and this component inherited props from Many2OneField + * So, must override props here to avoid constraint validateProps (props schema) in owl core + * This component is in module mass_mailing as optional module, + * So need to import dynamic way + */ +try { + (async () => { + // Make sure component mailing_m2o_filter in mass mailing module loaded + const installed_mass_mailing = await odoo.ready( + "@mass_mailing/js/mailing_m2o_filter" + ); + if (installed_mass_mailing) { + const {FieldMany2OneMailingFilter} = await odoo.runtimeImport( + "@mass_mailing/js/mailing_m2o_filter" + ); + FieldMany2OneMailingFilter.props = { + ...FieldMany2OneMailingFilter.props, + searchMore: {type: Boolean, optional: true}, + nodeOptions: {type: Object, optional: true}, + }; + } + })(); +} catch { + console.log( + "Ignore overriding props of component mailing_m2o_filter since the module is not installed" + ); +} + +/** + * X2ManyField + **/ +patch(X2ManyField.prototype, "web_m2x_options.X2ManyField", { + /** + * @override + */ + async openRecord(record) { + var self = this; + var open = this.props.open; + if (open && self.props.readonly) { + var res_id = record.data.id; + const action = await self.env.model.orm.call( + self.props.value.resModel, + "get_formview_action", + [[res_id]] + ); + return self.env.model.actionService.doAction(action); + } + return this._super.apply(this, arguments); + }, +}); + +const X2ManyFieldExtractProps = X2ManyField.extractProps; +X2ManyField.extractProps = ({attrs}) => { + const canOpen = Boolean(attrs.options.open); + return Object.assign(X2ManyFieldExtractProps({attrs}), { + open: canOpen, + }); +}; + +X2ManyField.props = { + ...X2ManyField.props, + open: {type: Boolean, optional: true}, +}; + +/** + * FormController + **/ +patch(FormController.prototype, "web_m2x_options.FormController", { + /** + * @override + */ + setup() { + var self = this; + this._super(...arguments); + + /** Due to problem of 2 onWillStart in native web core + * (see: https://github.com/odoo/odoo/blob/16.0/addons/web/static/src/views/model.js#L142) + * do the trick to override beforeLoadResolver here to customize viewLimit + */ + this.superBeforeLoadResolver = this.beforeLoadResolver; + this.beforeLoadResolver = async () => { + await self._setSubViewLimit(); + self.superBeforeLoadResolver(); + }; + }, + /** + * @override + * add more method to add subview limit on formview + */ + async _setSubViewLimit() { + const ir_options = Component.env.session.web_m2x_options; + + const activeFields = this.archInfo.activeFields, + fields = this.props.fields, + isSmall = this.user; + + var limit = ir_options["web_m2x_options.field_limit_entries"]; + if (!_.isUndefined(limit)) { + limit = parseInt(limit, 10); + } + + for (const fieldName in activeFields) { + const field = fields[fieldName]; + if (!isX2Many(field)) { + // What follows only concerns x2many fields + continue; + } + const fieldInfo = activeFields[fieldName]; + if (fieldInfo.modifiers.invisible === true) { + // No need to fetch the sub view if the field is always invisible + continue; + } + + if (!fieldInfo.FieldComponent.useSubView) { + // The FieldComponent used to render the field doesn't need a sub view + continue; + } + + let viewType = fieldInfo.viewMode || "list,kanban"; + viewType = viewType.replace("tree", "list"); + if (viewType.includes(",")) { + viewType = isSmall ? "kanban" : "list"; + } + fieldInfo.viewMode = viewType; + if (fieldInfo.views[viewType] && limit) { + fieldInfo.views[viewType].limit = limit; + } + } + }, +}); diff --git a/addons/web_m2x_options/static/src/components/relational_utils.esm.js b/addons/web_m2x_options/static/src/components/relational_utils.esm.js new file mode 100644 index 0000000..1fbe39e --- /dev/null +++ b/addons/web_m2x_options/static/src/components/relational_utils.esm.js @@ -0,0 +1,221 @@ +/** @odoo-module **/ + +import {Many2XAutocomplete} from "@web/views/fields/relational_utils"; +import {patch} from "@web/core/utils/patch"; +import {sprintf} from "@web/core/utils/strings"; +const {Component} = owl; + +export function is_option_set(option) { + if (_.isUndefined(option)) return false; + if (typeof option === "string") return option === "true" || option === "True"; + if (typeof option === "boolean") return option; + return false; +} + +patch(Many2XAutocomplete.prototype, "web_m2x_options.Many2XAutocomplete", { + setup() { + this._super(...arguments); + this.ir_options = Component.env.session.web_m2x_options; + }, + + async loadOptionsSource(request) { + if (this.lastProm) { + this.lastProm.abort(false); + } + // Add options limit used to change number of selections record + // returned. + if (!_.isUndefined(this.ir_options["web_m2x_options.limit"])) { + this.props.searchLimit = parseInt( + this.ir_options["web_m2x_options.limit"], + 10 + ); + this.limit = this.props.searchLimit; + } + + if (typeof this.props.nodeOptions.limit === "number") { + this.props.searchLimit = this.props.nodeOptions.limit; + this.limit = this.props.searchLimit; + } + + // Add options field_color and colors to color item(s) depending on field_color value + this.field_color = this.props.nodeOptions.field_color; + this.colors = this.props.nodeOptions.colors; + + this.lastProm = this.orm.call(this.props.resModel, "name_search", [], { + name: request, + operator: "ilike", + args: this.props.getDomain(), + limit: this.props.searchLimit + 1, + context: this.props.context, + }); + const records = await this.lastProm; + + var options = records.map((result) => ({ + value: result[0], + id: result[0], + label: result[1].split("\n")[0], + })); + + // Limit results if there is a custom limit options + if (this.limit) { + options = options.slice(0, this.props.searchLimit); + } + + // Search result value colors + if (this.colors && this.field_color) { + var value_ids = options.map((result) => result.value); + const objects = await this.orm.call( + this.props.resModel, + "search_read", + [], + { + domain: [["id", "in", value_ids]], + fields: [this.field_color], + } + ); + for (var index in objects) { + for (var index_value in options) { + if (options[index_value].id === objects[index].id) { + // Find value in values by comparing ids + var option = options[index_value]; + // Find color with field value as key + var color = + this.colors[objects[index][this.field_color]] || "black"; + option.style = "color:" + color; + break; + } + } + } + } + + // Quick create + // Note: Create should be before `search_more` (reserve native order) + // One more reason: when calling `onInputBlur`, native select the first option (activeSourceOption) + // which triggers m2o_dialog if m2o_dialog=true + var create_enabled = + this.props.quickCreate && !this.props.nodeOptions.no_create; + + var raw_result = _.map(records, function (x) { + return x[1]; + }); + var quick_create = is_option_set(this.props.nodeOptions.create), + quick_create_undef = _.isUndefined(this.props.nodeOptions.create), + m2x_create_undef = _.isUndefined(this.ir_options["web_m2x_options.create"]), + m2x_create = is_option_set(this.ir_options["web_m2x_options.create"]); + var show_create = + (!this.props.nodeOptions && (m2x_create_undef || m2x_create)) || + (this.props.nodeOptions && + (quick_create || + (quick_create_undef && (m2x_create_undef || m2x_create)))); + if ( + create_enabled && + !this.props.nodeOptions.no_quick_create && + request.length > 0 && + !_.contains(raw_result, request) && + show_create + ) { + options.push({ + label: sprintf(this.env._t(`Create "%s"`), request), + classList: "o_m2o_dropdown_option o_m2o_dropdown_option_create", + action: async (params) => { + try { + await this.props.quickCreate(request, params); + } catch { + const context = this.getCreationContext(request); + return this.openMany2X({context}); + } + }, + }); + } + + // Search more... + // Resolution order: + // 1- check if "search_more" is set locally in node's options + // 2- if set locally, apply its value + // 3- if not set locally, check if it's set globally via ir.config_parameter + // 4- if set globally, apply its value + // 5- if not set globally either, check if returned values are more than node's limit + var search_more = false; + if (!_.isUndefined(this.props.nodeOptions.search_more)) { + search_more = is_option_set(this.props.nodeOptions.search_more); + } else if (!_.isUndefined(this.ir_options["web_m2x_options.search_more"])) { + search_more = is_option_set(this.ir_options["web_m2x_options.search_more"]); + } else { + search_more = + !this.props.noSearchMore && this.props.searchLimit < records.length; + } + if (search_more) { + options.push({ + label: this.env._t("Search More..."), + action: this.onSearchMore.bind(this, request), + classList: "o_m2o_dropdown_option o_m2o_dropdown_option_search_more", + }); + } + + // Create and Edit + const canCreateEdit = + "createEdit" in this.activeActions + ? this.activeActions.createEdit + : this.activeActions.create; + if ( + !request.length && + !this.props.value && + (this.props.quickCreate || canCreateEdit) + ) { + options.push({ + label: this.env._t("Start typing..."), + classList: "o_m2o_start_typing", + unselectable: true, + }); + } + + // Create and edit ... + var create_edit = + is_option_set(this.props.nodeOptions.create) || + is_option_set(this.props.nodeOptions.create_edit), + create_edit_undef = + _.isUndefined(this.props.nodeOptions.create) && + _.isUndefined(this.props.nodeOptions.create_edit), + m2x_create_edit_undef = _.isUndefined( + this.ir_options["web_m2x_options.create_edit"] + ), + m2x_create_edit = is_option_set( + this.ir_options["web_m2x_options.create_edit"] + ); + var show_create_edit = + (!this.props.nodeOptions && (m2x_create_edit_undef || m2x_create_edit)) || + (this.props.nodeOptions && + (create_edit || + (create_edit_undef && (m2x_create_edit_undef || m2x_create_edit)))); + if ( + create_enabled && + !this.props.nodeOptions.no_create_edit && + show_create_edit && + request.length && + canCreateEdit + ) { + const context = this.getCreationContext(request); + options.push({ + label: this.env._t("Create and edit..."), + classList: "o_m2o_dropdown_option o_m2o_dropdown_option_create_edit", + action: () => this.openMany2X({context}), + }); + } + + // No records + if (!records.length && !this.activeActions.create) { + options.push({ + label: this.env._t("No records"), + classList: "o_m2o_no_result", + unselectable: true, + }); + } + + return options; + }, +}); + +Many2XAutocomplete.defaultProps = { + ...Many2XAutocomplete.defaultProps, + nodeOptions: {}, +}; diff --git a/addons/web_m2x_options/tests/__init__.py b/addons/web_m2x_options/tests/__init__.py new file mode 100644 index 0000000..b472ff3 --- /dev/null +++ b/addons/web_m2x_options/tests/__init__.py @@ -0,0 +1,2 @@ +# Copyright 2020 initOS GmbH. +from . import test_ir_config_parameter diff --git a/addons/web_m2x_options/tests/test_ir_config_parameter.py b/addons/web_m2x_options/tests/test_ir_config_parameter.py new file mode 100644 index 0000000..eae00c7 --- /dev/null +++ b/addons/web_m2x_options/tests/test_ir_config_parameter.py @@ -0,0 +1,28 @@ +# Copyright 2020 initOS GmbH. +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). + +from odoo.tests import common + + +class TestIrConfigParameter(common.TransactionCase): + @classmethod + def setUpClass(cls): + super(TestIrConfigParameter, cls).setUpClass() + cls.env["ir.config_parameter"].set_param("web_m2x_options.limit", 10) + cls.env["ir.config_parameter"].set_param("web_m2x_options.create_edit", "True") + cls.env["ir.config_parameter"].set_param("web_m2x_options.create", "True") + cls.env["ir.config_parameter"].set_param("web_m2x_options.search_more", "False") + cls.env["ir.config_parameter"].set_param("web_m2x_options.m2o_dialog", "True") + + def test_web_m2x_options_key(self): + web_m2x_options = self.env["ir.config_parameter"].get_web_m2x_options() + self.assertIn("web_m2x_options.limit", web_m2x_options) + self.assertNotIn("web_m2x_options.m2o_dialog_test", web_m2x_options) + + def test_web_m2x_options_value(self): + web_m2x_options = self.env["ir.config_parameter"].get_web_m2x_options() + self.assertEqual(web_m2x_options["web_m2x_options.limit"], "10") + self.assertTrue(bool(web_m2x_options["web_m2x_options.create_edit"])) + self.assertTrue(bool(web_m2x_options["web_m2x_options.create"])) + self.assertEqual(web_m2x_options["web_m2x_options.search_more"], "False") + self.assertTrue(bool(web_m2x_options["web_m2x_options.m2o_dialog"])) From bef1f157e2aba7cfcd707e5fe7b666e17cb501af Mon Sep 17 00:00:00 2001 From: belloafeez Date: Fri, 2 Aug 2024 10:12:04 +0100 Subject: [PATCH 13/54] updated Signed-off-by: belloafeez --- {addons => odoo/extra-addons}/openems/.gitignore | 0 {addons => odoo/extra-addons}/openems/__init__.py | 0 .../extra-addons}/openems/__manifest__.py | 0 .../extra-addons}/openems/controllers/__init__.py | 0 .../extra-addons}/openems/controllers/alerting.py | 0 .../extra-addons}/openems/controllers/const.py | 0 .../openems/controllers/openems_backend.py | 0 .../openems/controllers/setup_protocol.py | 0 .../extra-addons}/openems/controllers/user.py | 0 .../extra-addons}/openems/data/OpenEMS-Logo.jpg | Bin {addons => odoo/extra-addons}/openems/data/demo.xml | 0 .../openems/data/ir_config_parameter.xml | 0 .../openems/data/res_partner_category.xml | 0 {addons => odoo/extra-addons}/openems/i18n/de.po | 0 .../extra-addons}/openems/i18n/openems.pot | 0 .../openems/mail/openems/alerting_offline.xml | 0 .../openems/mail/openems/alerting_sum_state.xml | 0 .../mail/openems/setup_protocol_customer.xml | 0 .../mail/openems/setup_protocol_installer.xml | 0 .../openems/mail/openems/user_registration.xml | 0 .../openems/migrations/16.0.1.0.1/post-migrate.py | 0 .../openems/migrations/16.0.1.0.1/pre-migrate.py | 0 .../extra-addons}/openems/models/__init__.py | 0 .../extra-addons}/openems/models/device.py | 0 .../extra-addons}/openems/models/partner.py | 0 .../extra-addons}/openems/models/setup_protocol.py | 0 .../openems/models/stock_production_lot.py | 0 .../extra-addons}/openems/models/user.py | 0 .../extra-addons}/openems/report/setup_protocol.xml | 0 .../openems/security/ir.model.access.csv | 0 .../extra-addons}/openems/security/openems.xml | 0 .../setup/.setuptools-odoo-make-default-ignore | 0 {addons => odoo/extra-addons}/openems/setup/README | 0 .../openems/static/description/icon.png | Bin .../openems/static/mail/OpenEMS-Logo.jpg | Bin .../extra-addons}/openems/views/device.xml | 0 .../extra-addons}/openems/views/partner.xml | 0 .../extra-addons}/openems/views/setup_protocol.xml | 0 .../openems/views/stock_production_lot_views.xml | 0 .../extra-addons}/openems/views/user.xml | 0 .../extra-addons}/partner_firstname/README.rst | 0 .../extra-addons}/partner_firstname/__init__.py | 0 .../extra-addons}/partner_firstname/__manifest__.py | 0 .../extra-addons}/partner_firstname/exceptions.py | 0 .../extra-addons}/partner_firstname/hooks.py | 0 .../extra-addons}/partner_firstname/i18n/am.po | 0 .../extra-addons}/partner_firstname/i18n/ar.po | 0 .../extra-addons}/partner_firstname/i18n/bg.po | 0 .../extra-addons}/partner_firstname/i18n/bs.po | 0 .../extra-addons}/partner_firstname/i18n/ca.po | 0 .../extra-addons}/partner_firstname/i18n/cs.po | 0 .../extra-addons}/partner_firstname/i18n/da.po | 0 .../extra-addons}/partner_firstname/i18n/de.po | 0 .../extra-addons}/partner_firstname/i18n/el_GR.po | 0 .../extra-addons}/partner_firstname/i18n/en_GB.po | 0 .../extra-addons}/partner_firstname/i18n/es.po | 0 .../extra-addons}/partner_firstname/i18n/es_CR.po | 0 .../extra-addons}/partner_firstname/i18n/es_EC.po | 0 .../extra-addons}/partner_firstname/i18n/es_MX.po | 0 .../extra-addons}/partner_firstname/i18n/es_VE.po | 0 .../extra-addons}/partner_firstname/i18n/et.po | 0 .../extra-addons}/partner_firstname/i18n/eu.po | 0 .../extra-addons}/partner_firstname/i18n/fi.po | 0 .../extra-addons}/partner_firstname/i18n/fr.po | 0 .../extra-addons}/partner_firstname/i18n/fr_CA.po | 0 .../extra-addons}/partner_firstname/i18n/fr_CH.po | 0 .../extra-addons}/partner_firstname/i18n/gl.po | 0 .../extra-addons}/partner_firstname/i18n/hr.po | 0 .../extra-addons}/partner_firstname/i18n/hr_HR.po | 0 .../extra-addons}/partner_firstname/i18n/hu.po | 0 .../extra-addons}/partner_firstname/i18n/it.po | 0 .../extra-addons}/partner_firstname/i18n/ja.po | 0 .../extra-addons}/partner_firstname/i18n/lt.po | 0 .../extra-addons}/partner_firstname/i18n/lv.po | 0 .../extra-addons}/partner_firstname/i18n/mk.po | 0 .../extra-addons}/partner_firstname/i18n/mn.po | 0 .../extra-addons}/partner_firstname/i18n/nb.po | 0 .../extra-addons}/partner_firstname/i18n/nb_NO.po | 0 .../extra-addons}/partner_firstname/i18n/nl.po | 0 .../extra-addons}/partner_firstname/i18n/nl_BE.po | 0 .../extra-addons}/partner_firstname/i18n/nl_NL.po | 0 .../partner_firstname/i18n/partner_firstname.pot | 0 .../extra-addons}/partner_firstname/i18n/pl.po | 0 .../extra-addons}/partner_firstname/i18n/pt.po | 0 .../extra-addons}/partner_firstname/i18n/pt_BR.po | 0 .../extra-addons}/partner_firstname/i18n/pt_PT.po | 0 .../extra-addons}/partner_firstname/i18n/ro.po | 0 .../extra-addons}/partner_firstname/i18n/ru.po | 0 .../extra-addons}/partner_firstname/i18n/sk.po | 0 .../extra-addons}/partner_firstname/i18n/sl.po | 0 .../partner_firstname/i18n/sr@latin.po | 0 .../extra-addons}/partner_firstname/i18n/sv.po | 0 .../extra-addons}/partner_firstname/i18n/th.po | 0 .../extra-addons}/partner_firstname/i18n/tr.po | 0 .../extra-addons}/partner_firstname/i18n/tr_TR.po | 0 .../extra-addons}/partner_firstname/i18n/vi.po | 0 .../extra-addons}/partner_firstname/i18n/zh_CN.po | 0 .../extra-addons}/partner_firstname/i18n/zh_TW.po | 0 .../partner_firstname/models/__init__.py | 0 .../models/base_config_settings.py | 0 .../partner_firstname/models/res_partner.py | 0 .../partner_firstname/models/res_users.py | 0 .../partner_firstname/readme/CONFIGURE.rst | 0 .../partner_firstname/readme/CONTRIBUTORS.rst | 0 .../partner_firstname/readme/DESCRIPTION.rst | 0 .../partner_firstname/readme/ROADMAP.rst | 0 .../partner_firstname/readme/USAGE.rst | 0 .../partner_firstname/static/description/icon.png | Bin .../partner_firstname/static/description/index.html | 0 .../partner_firstname/tests/__init__.py | 0 .../extra-addons}/partner_firstname/tests/base.py | 0 .../partner_firstname/tests/test_config_settings.py | 0 .../partner_firstname/tests/test_copy.py | 0 .../partner_firstname/tests/test_create.py | 0 .../partner_firstname/tests/test_defaults.py | 0 .../partner_firstname/tests/test_delete.py | 0 .../partner_firstname/tests/test_empty.py | 0 .../partner_firstname/tests/test_name.py | 0 .../partner_firstname/tests/test_order.py | 0 .../partner_firstname/tests/test_partner_form.py | 0 .../partner_firstname/tests/test_user_form.py | 0 .../partner_firstname/views/base_config_view.xml | 0 .../partner_firstname/views/res_partner.xml | 0 .../partner_firstname/views/res_user.xml | 0 {addons => odoo/extra-addons}/readme.md | 0 .../extra-addons}/web_m2x_options/README.rst | 0 .../extra-addons}/web_m2x_options/__init__.py | 0 .../extra-addons}/web_m2x_options/__manifest__.py | 0 .../extra-addons}/web_m2x_options/i18n/ar.po | 0 .../extra-addons}/web_m2x_options/i18n/de.po | 0 .../extra-addons}/web_m2x_options/i18n/es.po | 0 .../extra-addons}/web_m2x_options/i18n/es_BO.po | 0 .../extra-addons}/web_m2x_options/i18n/fi.po | 0 .../extra-addons}/web_m2x_options/i18n/fr.po | 0 .../extra-addons}/web_m2x_options/i18n/hr.po | 0 .../extra-addons}/web_m2x_options/i18n/it.po | 0 .../extra-addons}/web_m2x_options/i18n/nl.po | 0 .../extra-addons}/web_m2x_options/i18n/nl_NL.po | 0 .../extra-addons}/web_m2x_options/i18n/pt_BR.po | 0 .../extra-addons}/web_m2x_options/i18n/sl.po | 0 .../extra-addons}/web_m2x_options/i18n/tr.po | 0 .../web_m2x_options/i18n/web_m2x_options.pot | 0 .../extra-addons}/web_m2x_options/i18n/zh_CN.po | 0 .../web_m2x_options/models/__init__.py | 0 .../web_m2x_options/models/ir_config_parameter.py | 0 .../extra-addons}/web_m2x_options/models/ir_http.py | 0 .../web_m2x_options/readme/CONTRIBUTORS.rst | 0 .../web_m2x_options/readme/CREDITS.rst | 0 .../web_m2x_options/readme/DESCRIPTION.rst | 0 .../web_m2x_options/readme/ROADMAP.rst | 0 .../extra-addons}/web_m2x_options/readme/USAGE.rst | 0 .../web_m2x_options/static/description/icon.png | Bin .../web_m2x_options/static/description/index.html | 0 .../web_m2x_options/static/src/components/base.xml | 0 .../static/src/components/form.esm.js | 0 .../static/src/components/relational_utils.esm.js | 0 .../extra-addons}/web_m2x_options/tests/__init__.py | 0 .../tests/test_ir_config_parameter.py | 0 158 files changed, 0 insertions(+), 0 deletions(-) rename {addons => odoo/extra-addons}/openems/.gitignore (100%) rename {addons => odoo/extra-addons}/openems/__init__.py (100%) rename {addons => odoo/extra-addons}/openems/__manifest__.py (100%) rename {addons => odoo/extra-addons}/openems/controllers/__init__.py (100%) rename {addons => odoo/extra-addons}/openems/controllers/alerting.py (100%) rename {addons => odoo/extra-addons}/openems/controllers/const.py (100%) rename {addons => odoo/extra-addons}/openems/controllers/openems_backend.py (100%) rename {addons => odoo/extra-addons}/openems/controllers/setup_protocol.py (100%) rename {addons => odoo/extra-addons}/openems/controllers/user.py (100%) rename {addons => odoo/extra-addons}/openems/data/OpenEMS-Logo.jpg (100%) rename {addons => odoo/extra-addons}/openems/data/demo.xml (100%) rename {addons => odoo/extra-addons}/openems/data/ir_config_parameter.xml (100%) rename {addons => odoo/extra-addons}/openems/data/res_partner_category.xml (100%) rename {addons => odoo/extra-addons}/openems/i18n/de.po (100%) rename {addons => odoo/extra-addons}/openems/i18n/openems.pot (100%) rename {addons => odoo/extra-addons}/openems/mail/openems/alerting_offline.xml (100%) rename {addons => odoo/extra-addons}/openems/mail/openems/alerting_sum_state.xml (100%) rename {addons => odoo/extra-addons}/openems/mail/openems/setup_protocol_customer.xml (100%) rename {addons => odoo/extra-addons}/openems/mail/openems/setup_protocol_installer.xml (100%) rename {addons => odoo/extra-addons}/openems/mail/openems/user_registration.xml (100%) rename {addons => odoo/extra-addons}/openems/migrations/16.0.1.0.1/post-migrate.py (100%) rename {addons => odoo/extra-addons}/openems/migrations/16.0.1.0.1/pre-migrate.py (100%) rename {addons => odoo/extra-addons}/openems/models/__init__.py (100%) rename {addons => odoo/extra-addons}/openems/models/device.py (100%) rename {addons => odoo/extra-addons}/openems/models/partner.py (100%) rename {addons => odoo/extra-addons}/openems/models/setup_protocol.py (100%) rename {addons => odoo/extra-addons}/openems/models/stock_production_lot.py (100%) rename {addons => odoo/extra-addons}/openems/models/user.py (100%) rename {addons => odoo/extra-addons}/openems/report/setup_protocol.xml (100%) rename {addons => odoo/extra-addons}/openems/security/ir.model.access.csv (100%) rename {addons => odoo/extra-addons}/openems/security/openems.xml (100%) rename {addons => odoo/extra-addons}/openems/setup/.setuptools-odoo-make-default-ignore (100%) rename {addons => odoo/extra-addons}/openems/setup/README (100%) rename {addons => odoo/extra-addons}/openems/static/description/icon.png (100%) rename {addons => odoo/extra-addons}/openems/static/mail/OpenEMS-Logo.jpg (100%) rename {addons => odoo/extra-addons}/openems/views/device.xml (100%) rename {addons => odoo/extra-addons}/openems/views/partner.xml (100%) rename {addons => odoo/extra-addons}/openems/views/setup_protocol.xml (100%) rename {addons => odoo/extra-addons}/openems/views/stock_production_lot_views.xml (100%) rename {addons => odoo/extra-addons}/openems/views/user.xml (100%) rename {addons => odoo/extra-addons}/partner_firstname/README.rst (100%) rename {addons => odoo/extra-addons}/partner_firstname/__init__.py (100%) rename {addons => odoo/extra-addons}/partner_firstname/__manifest__.py (100%) rename {addons => odoo/extra-addons}/partner_firstname/exceptions.py (100%) rename {addons => odoo/extra-addons}/partner_firstname/hooks.py (100%) rename {addons => odoo/extra-addons}/partner_firstname/i18n/am.po (100%) rename {addons => odoo/extra-addons}/partner_firstname/i18n/ar.po (100%) rename {addons => odoo/extra-addons}/partner_firstname/i18n/bg.po (100%) rename {addons => odoo/extra-addons}/partner_firstname/i18n/bs.po (100%) rename {addons => odoo/extra-addons}/partner_firstname/i18n/ca.po (100%) rename {addons => odoo/extra-addons}/partner_firstname/i18n/cs.po (100%) rename {addons => odoo/extra-addons}/partner_firstname/i18n/da.po (100%) rename {addons => odoo/extra-addons}/partner_firstname/i18n/de.po (100%) rename {addons => odoo/extra-addons}/partner_firstname/i18n/el_GR.po (100%) rename {addons => odoo/extra-addons}/partner_firstname/i18n/en_GB.po (100%) rename {addons => odoo/extra-addons}/partner_firstname/i18n/es.po (100%) rename {addons => odoo/extra-addons}/partner_firstname/i18n/es_CR.po (100%) rename {addons => odoo/extra-addons}/partner_firstname/i18n/es_EC.po (100%) rename {addons => odoo/extra-addons}/partner_firstname/i18n/es_MX.po (100%) rename {addons => odoo/extra-addons}/partner_firstname/i18n/es_VE.po (100%) rename {addons => odoo/extra-addons}/partner_firstname/i18n/et.po (100%) rename {addons => odoo/extra-addons}/partner_firstname/i18n/eu.po (100%) rename {addons => odoo/extra-addons}/partner_firstname/i18n/fi.po (100%) rename {addons => odoo/extra-addons}/partner_firstname/i18n/fr.po (100%) rename {addons => odoo/extra-addons}/partner_firstname/i18n/fr_CA.po (100%) rename {addons => odoo/extra-addons}/partner_firstname/i18n/fr_CH.po (100%) rename {addons => odoo/extra-addons}/partner_firstname/i18n/gl.po (100%) rename {addons => odoo/extra-addons}/partner_firstname/i18n/hr.po (100%) rename {addons => odoo/extra-addons}/partner_firstname/i18n/hr_HR.po (100%) rename {addons => odoo/extra-addons}/partner_firstname/i18n/hu.po (100%) rename {addons => odoo/extra-addons}/partner_firstname/i18n/it.po (100%) rename {addons => odoo/extra-addons}/partner_firstname/i18n/ja.po (100%) rename {addons => odoo/extra-addons}/partner_firstname/i18n/lt.po (100%) rename {addons => odoo/extra-addons}/partner_firstname/i18n/lv.po (100%) rename {addons => odoo/extra-addons}/partner_firstname/i18n/mk.po (100%) rename {addons => odoo/extra-addons}/partner_firstname/i18n/mn.po (100%) rename {addons => odoo/extra-addons}/partner_firstname/i18n/nb.po (100%) rename {addons => odoo/extra-addons}/partner_firstname/i18n/nb_NO.po (100%) rename {addons => odoo/extra-addons}/partner_firstname/i18n/nl.po (100%) rename {addons => odoo/extra-addons}/partner_firstname/i18n/nl_BE.po (100%) rename {addons => odoo/extra-addons}/partner_firstname/i18n/nl_NL.po (100%) rename {addons => odoo/extra-addons}/partner_firstname/i18n/partner_firstname.pot (100%) rename {addons => odoo/extra-addons}/partner_firstname/i18n/pl.po (100%) rename {addons => odoo/extra-addons}/partner_firstname/i18n/pt.po (100%) rename {addons => odoo/extra-addons}/partner_firstname/i18n/pt_BR.po (100%) rename {addons => odoo/extra-addons}/partner_firstname/i18n/pt_PT.po (100%) rename {addons => odoo/extra-addons}/partner_firstname/i18n/ro.po (100%) rename {addons => odoo/extra-addons}/partner_firstname/i18n/ru.po (100%) rename {addons => odoo/extra-addons}/partner_firstname/i18n/sk.po (100%) rename {addons => odoo/extra-addons}/partner_firstname/i18n/sl.po (100%) rename {addons => odoo/extra-addons}/partner_firstname/i18n/sr@latin.po (100%) rename {addons => odoo/extra-addons}/partner_firstname/i18n/sv.po (100%) rename {addons => odoo/extra-addons}/partner_firstname/i18n/th.po (100%) rename {addons => odoo/extra-addons}/partner_firstname/i18n/tr.po (100%) rename {addons => odoo/extra-addons}/partner_firstname/i18n/tr_TR.po (100%) rename {addons => odoo/extra-addons}/partner_firstname/i18n/vi.po (100%) rename {addons => odoo/extra-addons}/partner_firstname/i18n/zh_CN.po (100%) rename {addons => odoo/extra-addons}/partner_firstname/i18n/zh_TW.po (100%) rename {addons => odoo/extra-addons}/partner_firstname/models/__init__.py (100%) rename {addons => odoo/extra-addons}/partner_firstname/models/base_config_settings.py (100%) rename {addons => odoo/extra-addons}/partner_firstname/models/res_partner.py (100%) rename {addons => odoo/extra-addons}/partner_firstname/models/res_users.py (100%) rename {addons => odoo/extra-addons}/partner_firstname/readme/CONFIGURE.rst (100%) rename {addons => odoo/extra-addons}/partner_firstname/readme/CONTRIBUTORS.rst (100%) rename {addons => odoo/extra-addons}/partner_firstname/readme/DESCRIPTION.rst (100%) rename {addons => odoo/extra-addons}/partner_firstname/readme/ROADMAP.rst (100%) rename {addons => odoo/extra-addons}/partner_firstname/readme/USAGE.rst (100%) rename {addons => odoo/extra-addons}/partner_firstname/static/description/icon.png (100%) rename {addons => odoo/extra-addons}/partner_firstname/static/description/index.html (100%) rename {addons => odoo/extra-addons}/partner_firstname/tests/__init__.py (100%) rename {addons => odoo/extra-addons}/partner_firstname/tests/base.py (100%) rename {addons => odoo/extra-addons}/partner_firstname/tests/test_config_settings.py (100%) rename {addons => odoo/extra-addons}/partner_firstname/tests/test_copy.py (100%) rename {addons => odoo/extra-addons}/partner_firstname/tests/test_create.py (100%) rename {addons => odoo/extra-addons}/partner_firstname/tests/test_defaults.py (100%) rename {addons => odoo/extra-addons}/partner_firstname/tests/test_delete.py (100%) rename {addons => odoo/extra-addons}/partner_firstname/tests/test_empty.py (100%) rename {addons => odoo/extra-addons}/partner_firstname/tests/test_name.py (100%) rename {addons => odoo/extra-addons}/partner_firstname/tests/test_order.py (100%) rename {addons => odoo/extra-addons}/partner_firstname/tests/test_partner_form.py (100%) rename {addons => odoo/extra-addons}/partner_firstname/tests/test_user_form.py (100%) rename {addons => odoo/extra-addons}/partner_firstname/views/base_config_view.xml (100%) rename {addons => odoo/extra-addons}/partner_firstname/views/res_partner.xml (100%) rename {addons => odoo/extra-addons}/partner_firstname/views/res_user.xml (100%) rename {addons => odoo/extra-addons}/readme.md (100%) rename {addons => odoo/extra-addons}/web_m2x_options/README.rst (100%) rename {addons => odoo/extra-addons}/web_m2x_options/__init__.py (100%) rename {addons => odoo/extra-addons}/web_m2x_options/__manifest__.py (100%) rename {addons => odoo/extra-addons}/web_m2x_options/i18n/ar.po (100%) rename {addons => odoo/extra-addons}/web_m2x_options/i18n/de.po (100%) rename {addons => odoo/extra-addons}/web_m2x_options/i18n/es.po (100%) rename {addons => odoo/extra-addons}/web_m2x_options/i18n/es_BO.po (100%) rename {addons => odoo/extra-addons}/web_m2x_options/i18n/fi.po (100%) rename {addons => odoo/extra-addons}/web_m2x_options/i18n/fr.po (100%) rename {addons => odoo/extra-addons}/web_m2x_options/i18n/hr.po (100%) rename {addons => odoo/extra-addons}/web_m2x_options/i18n/it.po (100%) rename {addons => odoo/extra-addons}/web_m2x_options/i18n/nl.po (100%) rename {addons => odoo/extra-addons}/web_m2x_options/i18n/nl_NL.po (100%) rename {addons => odoo/extra-addons}/web_m2x_options/i18n/pt_BR.po (100%) rename {addons => odoo/extra-addons}/web_m2x_options/i18n/sl.po (100%) rename {addons => odoo/extra-addons}/web_m2x_options/i18n/tr.po (100%) rename {addons => odoo/extra-addons}/web_m2x_options/i18n/web_m2x_options.pot (100%) rename {addons => odoo/extra-addons}/web_m2x_options/i18n/zh_CN.po (100%) rename {addons => odoo/extra-addons}/web_m2x_options/models/__init__.py (100%) rename {addons => odoo/extra-addons}/web_m2x_options/models/ir_config_parameter.py (100%) rename {addons => odoo/extra-addons}/web_m2x_options/models/ir_http.py (100%) rename {addons => odoo/extra-addons}/web_m2x_options/readme/CONTRIBUTORS.rst (100%) rename {addons => odoo/extra-addons}/web_m2x_options/readme/CREDITS.rst (100%) rename {addons => odoo/extra-addons}/web_m2x_options/readme/DESCRIPTION.rst (100%) rename {addons => odoo/extra-addons}/web_m2x_options/readme/ROADMAP.rst (100%) rename {addons => odoo/extra-addons}/web_m2x_options/readme/USAGE.rst (100%) rename {addons => odoo/extra-addons}/web_m2x_options/static/description/icon.png (100%) rename {addons => odoo/extra-addons}/web_m2x_options/static/description/index.html (100%) rename {addons => odoo/extra-addons}/web_m2x_options/static/src/components/base.xml (100%) rename {addons => odoo/extra-addons}/web_m2x_options/static/src/components/form.esm.js (100%) rename {addons => odoo/extra-addons}/web_m2x_options/static/src/components/relational_utils.esm.js (100%) rename {addons => odoo/extra-addons}/web_m2x_options/tests/__init__.py (100%) rename {addons => odoo/extra-addons}/web_m2x_options/tests/test_ir_config_parameter.py (100%) diff --git a/addons/openems/.gitignore b/odoo/extra-addons/openems/.gitignore similarity index 100% rename from addons/openems/.gitignore rename to odoo/extra-addons/openems/.gitignore diff --git a/addons/openems/__init__.py b/odoo/extra-addons/openems/__init__.py similarity index 100% rename from addons/openems/__init__.py rename to odoo/extra-addons/openems/__init__.py diff --git a/addons/openems/__manifest__.py b/odoo/extra-addons/openems/__manifest__.py similarity index 100% rename from addons/openems/__manifest__.py rename to odoo/extra-addons/openems/__manifest__.py diff --git a/addons/openems/controllers/__init__.py b/odoo/extra-addons/openems/controllers/__init__.py similarity index 100% rename from addons/openems/controllers/__init__.py rename to odoo/extra-addons/openems/controllers/__init__.py diff --git a/addons/openems/controllers/alerting.py b/odoo/extra-addons/openems/controllers/alerting.py similarity index 100% rename from addons/openems/controllers/alerting.py rename to odoo/extra-addons/openems/controllers/alerting.py diff --git a/addons/openems/controllers/const.py b/odoo/extra-addons/openems/controllers/const.py similarity index 100% rename from addons/openems/controllers/const.py rename to odoo/extra-addons/openems/controllers/const.py diff --git a/addons/openems/controllers/openems_backend.py b/odoo/extra-addons/openems/controllers/openems_backend.py similarity index 100% rename from addons/openems/controllers/openems_backend.py rename to odoo/extra-addons/openems/controllers/openems_backend.py diff --git a/addons/openems/controllers/setup_protocol.py b/odoo/extra-addons/openems/controllers/setup_protocol.py similarity index 100% rename from addons/openems/controllers/setup_protocol.py rename to odoo/extra-addons/openems/controllers/setup_protocol.py diff --git a/addons/openems/controllers/user.py b/odoo/extra-addons/openems/controllers/user.py similarity index 100% rename from addons/openems/controllers/user.py rename to odoo/extra-addons/openems/controllers/user.py diff --git a/addons/openems/data/OpenEMS-Logo.jpg b/odoo/extra-addons/openems/data/OpenEMS-Logo.jpg similarity index 100% rename from addons/openems/data/OpenEMS-Logo.jpg rename to odoo/extra-addons/openems/data/OpenEMS-Logo.jpg diff --git a/addons/openems/data/demo.xml b/odoo/extra-addons/openems/data/demo.xml similarity index 100% rename from addons/openems/data/demo.xml rename to odoo/extra-addons/openems/data/demo.xml diff --git a/addons/openems/data/ir_config_parameter.xml b/odoo/extra-addons/openems/data/ir_config_parameter.xml similarity index 100% rename from addons/openems/data/ir_config_parameter.xml rename to odoo/extra-addons/openems/data/ir_config_parameter.xml diff --git a/addons/openems/data/res_partner_category.xml b/odoo/extra-addons/openems/data/res_partner_category.xml similarity index 100% rename from addons/openems/data/res_partner_category.xml rename to odoo/extra-addons/openems/data/res_partner_category.xml diff --git a/addons/openems/i18n/de.po b/odoo/extra-addons/openems/i18n/de.po similarity index 100% rename from addons/openems/i18n/de.po rename to odoo/extra-addons/openems/i18n/de.po diff --git a/addons/openems/i18n/openems.pot b/odoo/extra-addons/openems/i18n/openems.pot similarity index 100% rename from addons/openems/i18n/openems.pot rename to odoo/extra-addons/openems/i18n/openems.pot diff --git a/addons/openems/mail/openems/alerting_offline.xml b/odoo/extra-addons/openems/mail/openems/alerting_offline.xml similarity index 100% rename from addons/openems/mail/openems/alerting_offline.xml rename to odoo/extra-addons/openems/mail/openems/alerting_offline.xml diff --git a/addons/openems/mail/openems/alerting_sum_state.xml b/odoo/extra-addons/openems/mail/openems/alerting_sum_state.xml similarity index 100% rename from addons/openems/mail/openems/alerting_sum_state.xml rename to odoo/extra-addons/openems/mail/openems/alerting_sum_state.xml diff --git a/addons/openems/mail/openems/setup_protocol_customer.xml b/odoo/extra-addons/openems/mail/openems/setup_protocol_customer.xml similarity index 100% rename from addons/openems/mail/openems/setup_protocol_customer.xml rename to odoo/extra-addons/openems/mail/openems/setup_protocol_customer.xml diff --git a/addons/openems/mail/openems/setup_protocol_installer.xml b/odoo/extra-addons/openems/mail/openems/setup_protocol_installer.xml similarity index 100% rename from addons/openems/mail/openems/setup_protocol_installer.xml rename to odoo/extra-addons/openems/mail/openems/setup_protocol_installer.xml diff --git a/addons/openems/mail/openems/user_registration.xml b/odoo/extra-addons/openems/mail/openems/user_registration.xml similarity index 100% rename from addons/openems/mail/openems/user_registration.xml rename to odoo/extra-addons/openems/mail/openems/user_registration.xml diff --git a/addons/openems/migrations/16.0.1.0.1/post-migrate.py b/odoo/extra-addons/openems/migrations/16.0.1.0.1/post-migrate.py similarity index 100% rename from addons/openems/migrations/16.0.1.0.1/post-migrate.py rename to odoo/extra-addons/openems/migrations/16.0.1.0.1/post-migrate.py diff --git a/addons/openems/migrations/16.0.1.0.1/pre-migrate.py b/odoo/extra-addons/openems/migrations/16.0.1.0.1/pre-migrate.py similarity index 100% rename from addons/openems/migrations/16.0.1.0.1/pre-migrate.py rename to odoo/extra-addons/openems/migrations/16.0.1.0.1/pre-migrate.py diff --git a/addons/openems/models/__init__.py b/odoo/extra-addons/openems/models/__init__.py similarity index 100% rename from addons/openems/models/__init__.py rename to odoo/extra-addons/openems/models/__init__.py diff --git a/addons/openems/models/device.py b/odoo/extra-addons/openems/models/device.py similarity index 100% rename from addons/openems/models/device.py rename to odoo/extra-addons/openems/models/device.py diff --git a/addons/openems/models/partner.py b/odoo/extra-addons/openems/models/partner.py similarity index 100% rename from addons/openems/models/partner.py rename to odoo/extra-addons/openems/models/partner.py diff --git a/addons/openems/models/setup_protocol.py b/odoo/extra-addons/openems/models/setup_protocol.py similarity index 100% rename from addons/openems/models/setup_protocol.py rename to odoo/extra-addons/openems/models/setup_protocol.py diff --git a/addons/openems/models/stock_production_lot.py b/odoo/extra-addons/openems/models/stock_production_lot.py similarity index 100% rename from addons/openems/models/stock_production_lot.py rename to odoo/extra-addons/openems/models/stock_production_lot.py diff --git a/addons/openems/models/user.py b/odoo/extra-addons/openems/models/user.py similarity index 100% rename from addons/openems/models/user.py rename to odoo/extra-addons/openems/models/user.py diff --git a/addons/openems/report/setup_protocol.xml b/odoo/extra-addons/openems/report/setup_protocol.xml similarity index 100% rename from addons/openems/report/setup_protocol.xml rename to odoo/extra-addons/openems/report/setup_protocol.xml diff --git a/addons/openems/security/ir.model.access.csv b/odoo/extra-addons/openems/security/ir.model.access.csv similarity index 100% rename from addons/openems/security/ir.model.access.csv rename to odoo/extra-addons/openems/security/ir.model.access.csv diff --git a/addons/openems/security/openems.xml b/odoo/extra-addons/openems/security/openems.xml similarity index 100% rename from addons/openems/security/openems.xml rename to odoo/extra-addons/openems/security/openems.xml diff --git a/addons/openems/setup/.setuptools-odoo-make-default-ignore b/odoo/extra-addons/openems/setup/.setuptools-odoo-make-default-ignore similarity index 100% rename from addons/openems/setup/.setuptools-odoo-make-default-ignore rename to odoo/extra-addons/openems/setup/.setuptools-odoo-make-default-ignore diff --git a/addons/openems/setup/README b/odoo/extra-addons/openems/setup/README similarity index 100% rename from addons/openems/setup/README rename to odoo/extra-addons/openems/setup/README diff --git a/addons/openems/static/description/icon.png b/odoo/extra-addons/openems/static/description/icon.png similarity index 100% rename from addons/openems/static/description/icon.png rename to odoo/extra-addons/openems/static/description/icon.png diff --git a/addons/openems/static/mail/OpenEMS-Logo.jpg b/odoo/extra-addons/openems/static/mail/OpenEMS-Logo.jpg similarity index 100% rename from addons/openems/static/mail/OpenEMS-Logo.jpg rename to odoo/extra-addons/openems/static/mail/OpenEMS-Logo.jpg diff --git a/addons/openems/views/device.xml b/odoo/extra-addons/openems/views/device.xml similarity index 100% rename from addons/openems/views/device.xml rename to odoo/extra-addons/openems/views/device.xml diff --git a/addons/openems/views/partner.xml b/odoo/extra-addons/openems/views/partner.xml similarity index 100% rename from addons/openems/views/partner.xml rename to odoo/extra-addons/openems/views/partner.xml diff --git a/addons/openems/views/setup_protocol.xml b/odoo/extra-addons/openems/views/setup_protocol.xml similarity index 100% rename from addons/openems/views/setup_protocol.xml rename to odoo/extra-addons/openems/views/setup_protocol.xml diff --git a/addons/openems/views/stock_production_lot_views.xml b/odoo/extra-addons/openems/views/stock_production_lot_views.xml similarity index 100% rename from addons/openems/views/stock_production_lot_views.xml rename to odoo/extra-addons/openems/views/stock_production_lot_views.xml diff --git a/addons/openems/views/user.xml b/odoo/extra-addons/openems/views/user.xml similarity index 100% rename from addons/openems/views/user.xml rename to odoo/extra-addons/openems/views/user.xml diff --git a/addons/partner_firstname/README.rst b/odoo/extra-addons/partner_firstname/README.rst similarity index 100% rename from addons/partner_firstname/README.rst rename to odoo/extra-addons/partner_firstname/README.rst diff --git a/addons/partner_firstname/__init__.py b/odoo/extra-addons/partner_firstname/__init__.py similarity index 100% rename from addons/partner_firstname/__init__.py rename to odoo/extra-addons/partner_firstname/__init__.py diff --git a/addons/partner_firstname/__manifest__.py b/odoo/extra-addons/partner_firstname/__manifest__.py similarity index 100% rename from addons/partner_firstname/__manifest__.py rename to odoo/extra-addons/partner_firstname/__manifest__.py diff --git a/addons/partner_firstname/exceptions.py b/odoo/extra-addons/partner_firstname/exceptions.py similarity index 100% rename from addons/partner_firstname/exceptions.py rename to odoo/extra-addons/partner_firstname/exceptions.py diff --git a/addons/partner_firstname/hooks.py b/odoo/extra-addons/partner_firstname/hooks.py similarity index 100% rename from addons/partner_firstname/hooks.py rename to odoo/extra-addons/partner_firstname/hooks.py diff --git a/addons/partner_firstname/i18n/am.po b/odoo/extra-addons/partner_firstname/i18n/am.po similarity index 100% rename from addons/partner_firstname/i18n/am.po rename to odoo/extra-addons/partner_firstname/i18n/am.po diff --git a/addons/partner_firstname/i18n/ar.po b/odoo/extra-addons/partner_firstname/i18n/ar.po similarity index 100% rename from addons/partner_firstname/i18n/ar.po rename to odoo/extra-addons/partner_firstname/i18n/ar.po diff --git a/addons/partner_firstname/i18n/bg.po b/odoo/extra-addons/partner_firstname/i18n/bg.po similarity index 100% rename from addons/partner_firstname/i18n/bg.po rename to odoo/extra-addons/partner_firstname/i18n/bg.po diff --git a/addons/partner_firstname/i18n/bs.po b/odoo/extra-addons/partner_firstname/i18n/bs.po similarity index 100% rename from addons/partner_firstname/i18n/bs.po rename to odoo/extra-addons/partner_firstname/i18n/bs.po diff --git a/addons/partner_firstname/i18n/ca.po b/odoo/extra-addons/partner_firstname/i18n/ca.po similarity index 100% rename from addons/partner_firstname/i18n/ca.po rename to odoo/extra-addons/partner_firstname/i18n/ca.po diff --git a/addons/partner_firstname/i18n/cs.po b/odoo/extra-addons/partner_firstname/i18n/cs.po similarity index 100% rename from addons/partner_firstname/i18n/cs.po rename to odoo/extra-addons/partner_firstname/i18n/cs.po diff --git a/addons/partner_firstname/i18n/da.po b/odoo/extra-addons/partner_firstname/i18n/da.po similarity index 100% rename from addons/partner_firstname/i18n/da.po rename to odoo/extra-addons/partner_firstname/i18n/da.po diff --git a/addons/partner_firstname/i18n/de.po b/odoo/extra-addons/partner_firstname/i18n/de.po similarity index 100% rename from addons/partner_firstname/i18n/de.po rename to odoo/extra-addons/partner_firstname/i18n/de.po diff --git a/addons/partner_firstname/i18n/el_GR.po b/odoo/extra-addons/partner_firstname/i18n/el_GR.po similarity index 100% rename from addons/partner_firstname/i18n/el_GR.po rename to odoo/extra-addons/partner_firstname/i18n/el_GR.po diff --git a/addons/partner_firstname/i18n/en_GB.po b/odoo/extra-addons/partner_firstname/i18n/en_GB.po similarity index 100% rename from addons/partner_firstname/i18n/en_GB.po rename to odoo/extra-addons/partner_firstname/i18n/en_GB.po diff --git a/addons/partner_firstname/i18n/es.po b/odoo/extra-addons/partner_firstname/i18n/es.po similarity index 100% rename from addons/partner_firstname/i18n/es.po rename to odoo/extra-addons/partner_firstname/i18n/es.po diff --git a/addons/partner_firstname/i18n/es_CR.po b/odoo/extra-addons/partner_firstname/i18n/es_CR.po similarity index 100% rename from addons/partner_firstname/i18n/es_CR.po rename to odoo/extra-addons/partner_firstname/i18n/es_CR.po diff --git a/addons/partner_firstname/i18n/es_EC.po b/odoo/extra-addons/partner_firstname/i18n/es_EC.po similarity index 100% rename from addons/partner_firstname/i18n/es_EC.po rename to odoo/extra-addons/partner_firstname/i18n/es_EC.po diff --git a/addons/partner_firstname/i18n/es_MX.po b/odoo/extra-addons/partner_firstname/i18n/es_MX.po similarity index 100% rename from addons/partner_firstname/i18n/es_MX.po rename to odoo/extra-addons/partner_firstname/i18n/es_MX.po diff --git a/addons/partner_firstname/i18n/es_VE.po b/odoo/extra-addons/partner_firstname/i18n/es_VE.po similarity index 100% rename from addons/partner_firstname/i18n/es_VE.po rename to odoo/extra-addons/partner_firstname/i18n/es_VE.po diff --git a/addons/partner_firstname/i18n/et.po b/odoo/extra-addons/partner_firstname/i18n/et.po similarity index 100% rename from addons/partner_firstname/i18n/et.po rename to odoo/extra-addons/partner_firstname/i18n/et.po diff --git a/addons/partner_firstname/i18n/eu.po b/odoo/extra-addons/partner_firstname/i18n/eu.po similarity index 100% rename from addons/partner_firstname/i18n/eu.po rename to odoo/extra-addons/partner_firstname/i18n/eu.po diff --git a/addons/partner_firstname/i18n/fi.po b/odoo/extra-addons/partner_firstname/i18n/fi.po similarity index 100% rename from addons/partner_firstname/i18n/fi.po rename to odoo/extra-addons/partner_firstname/i18n/fi.po diff --git a/addons/partner_firstname/i18n/fr.po b/odoo/extra-addons/partner_firstname/i18n/fr.po similarity index 100% rename from addons/partner_firstname/i18n/fr.po rename to odoo/extra-addons/partner_firstname/i18n/fr.po diff --git a/addons/partner_firstname/i18n/fr_CA.po b/odoo/extra-addons/partner_firstname/i18n/fr_CA.po similarity index 100% rename from addons/partner_firstname/i18n/fr_CA.po rename to odoo/extra-addons/partner_firstname/i18n/fr_CA.po diff --git a/addons/partner_firstname/i18n/fr_CH.po b/odoo/extra-addons/partner_firstname/i18n/fr_CH.po similarity index 100% rename from addons/partner_firstname/i18n/fr_CH.po rename to odoo/extra-addons/partner_firstname/i18n/fr_CH.po diff --git a/addons/partner_firstname/i18n/gl.po b/odoo/extra-addons/partner_firstname/i18n/gl.po similarity index 100% rename from addons/partner_firstname/i18n/gl.po rename to odoo/extra-addons/partner_firstname/i18n/gl.po diff --git a/addons/partner_firstname/i18n/hr.po b/odoo/extra-addons/partner_firstname/i18n/hr.po similarity index 100% rename from addons/partner_firstname/i18n/hr.po rename to odoo/extra-addons/partner_firstname/i18n/hr.po diff --git a/addons/partner_firstname/i18n/hr_HR.po b/odoo/extra-addons/partner_firstname/i18n/hr_HR.po similarity index 100% rename from addons/partner_firstname/i18n/hr_HR.po rename to odoo/extra-addons/partner_firstname/i18n/hr_HR.po diff --git a/addons/partner_firstname/i18n/hu.po b/odoo/extra-addons/partner_firstname/i18n/hu.po similarity index 100% rename from addons/partner_firstname/i18n/hu.po rename to odoo/extra-addons/partner_firstname/i18n/hu.po diff --git a/addons/partner_firstname/i18n/it.po b/odoo/extra-addons/partner_firstname/i18n/it.po similarity index 100% rename from addons/partner_firstname/i18n/it.po rename to odoo/extra-addons/partner_firstname/i18n/it.po diff --git a/addons/partner_firstname/i18n/ja.po b/odoo/extra-addons/partner_firstname/i18n/ja.po similarity index 100% rename from addons/partner_firstname/i18n/ja.po rename to odoo/extra-addons/partner_firstname/i18n/ja.po diff --git a/addons/partner_firstname/i18n/lt.po b/odoo/extra-addons/partner_firstname/i18n/lt.po similarity index 100% rename from addons/partner_firstname/i18n/lt.po rename to odoo/extra-addons/partner_firstname/i18n/lt.po diff --git a/addons/partner_firstname/i18n/lv.po b/odoo/extra-addons/partner_firstname/i18n/lv.po similarity index 100% rename from addons/partner_firstname/i18n/lv.po rename to odoo/extra-addons/partner_firstname/i18n/lv.po diff --git a/addons/partner_firstname/i18n/mk.po b/odoo/extra-addons/partner_firstname/i18n/mk.po similarity index 100% rename from addons/partner_firstname/i18n/mk.po rename to odoo/extra-addons/partner_firstname/i18n/mk.po diff --git a/addons/partner_firstname/i18n/mn.po b/odoo/extra-addons/partner_firstname/i18n/mn.po similarity index 100% rename from addons/partner_firstname/i18n/mn.po rename to odoo/extra-addons/partner_firstname/i18n/mn.po diff --git a/addons/partner_firstname/i18n/nb.po b/odoo/extra-addons/partner_firstname/i18n/nb.po similarity index 100% rename from addons/partner_firstname/i18n/nb.po rename to odoo/extra-addons/partner_firstname/i18n/nb.po diff --git a/addons/partner_firstname/i18n/nb_NO.po b/odoo/extra-addons/partner_firstname/i18n/nb_NO.po similarity index 100% rename from addons/partner_firstname/i18n/nb_NO.po rename to odoo/extra-addons/partner_firstname/i18n/nb_NO.po diff --git a/addons/partner_firstname/i18n/nl.po b/odoo/extra-addons/partner_firstname/i18n/nl.po similarity index 100% rename from addons/partner_firstname/i18n/nl.po rename to odoo/extra-addons/partner_firstname/i18n/nl.po diff --git a/addons/partner_firstname/i18n/nl_BE.po b/odoo/extra-addons/partner_firstname/i18n/nl_BE.po similarity index 100% rename from addons/partner_firstname/i18n/nl_BE.po rename to odoo/extra-addons/partner_firstname/i18n/nl_BE.po diff --git a/addons/partner_firstname/i18n/nl_NL.po b/odoo/extra-addons/partner_firstname/i18n/nl_NL.po similarity index 100% rename from addons/partner_firstname/i18n/nl_NL.po rename to odoo/extra-addons/partner_firstname/i18n/nl_NL.po diff --git a/addons/partner_firstname/i18n/partner_firstname.pot b/odoo/extra-addons/partner_firstname/i18n/partner_firstname.pot similarity index 100% rename from addons/partner_firstname/i18n/partner_firstname.pot rename to odoo/extra-addons/partner_firstname/i18n/partner_firstname.pot diff --git a/addons/partner_firstname/i18n/pl.po b/odoo/extra-addons/partner_firstname/i18n/pl.po similarity index 100% rename from addons/partner_firstname/i18n/pl.po rename to odoo/extra-addons/partner_firstname/i18n/pl.po diff --git a/addons/partner_firstname/i18n/pt.po b/odoo/extra-addons/partner_firstname/i18n/pt.po similarity index 100% rename from addons/partner_firstname/i18n/pt.po rename to odoo/extra-addons/partner_firstname/i18n/pt.po diff --git a/addons/partner_firstname/i18n/pt_BR.po b/odoo/extra-addons/partner_firstname/i18n/pt_BR.po similarity index 100% rename from addons/partner_firstname/i18n/pt_BR.po rename to odoo/extra-addons/partner_firstname/i18n/pt_BR.po diff --git a/addons/partner_firstname/i18n/pt_PT.po b/odoo/extra-addons/partner_firstname/i18n/pt_PT.po similarity index 100% rename from addons/partner_firstname/i18n/pt_PT.po rename to odoo/extra-addons/partner_firstname/i18n/pt_PT.po diff --git a/addons/partner_firstname/i18n/ro.po b/odoo/extra-addons/partner_firstname/i18n/ro.po similarity index 100% rename from addons/partner_firstname/i18n/ro.po rename to odoo/extra-addons/partner_firstname/i18n/ro.po diff --git a/addons/partner_firstname/i18n/ru.po b/odoo/extra-addons/partner_firstname/i18n/ru.po similarity index 100% rename from addons/partner_firstname/i18n/ru.po rename to odoo/extra-addons/partner_firstname/i18n/ru.po diff --git a/addons/partner_firstname/i18n/sk.po b/odoo/extra-addons/partner_firstname/i18n/sk.po similarity index 100% rename from addons/partner_firstname/i18n/sk.po rename to odoo/extra-addons/partner_firstname/i18n/sk.po diff --git a/addons/partner_firstname/i18n/sl.po b/odoo/extra-addons/partner_firstname/i18n/sl.po similarity index 100% rename from addons/partner_firstname/i18n/sl.po rename to odoo/extra-addons/partner_firstname/i18n/sl.po diff --git a/addons/partner_firstname/i18n/sr@latin.po b/odoo/extra-addons/partner_firstname/i18n/sr@latin.po similarity index 100% rename from addons/partner_firstname/i18n/sr@latin.po rename to odoo/extra-addons/partner_firstname/i18n/sr@latin.po diff --git a/addons/partner_firstname/i18n/sv.po b/odoo/extra-addons/partner_firstname/i18n/sv.po similarity index 100% rename from addons/partner_firstname/i18n/sv.po rename to odoo/extra-addons/partner_firstname/i18n/sv.po diff --git a/addons/partner_firstname/i18n/th.po b/odoo/extra-addons/partner_firstname/i18n/th.po similarity index 100% rename from addons/partner_firstname/i18n/th.po rename to odoo/extra-addons/partner_firstname/i18n/th.po diff --git a/addons/partner_firstname/i18n/tr.po b/odoo/extra-addons/partner_firstname/i18n/tr.po similarity index 100% rename from addons/partner_firstname/i18n/tr.po rename to odoo/extra-addons/partner_firstname/i18n/tr.po diff --git a/addons/partner_firstname/i18n/tr_TR.po b/odoo/extra-addons/partner_firstname/i18n/tr_TR.po similarity index 100% rename from addons/partner_firstname/i18n/tr_TR.po rename to odoo/extra-addons/partner_firstname/i18n/tr_TR.po diff --git a/addons/partner_firstname/i18n/vi.po b/odoo/extra-addons/partner_firstname/i18n/vi.po similarity index 100% rename from addons/partner_firstname/i18n/vi.po rename to odoo/extra-addons/partner_firstname/i18n/vi.po diff --git a/addons/partner_firstname/i18n/zh_CN.po b/odoo/extra-addons/partner_firstname/i18n/zh_CN.po similarity index 100% rename from addons/partner_firstname/i18n/zh_CN.po rename to odoo/extra-addons/partner_firstname/i18n/zh_CN.po diff --git a/addons/partner_firstname/i18n/zh_TW.po b/odoo/extra-addons/partner_firstname/i18n/zh_TW.po similarity index 100% rename from addons/partner_firstname/i18n/zh_TW.po rename to odoo/extra-addons/partner_firstname/i18n/zh_TW.po diff --git a/addons/partner_firstname/models/__init__.py b/odoo/extra-addons/partner_firstname/models/__init__.py similarity index 100% rename from addons/partner_firstname/models/__init__.py rename to odoo/extra-addons/partner_firstname/models/__init__.py diff --git a/addons/partner_firstname/models/base_config_settings.py b/odoo/extra-addons/partner_firstname/models/base_config_settings.py similarity index 100% rename from addons/partner_firstname/models/base_config_settings.py rename to odoo/extra-addons/partner_firstname/models/base_config_settings.py diff --git a/addons/partner_firstname/models/res_partner.py b/odoo/extra-addons/partner_firstname/models/res_partner.py similarity index 100% rename from addons/partner_firstname/models/res_partner.py rename to odoo/extra-addons/partner_firstname/models/res_partner.py diff --git a/addons/partner_firstname/models/res_users.py b/odoo/extra-addons/partner_firstname/models/res_users.py similarity index 100% rename from addons/partner_firstname/models/res_users.py rename to odoo/extra-addons/partner_firstname/models/res_users.py diff --git a/addons/partner_firstname/readme/CONFIGURE.rst b/odoo/extra-addons/partner_firstname/readme/CONFIGURE.rst similarity index 100% rename from addons/partner_firstname/readme/CONFIGURE.rst rename to odoo/extra-addons/partner_firstname/readme/CONFIGURE.rst diff --git a/addons/partner_firstname/readme/CONTRIBUTORS.rst b/odoo/extra-addons/partner_firstname/readme/CONTRIBUTORS.rst similarity index 100% rename from addons/partner_firstname/readme/CONTRIBUTORS.rst rename to odoo/extra-addons/partner_firstname/readme/CONTRIBUTORS.rst diff --git a/addons/partner_firstname/readme/DESCRIPTION.rst b/odoo/extra-addons/partner_firstname/readme/DESCRIPTION.rst similarity index 100% rename from addons/partner_firstname/readme/DESCRIPTION.rst rename to odoo/extra-addons/partner_firstname/readme/DESCRIPTION.rst diff --git a/addons/partner_firstname/readme/ROADMAP.rst b/odoo/extra-addons/partner_firstname/readme/ROADMAP.rst similarity index 100% rename from addons/partner_firstname/readme/ROADMAP.rst rename to odoo/extra-addons/partner_firstname/readme/ROADMAP.rst diff --git a/addons/partner_firstname/readme/USAGE.rst b/odoo/extra-addons/partner_firstname/readme/USAGE.rst similarity index 100% rename from addons/partner_firstname/readme/USAGE.rst rename to odoo/extra-addons/partner_firstname/readme/USAGE.rst diff --git a/addons/partner_firstname/static/description/icon.png b/odoo/extra-addons/partner_firstname/static/description/icon.png similarity index 100% rename from addons/partner_firstname/static/description/icon.png rename to odoo/extra-addons/partner_firstname/static/description/icon.png diff --git a/addons/partner_firstname/static/description/index.html b/odoo/extra-addons/partner_firstname/static/description/index.html similarity index 100% rename from addons/partner_firstname/static/description/index.html rename to odoo/extra-addons/partner_firstname/static/description/index.html diff --git a/addons/partner_firstname/tests/__init__.py b/odoo/extra-addons/partner_firstname/tests/__init__.py similarity index 100% rename from addons/partner_firstname/tests/__init__.py rename to odoo/extra-addons/partner_firstname/tests/__init__.py diff --git a/addons/partner_firstname/tests/base.py b/odoo/extra-addons/partner_firstname/tests/base.py similarity index 100% rename from addons/partner_firstname/tests/base.py rename to odoo/extra-addons/partner_firstname/tests/base.py diff --git a/addons/partner_firstname/tests/test_config_settings.py b/odoo/extra-addons/partner_firstname/tests/test_config_settings.py similarity index 100% rename from addons/partner_firstname/tests/test_config_settings.py rename to odoo/extra-addons/partner_firstname/tests/test_config_settings.py diff --git a/addons/partner_firstname/tests/test_copy.py b/odoo/extra-addons/partner_firstname/tests/test_copy.py similarity index 100% rename from addons/partner_firstname/tests/test_copy.py rename to odoo/extra-addons/partner_firstname/tests/test_copy.py diff --git a/addons/partner_firstname/tests/test_create.py b/odoo/extra-addons/partner_firstname/tests/test_create.py similarity index 100% rename from addons/partner_firstname/tests/test_create.py rename to odoo/extra-addons/partner_firstname/tests/test_create.py diff --git a/addons/partner_firstname/tests/test_defaults.py b/odoo/extra-addons/partner_firstname/tests/test_defaults.py similarity index 100% rename from addons/partner_firstname/tests/test_defaults.py rename to odoo/extra-addons/partner_firstname/tests/test_defaults.py diff --git a/addons/partner_firstname/tests/test_delete.py b/odoo/extra-addons/partner_firstname/tests/test_delete.py similarity index 100% rename from addons/partner_firstname/tests/test_delete.py rename to odoo/extra-addons/partner_firstname/tests/test_delete.py diff --git a/addons/partner_firstname/tests/test_empty.py b/odoo/extra-addons/partner_firstname/tests/test_empty.py similarity index 100% rename from addons/partner_firstname/tests/test_empty.py rename to odoo/extra-addons/partner_firstname/tests/test_empty.py diff --git a/addons/partner_firstname/tests/test_name.py b/odoo/extra-addons/partner_firstname/tests/test_name.py similarity index 100% rename from addons/partner_firstname/tests/test_name.py rename to odoo/extra-addons/partner_firstname/tests/test_name.py diff --git a/addons/partner_firstname/tests/test_order.py b/odoo/extra-addons/partner_firstname/tests/test_order.py similarity index 100% rename from addons/partner_firstname/tests/test_order.py rename to odoo/extra-addons/partner_firstname/tests/test_order.py diff --git a/addons/partner_firstname/tests/test_partner_form.py b/odoo/extra-addons/partner_firstname/tests/test_partner_form.py similarity index 100% rename from addons/partner_firstname/tests/test_partner_form.py rename to odoo/extra-addons/partner_firstname/tests/test_partner_form.py diff --git a/addons/partner_firstname/tests/test_user_form.py b/odoo/extra-addons/partner_firstname/tests/test_user_form.py similarity index 100% rename from addons/partner_firstname/tests/test_user_form.py rename to odoo/extra-addons/partner_firstname/tests/test_user_form.py diff --git a/addons/partner_firstname/views/base_config_view.xml b/odoo/extra-addons/partner_firstname/views/base_config_view.xml similarity index 100% rename from addons/partner_firstname/views/base_config_view.xml rename to odoo/extra-addons/partner_firstname/views/base_config_view.xml diff --git a/addons/partner_firstname/views/res_partner.xml b/odoo/extra-addons/partner_firstname/views/res_partner.xml similarity index 100% rename from addons/partner_firstname/views/res_partner.xml rename to odoo/extra-addons/partner_firstname/views/res_partner.xml diff --git a/addons/partner_firstname/views/res_user.xml b/odoo/extra-addons/partner_firstname/views/res_user.xml similarity index 100% rename from addons/partner_firstname/views/res_user.xml rename to odoo/extra-addons/partner_firstname/views/res_user.xml diff --git a/addons/readme.md b/odoo/extra-addons/readme.md similarity index 100% rename from addons/readme.md rename to odoo/extra-addons/readme.md diff --git a/addons/web_m2x_options/README.rst b/odoo/extra-addons/web_m2x_options/README.rst similarity index 100% rename from addons/web_m2x_options/README.rst rename to odoo/extra-addons/web_m2x_options/README.rst diff --git a/addons/web_m2x_options/__init__.py b/odoo/extra-addons/web_m2x_options/__init__.py similarity index 100% rename from addons/web_m2x_options/__init__.py rename to odoo/extra-addons/web_m2x_options/__init__.py diff --git a/addons/web_m2x_options/__manifest__.py b/odoo/extra-addons/web_m2x_options/__manifest__.py similarity index 100% rename from addons/web_m2x_options/__manifest__.py rename to odoo/extra-addons/web_m2x_options/__manifest__.py diff --git a/addons/web_m2x_options/i18n/ar.po b/odoo/extra-addons/web_m2x_options/i18n/ar.po similarity index 100% rename from addons/web_m2x_options/i18n/ar.po rename to odoo/extra-addons/web_m2x_options/i18n/ar.po diff --git a/addons/web_m2x_options/i18n/de.po b/odoo/extra-addons/web_m2x_options/i18n/de.po similarity index 100% rename from addons/web_m2x_options/i18n/de.po rename to odoo/extra-addons/web_m2x_options/i18n/de.po diff --git a/addons/web_m2x_options/i18n/es.po b/odoo/extra-addons/web_m2x_options/i18n/es.po similarity index 100% rename from addons/web_m2x_options/i18n/es.po rename to odoo/extra-addons/web_m2x_options/i18n/es.po diff --git a/addons/web_m2x_options/i18n/es_BO.po b/odoo/extra-addons/web_m2x_options/i18n/es_BO.po similarity index 100% rename from addons/web_m2x_options/i18n/es_BO.po rename to odoo/extra-addons/web_m2x_options/i18n/es_BO.po diff --git a/addons/web_m2x_options/i18n/fi.po b/odoo/extra-addons/web_m2x_options/i18n/fi.po similarity index 100% rename from addons/web_m2x_options/i18n/fi.po rename to odoo/extra-addons/web_m2x_options/i18n/fi.po diff --git a/addons/web_m2x_options/i18n/fr.po b/odoo/extra-addons/web_m2x_options/i18n/fr.po similarity index 100% rename from addons/web_m2x_options/i18n/fr.po rename to odoo/extra-addons/web_m2x_options/i18n/fr.po diff --git a/addons/web_m2x_options/i18n/hr.po b/odoo/extra-addons/web_m2x_options/i18n/hr.po similarity index 100% rename from addons/web_m2x_options/i18n/hr.po rename to odoo/extra-addons/web_m2x_options/i18n/hr.po diff --git a/addons/web_m2x_options/i18n/it.po b/odoo/extra-addons/web_m2x_options/i18n/it.po similarity index 100% rename from addons/web_m2x_options/i18n/it.po rename to odoo/extra-addons/web_m2x_options/i18n/it.po diff --git a/addons/web_m2x_options/i18n/nl.po b/odoo/extra-addons/web_m2x_options/i18n/nl.po similarity index 100% rename from addons/web_m2x_options/i18n/nl.po rename to odoo/extra-addons/web_m2x_options/i18n/nl.po diff --git a/addons/web_m2x_options/i18n/nl_NL.po b/odoo/extra-addons/web_m2x_options/i18n/nl_NL.po similarity index 100% rename from addons/web_m2x_options/i18n/nl_NL.po rename to odoo/extra-addons/web_m2x_options/i18n/nl_NL.po diff --git a/addons/web_m2x_options/i18n/pt_BR.po b/odoo/extra-addons/web_m2x_options/i18n/pt_BR.po similarity index 100% rename from addons/web_m2x_options/i18n/pt_BR.po rename to odoo/extra-addons/web_m2x_options/i18n/pt_BR.po diff --git a/addons/web_m2x_options/i18n/sl.po b/odoo/extra-addons/web_m2x_options/i18n/sl.po similarity index 100% rename from addons/web_m2x_options/i18n/sl.po rename to odoo/extra-addons/web_m2x_options/i18n/sl.po diff --git a/addons/web_m2x_options/i18n/tr.po b/odoo/extra-addons/web_m2x_options/i18n/tr.po similarity index 100% rename from addons/web_m2x_options/i18n/tr.po rename to odoo/extra-addons/web_m2x_options/i18n/tr.po diff --git a/addons/web_m2x_options/i18n/web_m2x_options.pot b/odoo/extra-addons/web_m2x_options/i18n/web_m2x_options.pot similarity index 100% rename from addons/web_m2x_options/i18n/web_m2x_options.pot rename to odoo/extra-addons/web_m2x_options/i18n/web_m2x_options.pot diff --git a/addons/web_m2x_options/i18n/zh_CN.po b/odoo/extra-addons/web_m2x_options/i18n/zh_CN.po similarity index 100% rename from addons/web_m2x_options/i18n/zh_CN.po rename to odoo/extra-addons/web_m2x_options/i18n/zh_CN.po diff --git a/addons/web_m2x_options/models/__init__.py b/odoo/extra-addons/web_m2x_options/models/__init__.py similarity index 100% rename from addons/web_m2x_options/models/__init__.py rename to odoo/extra-addons/web_m2x_options/models/__init__.py diff --git a/addons/web_m2x_options/models/ir_config_parameter.py b/odoo/extra-addons/web_m2x_options/models/ir_config_parameter.py similarity index 100% rename from addons/web_m2x_options/models/ir_config_parameter.py rename to odoo/extra-addons/web_m2x_options/models/ir_config_parameter.py diff --git a/addons/web_m2x_options/models/ir_http.py b/odoo/extra-addons/web_m2x_options/models/ir_http.py similarity index 100% rename from addons/web_m2x_options/models/ir_http.py rename to odoo/extra-addons/web_m2x_options/models/ir_http.py diff --git a/addons/web_m2x_options/readme/CONTRIBUTORS.rst b/odoo/extra-addons/web_m2x_options/readme/CONTRIBUTORS.rst similarity index 100% rename from addons/web_m2x_options/readme/CONTRIBUTORS.rst rename to odoo/extra-addons/web_m2x_options/readme/CONTRIBUTORS.rst diff --git a/addons/web_m2x_options/readme/CREDITS.rst b/odoo/extra-addons/web_m2x_options/readme/CREDITS.rst similarity index 100% rename from addons/web_m2x_options/readme/CREDITS.rst rename to odoo/extra-addons/web_m2x_options/readme/CREDITS.rst diff --git a/addons/web_m2x_options/readme/DESCRIPTION.rst b/odoo/extra-addons/web_m2x_options/readme/DESCRIPTION.rst similarity index 100% rename from addons/web_m2x_options/readme/DESCRIPTION.rst rename to odoo/extra-addons/web_m2x_options/readme/DESCRIPTION.rst diff --git a/addons/web_m2x_options/readme/ROADMAP.rst b/odoo/extra-addons/web_m2x_options/readme/ROADMAP.rst similarity index 100% rename from addons/web_m2x_options/readme/ROADMAP.rst rename to odoo/extra-addons/web_m2x_options/readme/ROADMAP.rst diff --git a/addons/web_m2x_options/readme/USAGE.rst b/odoo/extra-addons/web_m2x_options/readme/USAGE.rst similarity index 100% rename from addons/web_m2x_options/readme/USAGE.rst rename to odoo/extra-addons/web_m2x_options/readme/USAGE.rst diff --git a/addons/web_m2x_options/static/description/icon.png b/odoo/extra-addons/web_m2x_options/static/description/icon.png similarity index 100% rename from addons/web_m2x_options/static/description/icon.png rename to odoo/extra-addons/web_m2x_options/static/description/icon.png diff --git a/addons/web_m2x_options/static/description/index.html b/odoo/extra-addons/web_m2x_options/static/description/index.html similarity index 100% rename from addons/web_m2x_options/static/description/index.html rename to odoo/extra-addons/web_m2x_options/static/description/index.html diff --git a/addons/web_m2x_options/static/src/components/base.xml b/odoo/extra-addons/web_m2x_options/static/src/components/base.xml similarity index 100% rename from addons/web_m2x_options/static/src/components/base.xml rename to odoo/extra-addons/web_m2x_options/static/src/components/base.xml diff --git a/addons/web_m2x_options/static/src/components/form.esm.js b/odoo/extra-addons/web_m2x_options/static/src/components/form.esm.js similarity index 100% rename from addons/web_m2x_options/static/src/components/form.esm.js rename to odoo/extra-addons/web_m2x_options/static/src/components/form.esm.js diff --git a/addons/web_m2x_options/static/src/components/relational_utils.esm.js b/odoo/extra-addons/web_m2x_options/static/src/components/relational_utils.esm.js similarity index 100% rename from addons/web_m2x_options/static/src/components/relational_utils.esm.js rename to odoo/extra-addons/web_m2x_options/static/src/components/relational_utils.esm.js diff --git a/addons/web_m2x_options/tests/__init__.py b/odoo/extra-addons/web_m2x_options/tests/__init__.py similarity index 100% rename from addons/web_m2x_options/tests/__init__.py rename to odoo/extra-addons/web_m2x_options/tests/__init__.py diff --git a/addons/web_m2x_options/tests/test_ir_config_parameter.py b/odoo/extra-addons/web_m2x_options/tests/test_ir_config_parameter.py similarity index 100% rename from addons/web_m2x_options/tests/test_ir_config_parameter.py rename to odoo/extra-addons/web_m2x_options/tests/test_ir_config_parameter.py From 0cabdde22b70bea03f625dd32bc652a446a2512b Mon Sep 17 00:00:00 2001 From: belloafeez Date: Fri, 2 Aug 2024 10:14:21 +0100 Subject: [PATCH 14/54] updated Signed-off-by: belloafeez --- addons/openems/.gitignore | 3 + addons/openems/__init__.py | 1 + addons/openems/__manifest__.py | 40 + addons/openems/controllers/__init__.py | 1 + addons/openems/controllers/alerting.py | 86 + addons/openems/controllers/const.py | 5 + addons/openems/controllers/openems_backend.py | 276 +++ addons/openems/controllers/setup_protocol.py | 142 ++ addons/openems/controllers/user.py | 32 + addons/openems/data/OpenEMS-Logo.jpg | Bin 0 -> 152320 bytes addons/openems/data/demo.xml | 12 + addons/openems/data/ir_config_parameter.xml | 9 + addons/openems/data/res_partner_category.xml | 11 + addons/openems/i18n/de.po | 1666 +++++++++++++++++ addons/openems/i18n/openems.pot | 1666 +++++++++++++++++ .../openems/mail/openems/alerting_offline.xml | 275 +++ .../mail/openems/alerting_sum_state.xml | 268 +++ .../mail/openems/setup_protocol_customer.xml | 170 ++ .../mail/openems/setup_protocol_installer.xml | 173 ++ .../mail/openems/user_registration.xml | 197 ++ .../migrations/16.0.1.0.1/post-migrate.py | 9 + .../migrations/16.0.1.0.1/pre-migrate.py | 7 + addons/openems/models/__init__.py | 1 + addons/openems/models/device.py | 321 ++++ addons/openems/models/partner.py | 12 + addons/openems/models/setup_protocol.py | 49 + addons/openems/models/stock_production_lot.py | 23 + addons/openems/models/user.py | 37 + addons/openems/report/setup_protocol.xml | 311 +++ addons/openems/security/ir.model.access.csv | 31 + addons/openems/security/openems.xml | 54 + .../.setuptools-odoo-make-default-ignore | 2 + addons/openems/setup/README | 2 + addons/openems/static/description/icon.png | Bin 0 -> 53271 bytes addons/openems/static/mail/OpenEMS-Logo.jpg | Bin 0 -> 152320 bytes addons/openems/views/device.xml | 320 ++++ addons/openems/views/partner.xml | 28 + addons/openems/views/setup_protocol.xml | 82 + .../views/stock_production_lot_views.xml | 13 + addons/openems/views/user.xml | 25 + addons/partner_firstname/README.rst | 146 ++ addons/partner_firstname/__init__.py | 2 + addons/partner_firstname/__manifest__.py | 30 + addons/partner_firstname/exceptions.py | 12 + addons/partner_firstname/hooks.py | 9 + addons/partner_firstname/i18n/am.po | 130 ++ addons/partner_firstname/i18n/ar.po | 131 ++ addons/partner_firstname/i18n/bg.po | 130 ++ addons/partner_firstname/i18n/bs.po | 131 ++ addons/partner_firstname/i18n/ca.po | 139 ++ addons/partner_firstname/i18n/cs.po | 130 ++ addons/partner_firstname/i18n/da.po | 135 ++ addons/partner_firstname/i18n/de.po | 136 ++ addons/partner_firstname/i18n/el_GR.po | 131 ++ addons/partner_firstname/i18n/en_GB.po | 131 ++ addons/partner_firstname/i18n/es.po | 136 ++ addons/partner_firstname/i18n/es_CR.po | 131 ++ addons/partner_firstname/i18n/es_EC.po | 131 ++ addons/partner_firstname/i18n/es_MX.po | 131 ++ addons/partner_firstname/i18n/es_VE.po | 131 ++ addons/partner_firstname/i18n/et.po | 130 ++ addons/partner_firstname/i18n/eu.po | 130 ++ addons/partner_firstname/i18n/fi.po | 130 ++ addons/partner_firstname/i18n/fr.po | 138 ++ addons/partner_firstname/i18n/fr_CA.po | 131 ++ addons/partner_firstname/i18n/fr_CH.po | 131 ++ addons/partner_firstname/i18n/gl.po | 130 ++ addons/partner_firstname/i18n/hr.po | 132 ++ addons/partner_firstname/i18n/hr_HR.po | 132 ++ addons/partner_firstname/i18n/hu.po | 138 ++ addons/partner_firstname/i18n/it.po | 136 ++ addons/partner_firstname/i18n/ja.po | 130 ++ addons/partner_firstname/i18n/lt.po | 131 ++ addons/partner_firstname/i18n/lv.po | 131 ++ addons/partner_firstname/i18n/mk.po | 130 ++ addons/partner_firstname/i18n/mn.po | 130 ++ addons/partner_firstname/i18n/nb.po | 131 ++ addons/partner_firstname/i18n/nb_NO.po | 131 ++ addons/partner_firstname/i18n/nl.po | 130 ++ addons/partner_firstname/i18n/nl_BE.po | 131 ++ addons/partner_firstname/i18n/nl_NL.po | 138 ++ .../i18n/partner_firstname.pot | 124 ++ addons/partner_firstname/i18n/pl.po | 132 ++ addons/partner_firstname/i18n/pt.po | 130 ++ addons/partner_firstname/i18n/pt_BR.po | 138 ++ addons/partner_firstname/i18n/pt_PT.po | 131 ++ addons/partner_firstname/i18n/ro.po | 131 ++ addons/partner_firstname/i18n/ru.po | 132 ++ addons/partner_firstname/i18n/sk.po | 130 ++ addons/partner_firstname/i18n/sl.po | 131 ++ addons/partner_firstname/i18n/sr@latin.po | 132 ++ addons/partner_firstname/i18n/sv.po | 130 ++ addons/partner_firstname/i18n/th.po | 130 ++ addons/partner_firstname/i18n/tr.po | 130 ++ addons/partner_firstname/i18n/tr_TR.po | 131 ++ addons/partner_firstname/i18n/vi.po | 130 ++ addons/partner_firstname/i18n/zh_CN.po | 131 ++ addons/partner_firstname/i18n/zh_TW.po | 131 ++ addons/partner_firstname/models/__init__.py | 3 + .../models/base_config_settings.py | 71 + .../partner_firstname/models/res_partner.py | 270 +++ addons/partner_firstname/models/res_users.py | 49 + addons/partner_firstname/readme/CONFIGURE.rst | 14 + .../partner_firstname/readme/CONTRIBUTORS.rst | 23 + .../partner_firstname/readme/DESCRIPTION.rst | 2 + addons/partner_firstname/readme/ROADMAP.rst | 3 + addons/partner_firstname/readme/USAGE.rst | 13 + .../static/description/icon.png | Bin 0 -> 9455 bytes .../static/description/index.html | 488 +++++ addons/partner_firstname/tests/__init__.py | 12 + addons/partner_firstname/tests/base.py | 65 + .../tests/test_config_settings.py | 35 + addons/partner_firstname/tests/test_copy.py | 95 + addons/partner_firstname/tests/test_create.py | 79 + .../partner_firstname/tests/test_defaults.py | 64 + addons/partner_firstname/tests/test_delete.py | 38 + addons/partner_firstname/tests/test_empty.py | 73 + addons/partner_firstname/tests/test_name.py | 119 ++ addons/partner_firstname/tests/test_order.py | 38 + .../tests/test_partner_form.py | 106 ++ .../partner_firstname/tests/test_user_form.py | 51 + .../views/base_config_view.xml | 28 + .../partner_firstname/views/res_partner.xml | 105 ++ addons/partner_firstname/views/res_user.xml | 25 + addons/readme.md | 1 + addons/web_m2x_options/README.rst | 217 +++ addons/web_m2x_options/__init__.py | 1 + addons/web_m2x_options/__manifest__.py | 21 + addons/web_m2x_options/i18n/ar.po | 133 ++ addons/web_m2x_options/i18n/de.po | 159 ++ addons/web_m2x_options/i18n/es.po | 145 ++ addons/web_m2x_options/i18n/es_BO.po | 116 ++ addons/web_m2x_options/i18n/fi.po | 132 ++ addons/web_m2x_options/i18n/fr.po | 158 ++ addons/web_m2x_options/i18n/hr.po | 150 ++ addons/web_m2x_options/i18n/it.po | 133 ++ addons/web_m2x_options/i18n/nl.po | 162 ++ addons/web_m2x_options/i18n/nl_NL.po | 125 ++ addons/web_m2x_options/i18n/pt_BR.po | 156 ++ addons/web_m2x_options/i18n/sl.po | 133 ++ addons/web_m2x_options/i18n/tr.po | 132 ++ .../web_m2x_options/i18n/web_m2x_options.pot | 115 ++ addons/web_m2x_options/i18n/zh_CN.po | 153 ++ addons/web_m2x_options/models/__init__.py | 2 + .../models/ir_config_parameter.py | 18 + addons/web_m2x_options/models/ir_http.py | 11 + .../web_m2x_options/readme/CONTRIBUTORS.rst | 16 + addons/web_m2x_options/readme/CREDITS.rst | 1 + addons/web_m2x_options/readme/DESCRIPTION.rst | 10 + addons/web_m2x_options/readme/ROADMAP.rst | 6 + addons/web_m2x_options/readme/USAGE.rst | 95 + .../static/description/icon.png | Bin 0 -> 9455 bytes .../static/description/index.html | 412 ++++ .../static/src/components/base.xml | 46 + .../static/src/components/form.esm.js | 404 ++++ .../src/components/relational_utils.esm.js | 221 +++ addons/web_m2x_options/tests/__init__.py | 2 + .../tests/test_ir_config_parameter.py | 28 + 158 files changed, 19021 insertions(+) create mode 100644 addons/openems/.gitignore create mode 100644 addons/openems/__init__.py create mode 100644 addons/openems/__manifest__.py create mode 100644 addons/openems/controllers/__init__.py create mode 100644 addons/openems/controllers/alerting.py create mode 100644 addons/openems/controllers/const.py create mode 100644 addons/openems/controllers/openems_backend.py create mode 100644 addons/openems/controllers/setup_protocol.py create mode 100644 addons/openems/controllers/user.py create mode 100644 addons/openems/data/OpenEMS-Logo.jpg create mode 100644 addons/openems/data/demo.xml create mode 100644 addons/openems/data/ir_config_parameter.xml create mode 100644 addons/openems/data/res_partner_category.xml create mode 100644 addons/openems/i18n/de.po create mode 100644 addons/openems/i18n/openems.pot create mode 100644 addons/openems/mail/openems/alerting_offline.xml create mode 100644 addons/openems/mail/openems/alerting_sum_state.xml create mode 100644 addons/openems/mail/openems/setup_protocol_customer.xml create mode 100644 addons/openems/mail/openems/setup_protocol_installer.xml create mode 100644 addons/openems/mail/openems/user_registration.xml create mode 100644 addons/openems/migrations/16.0.1.0.1/post-migrate.py create mode 100644 addons/openems/migrations/16.0.1.0.1/pre-migrate.py create mode 100644 addons/openems/models/__init__.py create mode 100644 addons/openems/models/device.py create mode 100644 addons/openems/models/partner.py create mode 100644 addons/openems/models/setup_protocol.py create mode 100644 addons/openems/models/stock_production_lot.py create mode 100644 addons/openems/models/user.py create mode 100644 addons/openems/report/setup_protocol.xml create mode 100644 addons/openems/security/ir.model.access.csv create mode 100644 addons/openems/security/openems.xml create mode 100644 addons/openems/setup/.setuptools-odoo-make-default-ignore create mode 100644 addons/openems/setup/README create mode 100644 addons/openems/static/description/icon.png create mode 100644 addons/openems/static/mail/OpenEMS-Logo.jpg create mode 100644 addons/openems/views/device.xml create mode 100644 addons/openems/views/partner.xml create mode 100644 addons/openems/views/setup_protocol.xml create mode 100644 addons/openems/views/stock_production_lot_views.xml create mode 100644 addons/openems/views/user.xml create mode 100644 addons/partner_firstname/README.rst create mode 100644 addons/partner_firstname/__init__.py create mode 100644 addons/partner_firstname/__manifest__.py create mode 100644 addons/partner_firstname/exceptions.py create mode 100644 addons/partner_firstname/hooks.py create mode 100644 addons/partner_firstname/i18n/am.po create mode 100644 addons/partner_firstname/i18n/ar.po create mode 100644 addons/partner_firstname/i18n/bg.po create mode 100644 addons/partner_firstname/i18n/bs.po create mode 100644 addons/partner_firstname/i18n/ca.po create mode 100644 addons/partner_firstname/i18n/cs.po create mode 100644 addons/partner_firstname/i18n/da.po create mode 100644 addons/partner_firstname/i18n/de.po create mode 100644 addons/partner_firstname/i18n/el_GR.po create mode 100644 addons/partner_firstname/i18n/en_GB.po create mode 100644 addons/partner_firstname/i18n/es.po create mode 100644 addons/partner_firstname/i18n/es_CR.po create mode 100644 addons/partner_firstname/i18n/es_EC.po create mode 100644 addons/partner_firstname/i18n/es_MX.po create mode 100644 addons/partner_firstname/i18n/es_VE.po create mode 100644 addons/partner_firstname/i18n/et.po create mode 100644 addons/partner_firstname/i18n/eu.po create mode 100644 addons/partner_firstname/i18n/fi.po create mode 100644 addons/partner_firstname/i18n/fr.po create mode 100644 addons/partner_firstname/i18n/fr_CA.po create mode 100644 addons/partner_firstname/i18n/fr_CH.po create mode 100644 addons/partner_firstname/i18n/gl.po create mode 100644 addons/partner_firstname/i18n/hr.po create mode 100644 addons/partner_firstname/i18n/hr_HR.po create mode 100644 addons/partner_firstname/i18n/hu.po create mode 100644 addons/partner_firstname/i18n/it.po create mode 100644 addons/partner_firstname/i18n/ja.po create mode 100644 addons/partner_firstname/i18n/lt.po create mode 100644 addons/partner_firstname/i18n/lv.po create mode 100644 addons/partner_firstname/i18n/mk.po create mode 100644 addons/partner_firstname/i18n/mn.po create mode 100644 addons/partner_firstname/i18n/nb.po create mode 100644 addons/partner_firstname/i18n/nb_NO.po create mode 100644 addons/partner_firstname/i18n/nl.po create mode 100644 addons/partner_firstname/i18n/nl_BE.po create mode 100644 addons/partner_firstname/i18n/nl_NL.po create mode 100644 addons/partner_firstname/i18n/partner_firstname.pot create mode 100644 addons/partner_firstname/i18n/pl.po create mode 100644 addons/partner_firstname/i18n/pt.po create mode 100644 addons/partner_firstname/i18n/pt_BR.po create mode 100644 addons/partner_firstname/i18n/pt_PT.po create mode 100644 addons/partner_firstname/i18n/ro.po create mode 100644 addons/partner_firstname/i18n/ru.po create mode 100644 addons/partner_firstname/i18n/sk.po create mode 100644 addons/partner_firstname/i18n/sl.po create mode 100644 addons/partner_firstname/i18n/sr@latin.po create mode 100644 addons/partner_firstname/i18n/sv.po create mode 100644 addons/partner_firstname/i18n/th.po create mode 100644 addons/partner_firstname/i18n/tr.po create mode 100644 addons/partner_firstname/i18n/tr_TR.po create mode 100644 addons/partner_firstname/i18n/vi.po create mode 100644 addons/partner_firstname/i18n/zh_CN.po create mode 100644 addons/partner_firstname/i18n/zh_TW.po create mode 100644 addons/partner_firstname/models/__init__.py create mode 100644 addons/partner_firstname/models/base_config_settings.py create mode 100644 addons/partner_firstname/models/res_partner.py create mode 100644 addons/partner_firstname/models/res_users.py create mode 100644 addons/partner_firstname/readme/CONFIGURE.rst create mode 100644 addons/partner_firstname/readme/CONTRIBUTORS.rst create mode 100644 addons/partner_firstname/readme/DESCRIPTION.rst create mode 100644 addons/partner_firstname/readme/ROADMAP.rst create mode 100644 addons/partner_firstname/readme/USAGE.rst create mode 100644 addons/partner_firstname/static/description/icon.png create mode 100644 addons/partner_firstname/static/description/index.html create mode 100644 addons/partner_firstname/tests/__init__.py create mode 100644 addons/partner_firstname/tests/base.py create mode 100644 addons/partner_firstname/tests/test_config_settings.py create mode 100644 addons/partner_firstname/tests/test_copy.py create mode 100644 addons/partner_firstname/tests/test_create.py create mode 100644 addons/partner_firstname/tests/test_defaults.py create mode 100644 addons/partner_firstname/tests/test_delete.py create mode 100644 addons/partner_firstname/tests/test_empty.py create mode 100644 addons/partner_firstname/tests/test_name.py create mode 100644 addons/partner_firstname/tests/test_order.py create mode 100644 addons/partner_firstname/tests/test_partner_form.py create mode 100644 addons/partner_firstname/tests/test_user_form.py create mode 100644 addons/partner_firstname/views/base_config_view.xml create mode 100644 addons/partner_firstname/views/res_partner.xml create mode 100644 addons/partner_firstname/views/res_user.xml create mode 100644 addons/readme.md create mode 100644 addons/web_m2x_options/README.rst create mode 100644 addons/web_m2x_options/__init__.py create mode 100644 addons/web_m2x_options/__manifest__.py create mode 100644 addons/web_m2x_options/i18n/ar.po create mode 100644 addons/web_m2x_options/i18n/de.po create mode 100644 addons/web_m2x_options/i18n/es.po create mode 100644 addons/web_m2x_options/i18n/es_BO.po create mode 100644 addons/web_m2x_options/i18n/fi.po create mode 100644 addons/web_m2x_options/i18n/fr.po create mode 100644 addons/web_m2x_options/i18n/hr.po create mode 100644 addons/web_m2x_options/i18n/it.po create mode 100644 addons/web_m2x_options/i18n/nl.po create mode 100644 addons/web_m2x_options/i18n/nl_NL.po create mode 100644 addons/web_m2x_options/i18n/pt_BR.po create mode 100644 addons/web_m2x_options/i18n/sl.po create mode 100644 addons/web_m2x_options/i18n/tr.po create mode 100644 addons/web_m2x_options/i18n/web_m2x_options.pot create mode 100644 addons/web_m2x_options/i18n/zh_CN.po create mode 100644 addons/web_m2x_options/models/__init__.py create mode 100644 addons/web_m2x_options/models/ir_config_parameter.py create mode 100644 addons/web_m2x_options/models/ir_http.py create mode 100644 addons/web_m2x_options/readme/CONTRIBUTORS.rst create mode 100644 addons/web_m2x_options/readme/CREDITS.rst create mode 100644 addons/web_m2x_options/readme/DESCRIPTION.rst create mode 100644 addons/web_m2x_options/readme/ROADMAP.rst create mode 100644 addons/web_m2x_options/readme/USAGE.rst create mode 100644 addons/web_m2x_options/static/description/icon.png create mode 100644 addons/web_m2x_options/static/description/index.html create mode 100644 addons/web_m2x_options/static/src/components/base.xml create mode 100644 addons/web_m2x_options/static/src/components/form.esm.js create mode 100644 addons/web_m2x_options/static/src/components/relational_utils.esm.js create mode 100644 addons/web_m2x_options/tests/__init__.py create mode 100644 addons/web_m2x_options/tests/test_ir_config_parameter.py diff --git a/addons/openems/.gitignore b/addons/openems/.gitignore new file mode 100644 index 0000000..e41d5e2 --- /dev/null +++ b/addons/openems/.gitignore @@ -0,0 +1,3 @@ +.swp +.swo +**/__pycache__ diff --git a/addons/openems/__init__.py b/addons/openems/__init__.py new file mode 100644 index 0000000..72d3ea6 --- /dev/null +++ b/addons/openems/__init__.py @@ -0,0 +1 @@ +from . import controllers, models diff --git a/addons/openems/__manifest__.py b/addons/openems/__manifest__.py new file mode 100644 index 0000000..232ebf1 --- /dev/null +++ b/addons/openems/__manifest__.py @@ -0,0 +1,40 @@ +{ + "name": "OpenEMS", + "summary": "Everything related to OpenEMS (Open Energy Management System)", + "version": "16.0.1.0.1", + "author": "OpenEMS Association e.V.", + "maintainer": "OpenEMS Association e.V.", + "contributors": [ + "Stefan Feilmeier " + "Maximilian Lang " + ], + "website": "https://openems.io", + "license": "AGPL-3", + "category": "Specific Industry Applications", + "depends": ["base", "web", "mail", "crm", "resource", "stock", "web_m2x_options", "partner_firstname"], + "data": [ + "data/ir_config_parameter.xml", + "data/res_partner_category.xml", + "security/openems.xml", + "security/ir.model.access.csv", + "report/setup_protocol.xml", + "views/device.xml", + "views/partner.xml", + "views/setup_protocol.xml", + "views/user.xml", + "views/stock_production_lot_views.xml", + "mail/openems/alerting_offline.xml", + "mail/openems/alerting_sum_state.xml", + "mail/openems/setup_protocol_customer.xml", + "mail/openems/setup_protocol_installer.xml", + "mail/openems/user_registration.xml", + ], + "demo": ["data/demo.xml"], + "js": [], + "css": [], + "qweb": [], + "images": [], + "test": [], + "installable": True, + "application": True, +} diff --git a/addons/openems/controllers/__init__.py b/addons/openems/controllers/__init__.py new file mode 100644 index 0000000..3e863cd --- /dev/null +++ b/addons/openems/controllers/__init__.py @@ -0,0 +1 @@ +from . import openems_backend, setup_protocol, user, alerting diff --git a/addons/openems/controllers/alerting.py b/addons/openems/controllers/alerting.py new file mode 100644 index 0000000..7a848f2 --- /dev/null +++ b/addons/openems/controllers/alerting.py @@ -0,0 +1,86 @@ +import logging +from datetime import datetime +from enum import Enum + +from odoo import http +from odoo.http import request + +class SumState(Enum): + FAULT = 0 + WARNING = 1 + +class Message: + sentAt: datetime + edgeId: str + userIds: list[int] + + def __init__(self, sentAt: datetime, edgeId: str, userIds: list[int]) -> None: + self.sentAt = sentAt + self.edgeId = edgeId + self.userIds = userIds + +class SumStateMessage(Message): + state: SumState + + def __init__(self, sentAt: datetime, edgeId: str, userIds: list[int], state: SumState) -> None: + super().__init__(sentAt, edgeId, userIds) + self.state = state + +class Alerting(http.Controller): + __logger = logging.getLogger("Alerting") + + @http.route("/openems_backend/mail/alerting_sum_state", type="json", auth="user") + def sum_state_alerting(self, sentAt: str, params: list[dict]): + msgs = self.__get_sum_state_params(sentAt, params) + update_func = lambda role, at: { role.write({"sum_state_last_notification": at})} + + if len(msgs) == 0: + self.__logger.error("Scheduled SumState-Alerting-Mail without any recipients!!!") + + template = request.env.ref('openems.alerting_sum_state') + for msg in msgs: + self.__send_mails(template, msg, update_func) + + return {} + + @http.route("/openems_backend/mail/alerting_offline", type="json", auth="user") + def offline_alerting(self, sentAt: str, params: list[dict]): + msgs = self.__get_offline_params(sentAt, params) + update_func = lambda role, at: { role.write({"offline_last_notification": at})} + + template = request.env.ref("openems.alerting_offline") + for msg in msgs: + self.__send_mails(template, msg, update_func) + + return {} + + def __get_offline_params(self, sentAt, params) -> list[Message]: + msgs = list() + sent = datetime.strptime(sentAt, "%Y-%m-%d %H:%M:%S") + for param in params: + edgeId = param["edgeId"] + recipients = param["recipients"] + msgs.append(Message(sent, edgeId, recipients)); + return msgs + + def __get_sum_state_params(self, sentAt, params) -> list[SumStateMessage]: + msgs = list() + sent = datetime.strptime(sentAt, "%Y-%m-%d %H:%M:%S") + for param in params: + edgeId = param["edgeId"] + recipients = param["recipients"] + state = param["state"] + msgs.append(SumStateMessage(sent, edgeId, recipients, state)); + return msgs + + def __send_mails(self, template, msg: Message, update_func): + roles = http.request.env['openems.alerting'].search( + [('user_id','in',msg.userIds),('device_id','=',msg.edgeId)] + ) + + for role in roles: + try: + template.send_mail(res_id=role.id, force_send=True) + update_func(role, msg.sentAt) + except Exception as err: + self.__logger.error("[" + str(err) + "] Unable to send template[" + str(template.name) +"] to edgeUser[user=" + str(role.id) + ", edge=" + str(msg.edgeId)+ "]") \ No newline at end of file diff --git a/addons/openems/controllers/const.py b/addons/openems/controllers/const.py new file mode 100644 index 0000000..c6fbc01 --- /dev/null +++ b/addons/openems/controllers/const.py @@ -0,0 +1,5 @@ +from odoo.modules.module import get_module_resource + +import base64 + +OPENEMS_LOGO_BASE64 = base64.b64encode(open(get_module_resource('openems', 'data', 'OpenEMS-Logo.jpg') , "rb").read()) \ No newline at end of file diff --git a/addons/openems/controllers/openems_backend.py b/addons/openems/controllers/openems_backend.py new file mode 100644 index 0000000..d0dcb80 --- /dev/null +++ b/addons/openems/controllers/openems_backend.py @@ -0,0 +1,276 @@ +from odoo import http + + +class OpenemsBackend(http.Controller): + @http.route("/openems_backend/info", auth="user", type="json") + def index(self): + # Get user + user_id = http.request.env.context.get("uid") + res_users = http.request.env["res.users"].sudo() + user_rec = res_users.search_read( + [("id", "=", user_id)], + ["login", "name", "groups_id", "global_role", "openems_language"], + )[0] + res_users.browse([user_id]) + + # Get res group model + res_groups_model = http.request.env["res.groups"].sudo() + + # Get Manager and Reader group + manager_group = res_groups_model.env.ref("openems.group_openems_manager") + reader_group = res_groups_model.env.ref("openems.group_openems_reader") + + manager_group_id = manager_group["id"] + reader_group_id = reader_group["id"] + + # Get user attributes + global_role = user_rec["global_role"] + if manager_group_id in user_rec["groups_id"]: + # Manager group + global_role = "admin" + + # return empty device (use pagination) list if user is manager or reader + if manager_group_id in user_rec["groups_id"] or reader_group_id in user_rec["groups_id"]: + return { + "user": { + "id": user_rec["id"], + "login": user_rec["login"], + "name": user_rec["name"], + "global_role": global_role, + "language": user_rec["openems_language"], + "has_multiple_edges": True + }, + "devices": [], + } + + # Get specific Device roles + device_user_role_model = http.request.env["openems.device_user_role"] + user_role_ids = device_user_role_model.search_read( + [("user_id", "=", user_id)], ["id", "role"] + ) + + # Get Devices + device_model = http.request.env["openems.device"] + devices = device_model.search_read( + [], ["id", "name", "user_role_ids", "comment", "producttype", + "lastmessage", "first_setup_protocol_date", "openems_sum_state_level"] + ) + + devs = [] + for device_rec in devices: + # Set user role per group + role = "guest" + if manager_group_id in user_rec["groups_id"]: + # Manager group + role = "admin" + elif reader_group_id in user_rec["groups_id"]: + # Reader group + role = "guest" + + # Set specific user role + for device_role_id in device_rec["user_role_ids"]: + for user_role_id in user_role_ids: + if device_role_id == user_role_id["id"]: + role = user_role_id["role"] + + # Prepare result + dev = { + "id": device_rec["id"], + "name": device_rec["name"], + "comment": device_rec["comment"], + "producttype": device_rec["producttype"], + "role": role, + "lastmessage": device_rec["lastmessage"], + "openems_sum_state_level": device_rec["openems_sum_state_level"] + } + + if device_rec["first_setup_protocol_date"]: + dev["first_setup_protocol_date"] = device_rec[ + "first_setup_protocol_date" + ] + + devs.append(dev) + + return { + "user": { + "id": user_rec["id"], + "login": user_rec["login"], + "name": user_rec["name"], + "global_role": global_role, + "language": user_rec["openems_language"], + "has_multiple_edges": len(devs) > 1 + }, + "devices": devs, + } + + @http.route("/openems_backend/get_edge_with_role", auth="user", type="json") + def get_edge_with_role(self, edge_id: str): + user_id = http.request.env.context.get("uid") + res_users = http.request.env["res.users"].sudo() + user_rec = res_users.search_read( + [("id", "=", user_id)], + ["login", "name", "groups_id"], + )[0] + + # Get res group model + res_groups_model = http.request.env["res.groups"].sudo() + + # Get Manager and Reader group + manager_group = res_groups_model.env.ref("openems.group_openems_manager") + reader_group = res_groups_model.env.ref("openems.group_openems_reader") + + manager_group_id = manager_group["id"] + reader_group_id = reader_group["id"] + + # get devices for which the user has permissions + device_model = http.request.env["openems.device"] + devices = device_model.search_read( + [("name", "=", edge_id)], + ["id", "name", "comment", "producttype", "lastmessage", "first_setup_protocol_date", "openems_sum_state_level"]) + + if len(devices) != 1: + return {} + + device = devices[0] + + # Get specific Device roles + device_user_role_model = http.request.env["openems.device_user_role"] + device_user_roles = device_user_role_model.search_read( + [("user_id", "=", user_id), + ("device_id", "=", device["id"])], ["id", "role"] + ) + + # Set user role per group + role = "guest" + if manager_group_id in user_rec["groups_id"]: + # Manager group + role = "admin" + elif reader_group_id in user_rec["groups_id"]: + # Reader group + role = "guest" + + # Set specific user role + if len(device_user_roles) > 0: + role = device_user_roles[0]["role"] + + dev = { + "id": device["id"], + "name": device["name"], + "comment": device["comment"], + "producttype": device["producttype"], + "role": role, + "lastmessage": device["lastmessage"], + "openems_sum_state_level": device["openems_sum_state_level"] + } + if device["first_setup_protocol_date"]: + dev["first_setup_protocol_date"] = device["first_setup_protocol_date"] + + return dev + + @http.route("/openems_backend/get_edges", auth="user", type="json") + def get_edges(self, limit, page, query=None, searchParams=None): + # Get user + user_id = http.request.env.context.get("uid") + res_users = http.request.env["res.users"].sudo() + user_rec = res_users.search_read( + [("id", "=", user_id)], + ["login", "name", "groups_id", "global_role"], + )[0] + + # Get res group model + res_groups_model = http.request.env["res.groups"].sudo() + + # Get Manager and Reader group + manager_group = res_groups_model.env.ref("openems.group_openems_manager") + reader_group = res_groups_model.env.ref("openems.group_openems_reader") + + manager_group_id = manager_group["id"] + reader_group_id = reader_group["id"] + + # Get specific Device roles + device_user_role_model = http.request.env["openems.device_user_role"] + user_role_ids = device_user_role_model.search_read( + [("user_id", "=", user_id)], ["id", "role"] + ) + + domains = [] + logical_operators = [] + additional_domains = [] + if query: + logical_operators.extend(['|', '|']) + domains = [ + ("name", "ilike", query), + ("comment", "ilike", query), + ("producttype", "ilike", query)] + + if searchParams: + if searchParams.get("producttype"): + additional_domains.append( + ("producttype", "in", searchParams.get("producttype"))) + + if searchParams.get("sumState"): + sum_states = list(map(lambda s: s.lower(), searchParams.get("sumState"))) + additional_domains.append( + ("openems_sum_state_level", "in", sum_states)) + + if "isOnline" in searchParams: + additional_domains.append( + ("openems_is_connected", "=", searchParams.get("isOnline"))) + + if len(additional_domains) > 1: + for _ in range(len(additional_domains) - 1): + logical_operators.insert(0, '&') + + # insert 'and' if both are not 'None' + if query and searchParams: + logical_operators.insert(0, '&') + + domains.extend(additional_domains) + logical_operators.extend(domains) + + # Get Devices + device_model = http.request.env["openems.device"] + devices = device_model.search_read( + logical_operators, + ["id", "name", "user_role_ids", "comment", "producttype", + "lastmessage", "first_setup_protocol_date", "openems_sum_state_level"], + limit=limit, offset=(page * limit) + ) + devs = [] + for device_rec in devices: + # Set user role per group + role = "guest" + if manager_group_id in user_rec["groups_id"]: + # Manager group + role = "admin" + elif reader_group_id in user_rec["groups_id"]: + # Reader group + role = "guest" + + # Set specific user role + for device_role_id in device_rec["user_role_ids"]: + for user_role_id in user_role_ids: + if device_role_id == user_role_id["id"]: + role = user_role_id["role"] + + # Prepare result + dev = { + "id": device_rec["id"], + "name": device_rec["name"], + "comment": device_rec["comment"], + "producttype": device_rec["producttype"], + "role": role, + "lastmessage": device_rec["lastmessage"], + "openems_sum_state_level": device_rec["openems_sum_state_level"] + } + + if device_rec["first_setup_protocol_date"]: + dev["first_setup_protocol_date"] = device_rec[ + "first_setup_protocol_date" + ] + + devs.append(dev) + + return { + "devices": devs, + } diff --git a/addons/openems/controllers/setup_protocol.py b/addons/openems/controllers/setup_protocol.py new file mode 100644 index 0000000..d64b18e --- /dev/null +++ b/addons/openems/controllers/setup_protocol.py @@ -0,0 +1,142 @@ +import base64 + +from odoo import http +from odoo.http import request + + +class SetupProtocol(http.Controller): + @http.route("/openems_backend/sendSetupProtocolEmail", type="json", auth="user") + def index(self, setupProtocolId, edgeId): + setup_protocol_model = request.env["openems.setup_protocol"] + setup_protocol_record = setup_protocol_model.search_read( + [("id", "=", setupProtocolId)] + ) + if len(setup_protocol_record) != 1: + raise ValueError("Setup protocol not found for id [" + edgeId + "]") + + device_model = request.env["openems.device"] + device_rec = device_model.search_read([("name", "=", edgeId)]) + if len(device_rec) != 1: + raise ValueError("Device not found for id [" + edgeId + "]") + + name = ( + "IBN-" + + edgeId + + "-" + + setup_protocol_record[0]["create_date"].strftime("%d.%m.%Y") + + ".pdf" + ) + + data = request.env.ref( + "openems.action_openems_setup_protocol_report" + )._render_qweb_pdf([setupProtocolId]) + ibnPdf = request.env["ir.attachment"].create( + { + "res_model": "openems.device", + "res_id": device_rec[0]["id"], + "name": name, + "store_fname": name, + "datas": base64.b64encode(data[0]), + } + ) + + templates = self.getTemplates(device_rec[0]['oem'], ibnPdf) + + templates['installer'].send_mail(setupProtocolId, force_send=True) + templates['customer'].send_mail(setupProtocolId, force_send=True) + + return {} + + def getTemplates(self, oem: str, protocol): + templates = {'customer': None, 'installer': None} + + templates['customer'] = request.env.ref( + "openems.setup_protocol_email_customer") + templates['installer'] = request.env.ref( + "openems.setup_protocol_email_installer") + + logo = request.env.ref("openems.attachment_logo_openems") + + templates['customer'].attachment_ids = [ + (6, 0, [protocol.id, logo.id])] + templates['installer'].attachment_ids = [ + (6, 0, [protocol.id, logo.id])] + + return templates + + @http.route('/openems_backend/get_latest_setup_protocol', type='json', auth='user') + def get_latest_setup_protocol(self, edge_name): + # search for device + device_model = request.env['openems.device'] + device = device_model.search([('name', '=', edge_name)]) + + response = dict() + if not len(device.setup_protocol_ids) > 0: + return response + + latest_protocol = device.setup_protocol_ids[0] + + # build customer object + customer = latest_protocol.customer_id + customer_values = dict({ + "firstname": customer['firstname'], + "lastname": customer['lastname'], + "email": customer['email'], + "phone": customer['phone'], + "address": { + "street": customer['street'], + "city": customer['city'], + "zip": customer['zip'], + "country": customer['country_id']['name'] + } + }) + + # check company for customer + customer_company = customer['commercial_company_name'] + if customer_company: + customer_values.update({ + "company": { + "name": customer['commercial_company_name'] + } + }) + response.update({"customer": customer_values}) + + # check different location is available + location = latest_protocol['different_location_id'] + if location: + location_values = dict({ + "firstname": location['firstname'], + "lastname": location['lastname'], + "email": location['email'], + "phone": location['phone'], + "address": { + "street": location['street'], + "city": location['city'], + "zip": location['zip'], + "country": location['country_id']['name'] + } + }) + + # check company for different location + different_location_company = location['commercial_company_name'] + if different_location_company: + location_values.update({ + "company": { + "name": location['commercial_company_name'] + } + }) + response.update({"location": location_values}) + + # build items object + items = list() + for item in latest_protocol.item_ids: + items.append({ + "view": item['view'], + "field": item['field'], + "category": item['category'], + "name": item['name'], + "value": item['value'] + }) + response.update({"items": items}) + + return response diff --git a/addons/openems/controllers/user.py b/addons/openems/controllers/user.py new file mode 100644 index 0000000..75ec137 --- /dev/null +++ b/addons/openems/controllers/user.py @@ -0,0 +1,32 @@ +from odoo import http +from odoo.http import request + +class User(http.Controller): + @http.route("/openems_backend/sendRegistrationEmail", type="json", auth="user") + def index(self, userId, password=None, oem: str = ''): + user_model = request.env["res.users"] + user_record = user_model.search_read([("id", "=", userId)], ["partner_id"]) + if len(user_record) != 1: + raise ValueError("User not found for id [" + userId + "]") + + partner = user_record[0] + partner_id = partner.get("partner_id") + if partner_id is None: + raise ValueError("User has no partner") + + if password is None: + password = "*****" + # load template + template = self.getTemplate(oem) + # set mail values + email_values = { + 'password': password + } + # send mail + template.with_context(email_values).send_mail( + res_id=partner_id[0], force_send=True) + return {} + + def getTemplate(self, oem: str): + template = request.env.ref("openems.registration_email") + return template diff --git a/addons/openems/data/OpenEMS-Logo.jpg b/addons/openems/data/OpenEMS-Logo.jpg new file mode 100644 index 0000000000000000000000000000000000000000..13ae0fba6120a7472998decceef335398be01035 GIT binary patch literal 152320 zcmeEv1zZ$u7w;?~(%m5)(xtSkAR(Z1D4>$kodT`}g3?HrfOL0RNJxu_NQsCvsHB3y zou$$BebG<8@BZ#}l$~?_r=B@8PtLQj@^a-hfOkS#P8xtfAb>3R4_Fz*`*PgH)EEF1 z6@h~Q0PF|QAQS*9NI}3KeF)_yZ3bZlkXLaeP$&w3p8!7iW9MxOpseD+{(_j;RXci+ zzcxVypn(ptKsp8dfgfPRRr%^!)xpU4ycMmqk*S5Hk*Sd#0H^{EfDvE}oCmA`T0k14 zO#utQa`kKkfC>QB1o*KZ{P}zQ&A{Ib{LR4M4E)W&-wgc!nE{kQ06xM1P3nm1AjB{Hv|9wW?*FydGUgSgN+C` zx0OBDc|&V`BQ67LOKz9*Hr%{iJlufT5f_{D2IfW%wE9LSrdHxC?<*g$(3%>GvuFw` z@+jI!8eK4zb+a>4bvvnM;AU3N zF04ELPO@on)Xu@w-T^^=RwJ)VH?_5tjygJA05kn#KG%xBA>Xu6I&WxbYGoq9$8(5> zR^QdZ$ez~G%FxKz)XK<^*6_T;`StQ`=xrJv2XmxhWM>ag51gi5XK4Ajc-L*Vt8Cgy zTb#GQpk(T@VY|U^+Jlv1-F`!~p}Ofq(%Qn>P8F;*MiS~)2InnI_3h3(7#XgcZIfTM9ySg>4kjiZ2_8Nn5iv0_7A`3n2@x3q5it?m2?QCmK|w`F zMMWpV#>6K2_?v-W&cNhj z4oy-$cJExu`VQ;N3-5b#KBvaB^)`jQdt2U{PW#LL5F0p5v=P>J`M#OVA08{|DDWxk z%~=65qj}HQhfTkoY6Cm--#*SvbQ30)2B>Q-41ueq2MtBa3lC9gS8{R0n=l#vw%2Wj zkYkU-lhDufU(b10H|sFt11`fFYdzs)zgt>NN?8osrul0m8PMa#WPteSN6qW53(&YXNziOM^(nstkKXd@RunfuYCp8EHc*Sn-2n5p_5mD z=SzLL&a}VmZp~o7A9js#)b>aJ-dH>LgVbi{8OGmq36_fN)yW7C)YiiRY1@1R>uAWo zAJ5o^{0hlxKEO6M(-%v-&4|2-i`-*Duyq=`4g4jN`t+=?a-YmWiwoPI&a?A#Q>U~? zCTV}k*QPQWm5Ju3Hq|=5O#~#Uy9YV%r3Rkv(tvJ^;ydl|0o5njnb7ahU9w~p zmHVyZE56s3wKTt5TJ)s=_PyX=`D6x165G?FX4~sL+z6ldK}uUs7wlghAXMNf?$3)C z-5daH=#ZamHO);-eBb-aZmD=0sgK%U&3U)sYU7NadMCM6+vb-YuG#at>na`L_uSq% z!vzq`?B!G%U;odkJNkn)n}7a1Gv2*_uC(mk$!oCh6!)LJ$BA>M^7~ldY5k0an6_2w zE}fG8LGCnqtK;c2qsmVYe-Qm6KzF{Seg9l|SdSCzdp%0bPS@U7vEReH&{|Ak$xNO4sYk7>VGL`rE~_-62X%^m2ANN_Y{-U-3=19CZL zZ@Y*cf9Y1CVo{s8OM4C7`f-HIb!hTsTxrX1c6NZ$wWX%!Q)uVDzkC1yyL)-=gXTOx zN`8*0;P*tcW;5mesL|+bcT${*82Y1RHwY5Go4IV~@w?}KP=-hzHh9eQAZ0l82hq;~ zR64ShV!w`V*bgcYhSIE1U3CrU50YI0kQ=Y3uDkZu{HTni?fFhP{7&+(jG`g3$4xnh zIyG2-bcfMsGG@w8LIwR%v@1l!aWtnYJQ;y5R;o2)N4v^g6CMH~VhH0H%W>PwS?>`@ znc&mY_q|yNM7x2I@VI%$I9y9%KPvB2Ee$gnOBdxsknA6|SCM3T0ZlTI)(;58Rbw4T z7HC{)5r}pJ5na;@dm*l_k3bihrMpF7UM*&J*X3l}f19`tr?d=#GxW9|&Bk{V1PDaC zf_P(el>)vW+O1h0i~(`f$e}g$PoKSAUQ*e@enx>~*b2f?Ymwp+gc^L*?j2{3 z%k1(YN91B3yLZlkqjoSvGGMBWJU1z+YU~+8=?;*ZqVT$FQ4K!2HRrCFibM||_=avopd(K$ ztk!hiV81(q>t1gwg<;>JzsAxLC70BESon#Pz|)#fEHi&1TnhxRJ*T5Oe-gFPX|{>` zAUo|(#Jhu$lQf>3imjTggCf*NN-mjAV(D)DNupP6kUHWW_}ltzeq2LY730_wTFc1T zmTDmkuxoH1PHDwqWn;wp$faV&o>zj0obnLMS5c7p&Qavs=4AFd~-j z7KO-4rg3GJBbs2sUECWRjX2x!j}r~n<7v~jI=V2#5xGSK6g*H5v;9Pj*a!j2>0s&Q z`Z$%f@&$WM|ful-DxoqC*NBeUJyOOMqyL+OEV2HI( z!e2pAJTvOi&h#N3YXTbjXD*)d=t%g9M|i92h}xz{4nwTaqV?fP zw)ub5m9IHQibyO9`}9rk3gS3mk4}iWY~}g}u^3Rn7h%6hWAzhjlmW*JxBH*l{ef%( z$eDV!6qGkTTw#cd(&TI>XE{lLSO{+>K4CN=A(kQy858tQcuq$k7XKPbQgNszEqi(9 zCr{r&xp!u>9x>^NopK6)l)8}psRo8n4DRR&d!?p3Z-!9%t6;tDeC>F)&_l#_qD}_9 z_fw|3Zy*#?*+%#g-%IgJKq!T1gPUV!bz>ePl>QbjqkfY=-w_VGhhF;wA|K zZnmoKa!N*QdhDqA*@*XVvS5hCzlegXyi>%^E{Lt@7)!H%wlt}2|K3-*R|&D926-kI z$MkKF|F{QQa}Vx`$*ISF^b&?J8gikSQP=aYy*!AdLI%7d>^Ch%5y`-}>c*mFZ%K+9 z5KDg<-7hmSW%Gp^hR_faG%*sQ)A<65KnlK}Co}u@lU@>RA;1^Q=Claxeh0#kglL`z z-@YKWMW-&dQZ2oWAQ*hikxgBU*lgdK%HX5sy4r}Pzm7s=&rM$ZQ2aFkp(#$^OxP>c z#VG`p3x}8Y1iQKJ87M--bg<%pL*bt+E+91d7trg#)l%d$1F{I!AR$vD!DloWe-J`s z&$CzN756{?K>`O*6{f@Y8P_9j!Vp^g8;DHZ&_SJ^KjaTZs3~W4aF*Kr^$#*|k4G)* zbUNbBNmxOaGtRoApM0p1+z&A7JpRm&CJbDdLXny zt~4ePHEU{F{sW_qtx`Fjhi}+yigw+Cwoxpc{S9$Nx!aI6l2?q{h2kgOx#Fm_4{@=x zQ}Yj2{|SI0iLKl3^?Dj%X9Dl=GIBnSe;)uR+qGt#^V50S?*(u^tC0GOb|wwQ6GXz_ z$F%LO13F(iOdz~`(u)gn?=muJ*}#&`55{X$EzdONVwD+$>j~S`xzx%XJ z#E`nIrlB4|l_G3J95Kq<#5yW8*F@7iGu1}Z2Y%p8%}lqUz>bNk8~6|XaM|#}qd7Gj zlHBgPCxZB)|NZN;skTusA$uheg~-K0!_UIz>>g)C1V=l)9AMj3SVD*T3o-pFJ}*v= z@_OY?Cu|q4(@5zJPIjXlWup8DT0{i;zW|YlRelf*qZXM<`vs#Ns!H#=y_}k^fSdIH zgO?vWJZ>?Ndh*9zi*H;i#((#A5%b;abG?bfSzg_9DY5x2Jqe zQf%#)`*Vf)nJ461iY0y}QBJ+4y(VoHu%D@I$EyZXCOtE=dvZ!AhIzIN_Kc<@zFRW1 z8}CR);g0CLQT)$!z=@Wd{LfZ0ceqDVc2wWR%jq39zspd&7?GzGCG5tWu}jdS{AcTf zyK%649f&0M*-o0Qy!-v$yLt0Q#Ia!FKiVCe_vW@v7vd@6?qlyx6R*zheb;@n(OmMZ zT<7zF138~PsUxBPW{Y~iD!=bDZ{KGT+fbCAHzy^t3M*8(sz6xRbFfR z9`u%#duZ^|1Kkxs`u^1GfATJ36OB!2`(>$nq6JjL^eeLnP?obV{U?(@C1aHu&(e2T z+z!%)fDHy_b9O0U&s)ViT zqZ)-xbVN*b{JdFA=5?>k>$_MnvsR%X{c)n~oyvXF4|f^wKTu0%D2~mGqJ*xym~Q0v zsNnNB{j(8aVMiRMcVh3xni@thy98VISKSTs|DYiMVoL4OS~y!;(qq4_2hrBEd@MfD zVq3zB&=UMc1g^IyfB1zB{l+s4&)Wz7&}#{VA=g0+{EWCUBkG6^9aN*JsrHDecI^#d z`x%+Cr4;#5d)F=4IttCx|X|1?iV@ve*|u4KDg>PV^Jrm)XRTH8U8CRr}H^}?}t^2v5QQm_=Iakd~~ zJGKWj>oHbNgU(pkcGnszlsFc-dRL&^K>&$ke(IL`!om>kc35xTtlKlgKVdtz2lT%D zS!ZzSv%@n%o3p*~MF+JVAS7V4mm+I&XFrK_M)HNy-gihOJ%yd$PA=^z4?zCvoBM#Z z&<@aGX|c{+glDeeV{qMvl1Qr-}@(|2f8QwUq<_SXYQ9U8VGaj(dB)Esc15W%UB;KZF(0zp=nur@xit_4(aq#rtp8|=enu0Mi{ykO$8{+euw^P zR_U^9lRFEV(szE}w~>3a;clOZ5YgWjFA@9vogQjk-y!epJ89p+f0{Lq=Xbm{^y)je z1Pu;mp*=HOcN~dK0_PSQ+V?pl4(nQ^aog)bhhT14Ro+O?cVz^EyJw9m1-9nCBvJO> z9Up&q_^{I_$3*S__)CwSr9s6u8RoW_x7djSfRhQKXw7t7x;C87u@pE{z=vn-nt&- z=Gy_1j41%4QQi71ds!}gGrlBw(|z2d<_1aIwo9RuJjk2t+p4l#Vg4iq6&tQ2y}A_z zqe*z6NqC-EY!(Ip;2b7r%#u2m7MN;eAuaAp*@!H~_IXNp5fDD%ICjv!gvtlR9VQ!5 zM=fW>JT{*=0Q|NA_1($6Zt)-(iA8>$PGE7@4hT3VeM#dVzq(}rb$_*5lNEv`DHqC(^OQDWD+iFc?-jM+%N{;mq3cWPZGxCM9r#-J|m{e)R#Y zt`k=56RVNx?cTrmrZ)!u z`Y`g^g$rxJA^WpWIkAM;5QjZo2t7<`14kjpNF_}vGq?7$6MW7XSFd$hv)Hpwk-S*# zw;rgp8v#&KNjvQ*C02Q)UJbVg4Flj~QaSNzDt}$&XxfzJf-#!0a?#gI@x!Z%MAuZ} z>X;PIt!n^4SoOTalIOcEU{mr(32fWpcbn@=pl80=s6#Aw?`FY38nQoD{ML!6hd^lE z$OF3e^;(F-%Y%F50u0Iek|tf@n^h28QYo433Uk})!|WT1?peoAwf@nv{^$&Hj78pn zFf9+dAwoLqtjkuCyIOp(MSP&Ulo==V1UNDM$*$jRU8%GyhQjL!AX;LO|5co6`$WS%OJ_eqH@qVi#4c0BOncLU0Lke?lWqL= zmYF;NL9`x6+s4F&q@wUDxCVrz`IVxC^lnPo>RdaSK~VQYkNj54iSlf*K;FE1!|`67 zSAYC;Rowogax!-z&*_2pHC>ju_<|S;p6P7nwZlv@p+XVKAz&OUOI)Hn3s|^LP>YW8j z-c+)6-JwNIi48J~`_!-LNDH8!ec#Db{(5Tj*Eb~UFX)!((ZJweTRZ*$C91<~$QT{m zsrRWOQSF7$E5)tRDA1~9*CtMU9J)u>u<2Gra5zgW_9K?zCIZpceb*H-*=}2ilf{=e z((gCYFAD&ql?%=9CYOe9Z0Py;KL2?BQ|VIx(x`p%{>4{*IwPD5qc`7<6?a5z=l}rr z^>NdJuT`(NkiDTWj#0{(Qe;dg>~xRm7tvzPesS^K1`K}d@qprazu~?OVC@VEp6JNG zcbo~j6W#-^xT8>e=}hZ)Q(s7Ts3JFe?%}Ng8FDVw9W^J7sEwuP^`a2OyHUgpT%w2W zLD6=&1iy?m&hchJ{NWCioz0`xQ?n4d1)iSh-k(@7S-lMcg+>MY70HHm7*`FgwRd|)_sL``^emPnY>$b=tKLtOy*7qj!%+&} z+}C#0{V!A@007^{TIf5Hu)?;Al$Gkd;9R+|1%MQqo-nj(A^U#SHa+9Y^3?nO@uAzG z9X5ZI!8nFKn*G7?tJ;=V@?IQMqkAq}07yZuzMk+=b57U-AB=V8iwkl)HAA;-!%^*11EZ@9RhO9P$RRWa`Y3{{~ZH+wAs1+q)hsrDK7dsXAiUWVaX7OlL zdHviw=tc;XQ43+FQmPGh{Y)nEEyC~kl}!{}?|A7M98K48mv$4|Qv&sV*24Sf^1RU= z*m@j@_9+i+#dp)^R(a$rmi~o#<-!STQX8MHS9SwQdeAi%0N%GzUmjcpELAv{eU#YP%Z52bm`TS!&`$hbXl8G)F zt7Vo-mex4 zV$fEBJUYE`jhNXlEpX*dU3&1}D>AYdA^M%-fG$VaT9Mf~ea1~cuZ{VTuPI3Ax5C?t zgSyoQgstb`Do7L`TXjy4H^XVLwE*vm#Jt)^(Y!VOzwwE2jO~;GVQOCTS}@d)(&--) z(^nZDsf(-$AcZQok3Vh|*?(KmAE|Qf2?4Mc0vLOiGfRb5MgN@-ylR^T@O`73;M>)B z5ZZ#bVSSn~ID_|Adv%8`#F>yEzAgsbR$i!2g+xl{Ll|DwuYsmwrNEv(hRuPW!#mN;w)B*8H2$;l!wtOB+^FFa3AuaX3qG;*=i zXa8HB+G#<2u| z<1rRJuT0La)-@d=vZMp-23aFIkz__V57#h9gRtV+F7Wa&!Ydb=xXcS*i2d3xV*Mff zZvjYwk8Kvf-H5g^l`uedT4=b7c)fs|?ojd^zba*j3IOQ3@2bJqDD(wye*bqAZhHL< z0xau?h2t5bGgPtrA-ypc){622J14%NQ#R~Nqg=dwy|8qT_KZ`Ok7x^q{^pBV?4tTaB@m7WCSp-t-hu-SjnMBj{#z``a-shV zr~1r`7Uhd4EI%-t)Hh*pC7XLq?P=spWf3#=)Kq?p&S|1{AK>vfY(0PH)sAyt|1)I$O zia-h+B-n_JQC;xAX^S@suy#fxi-K+-S>*~FWMqFtHl5KgN*>TS_1aa|8YUq!$VfjtApnMI|}r-6n``DHv@k&@c&*0Fp2aHk0ZH~ z-_ZTv53km<%fmWHRg^(5g9iu`qFWVqXtmnX{@;;!yoLY>y%1Oy2$T47 zK>1!BRQPjqtS^*CtX0ifxBwwC1J$UbREp8u2`+5{FoZ$(J&0K9xky_EN?A|bEzXa# z!%KF56Vd(b{2cJyxSv*K%Wti zJ>EVSr^~v4a=AK!ay+K zKH&pADIy(H{OvQekaK>{oPLCEwhV;$_Bm9ynp1*Sw;;TcNuiff1Ij|H$!ng2n}6_y zZz<;`x>7S9G{D9nwTmLxih=>F_bwo<{qX7xYQKtvt$bGqjhfFg$B8#k0P^s|t$G!a zmb7?PDVR{)zKHJBOnO)FlHR!R*}i03h&dSer>^e@KM=`=4w|!4G0W=YYVe5eT`~Hj zsj8E*Q7~IE%`g!hmUiY=v5FhYP>fWL04bK|AMVKlILsLlvr@%8oCVy7m*o87L{?l zliSV?-8MwUMQIheb)O?d3IK>tjz@evBy10$m@T>Ble`8Okl%R1C}|i0o{$54c>Dy9 zYudp_#&DUEkW&^gUkZp#TlOP#S-o}F8AgffJJMoI=Mwd*4^N$<1$g!^wQ#E_xXDme z5erQ-E=Ms!BuAySmXEQtf2rX;?LwygfTGXe49YpUDr;2T)~zL6i?1F1XmpqO`YgzxQYBJd?6D?`fBeZsxj&bP?MbMlU#{3?DI$Mh!|DR3X;9X9l!@Cjsu zym0Zi^`lt#w~ES1r1$`~GG4>c;vqP4dzOb)#}LUU_5o3H|L_b%$4fD=KLk({ zB}|*o6OOBP1qlL=8Ailv2`A^C;f(}>Emg2VgN%TOm`_78O z~1HAHpSnm?-Zo=johEb{d#EuEF zIOqqlp`wrp@Q;^Hiro}iD&`yakvb&+a4~WD^o?|R3&6l~?$N>Oieoz`#~uDm%nr;u zM9TeDBi+;a$jL8uS+F~=BkPr;Q}ib4X#of>#;AXoS8w>enZ^W)3WL#E^m&ImPXIu% z({qF^W5q@i0M!caPoRr$oQq@u$X#YJp3C#)e6oS7-GX&U5r9GC<<%w&z&i#74-ubc zMq9B*yd(1-WVZ_H{g?%NB(BwI($b*CI0eHyMPwhmh)&suEH_XwRd7t_JZYNhT%YVw z5Z`qGrb~x%i4NZS_g;g%?U~87DUUA2YC{V_ds_Ob7Q*q4NX# zKiGL*qr_o^ymqZ$?Hu3^(Fk>$-M@)9Tam4{t#IhiAOGGf^z(hx0DCXw>TZL(=S$iy z)~N%X9S4pCo;+cY2bL%F@qkZL4Q#b<5HE|J21i1sasgPh9$X5+j6Z7y0P}hG`7oV< zIhulcu5-u_=lq|YN>7BsFApN+;;;W{(ZNUw&h5>iH0w|w-p(o!3RY_XY`9u(<@-MF zXjn*Ags%1ooA;TxiJB9;l=~vsV+y+0x785N>%>WcCICPt7ZAChrtjn;*n0~k*L&ef zgfq(#09|tjM3omPm}h7~9SDX@D_cOSvhX#S5JPjpbAFn4b=E4t=JQ=BkX$#nI$A{w zXBHF@Um#S2fo6MiKt|C6Xc+RAFOi>xf!oztn$hd;N>qz85CGfjIFk2ezIruD$ELnd zEh_u&MJ&DYJ#bXDFcAvigu1#(KIavGh>XrVM~B?&^Qs+e2SX!1RHHq6+dvQfaj45X zKfwausR95SZ5zrygHi1T9MW+Rqd6brFyXNR5Guhn_U6F8$U9d>Qywv20uE;YoWd4+ zn&Z%As#u?$7mZ915Y<6ev+S}EdWsgybPmUM;#9`)go3UQfI*>R@EBEjzM5HTXG_n< zJ9rKEZbR@|OaI(M+NVkuei6rl=6nstpPxKW3o@J484IPp`SI9{!0J%%E%}WK@g{OR zP+_l**8%auf>|=>?{yTn$Dg`@rVW!$6A*r3;p%}7);A>YD<;&^77cEREP=o{{b-z` zJN~?&CycQscA>hu)(iP40nCR_i(9J z=zZvN2>B>20B9$TGS(-Dj0?p<;YxdRAQAGuX1nnP?z}DTi^3a5V6|eO1NjUOqKhOf z5ddDO`%**=2#}&xsFs2A5G;=RWGXlKx1HY@M0riSnnGk zPZ<;RI1nhNeKsdYA=AzplL3Wm?a?6P1)+3y(&c>0vUEU z`Z^@?Ygtxnz#d&HfQqG7#|1z_!cH?MfJ+1Lk-KrPcqF+U6fjn}Vg`nVJi=dcfZ~kH z(q9BQOcbriqFFEv%;cof$7vxow~}svI+Dyr9ZI%5s^l-%oE$9~0ojK-(bgPDPvj z>ImY0T$+vWkec=m8f$Srs~daSv~EQEd;Xh&zZv+Ofxj8}n}NR>*vJ6xN)2!b4_q@x zLfVgtf(#%b!#9;ckdRSOfqiI7_ymNsJcpn*ctj+mFk(8vbG&>4jQsQr4+B?vfc+2% z06|4s0fuyh8za~b_Jt-7Q|LBiPT-hN;9MwZJ?0~1lRTm%&O9hsc`Y&dL}<9x2^E{? zrq0ZFg6sqr(1^4(nUY7bh(Ze;S$&D2(@0JDNac~jX`_5sAIU9`tEgU;eUeaWP2%oL zl=WJr;3V;#XJQ0Y4L4mwf&+E@(Yw2HPdvR@CVF)y*dc@H*30X(OQh5#+RqfnO)Io# zn`YW|rdu0kbVCZQ`fg{O$S`_778s<9aqK)3t2eT@d5we0?326ljadZPsd+qDjca$u+G>%}=VQevX>1+s9c{!0ifELu66I zP1!OL%#=ChvB8XD)eDE8`e8_nbQxtag*M$V3Q_su@tpq_%fd zB%OVSTrkUSaoRDR!$IN2Iqc&+WTFxR6WRi%&Ig4LpP?w}PBluo{mk=TWichDHe;WY zYscH3j?{_rCv@shQ;m{|dc>ZbK0!@!)J}-oSWPLNxGyj6nu9;IRx$d1V}v90ah8P- zlR{9`iQ9V3qQMMqx{vxO=^;-U50zhJ{m_$brxDCzDJ#TqWl>QbBZ#_@Tqn|}ILb*y z$$_sSSnWw{Or+*iNa7PG4!FwjWk{ zFu$l`@TJ>;O+1ze`sk%efm_iL+s45MZQXL`Rsf%{LU-dt-&&p6tHQAB7wOrD+aW6e zX+iMOyJ0&04ZYNvi6SiLG#=^8>#9g8;bF??1eGR9OecJcJN$RyIw7_5_M@7mt-%i3KU?lwJUUerQ%pX7}y z?4Yb`<%>CC{^Z=IJ52TP%kh+BtoxV?F&F>Kv2_ zZXQ1OIzG4D2D?LDlEZ!6SJZ?$E=b1A%jq~OgP;wL>Q_gj6F#ImtwgOu%H4Om2UA(6 zNLrt2Jz@2|s}-Le^YB=u9oMPYQW>i}kE?~V7tB-R1nfBd!DK9Vj9xS_3A!;6QnU}7 zw&D!2eI3^#GwusR8k4jXcGhE;F?+}b1byP_E5DwfyXRy7vPMw8hXEj?V#wDN*MDzy zwo|u!-*`l|y~zzm_Jb;y<$HvQ4*85G^Q0KJLaHyNXQj~}4bn2&SeW<0a4>=*}T z>aun-3j6ii>d1L}4@l3QRLeySlNKFJN5H{*{8Y@eV!WVrshUK8mK}^M(wB*9S-dsv zTkzKx2__FIsynf-cw`4!W|4np5!LtfAGWcIyrv*Lf6pWEn#iO!g8JH}~ zY^y;W`A7T~C(wFJFc~rNrD_>QTc|9Ea3752#!O?!<6XJ)R2KhK2{)ysPtuV9+hvAP zQToxTXbbt?!_!43%MO?_lnyJvQEjE;{4r{W+#i*cTFSgX*=vCtPoI`(M~0*G#kAM2 zB63dSvpwtrPEQ(C=_WmEyoCOcvBlTVe&ow+81-^IvazK$FfPeJS&O9*zjXdC_9;UA zXTswcEc}KLB&XqC%W|11;R!Pg89At0WVg2(Rd%VWIMAU;2^OO?+v##VpKXDJ)7QF~ zuOYf82gFR{3v7$H?8ZH=TxxZ1NwuL7=xn=TtI)uT5ptO4@=?d*M*J@k!L6 zi58JND*Kj)s{HEhl139bMk9r*b_vui%6w_+J-))d#6>uIOCBntvWNJdM;Xc9YddgH z$mkdafBc(h&XQA{>QDu5o|x_?C$$4s<2f%gReZ?lS}C*hl@1@*N5xFOQZ?(qhmxD7 z`Fvm1(qtQ(p6%&5v#v;us_NoWm6Aq{mkY(>=268hr$@5yOj_Kv49%{%JwlW#knLJ) z-kPcBdSdzV%n0vC-0ZlxtWO?S4bMMi2) zgF-JJgro!+r1&baI=f1pNIUqnVNsdcOC?w;9nIyo#c@-OdietMLn1{XDon2&Pvf6Z z&VM$gZ`qp7_|)fPwsf*esF}lOylB;QxgvUx_sZo&cge|$m zLB^$N1srhV-`7AVl*z8+!A^dmF2|M8r;}Ew`T9CNVqTh=fd-TxoqG;|!8(VA~1cCl)I`*AP(Kf9moviVH0vg5-YWiI+dq zon{r#5YT7{g9*6f9~d1riz(%PG%+Ui>xIc65z%Fl6jeLUZ!aa#%5<`WZOUWVD-M`3 z6oWd-iL9#M(hNdFoog{fL(=c7qASwOQ>T6qc$`6iE7ns*FRBzOQ%gaA{m6K|T6+6H zDC@h>BiI!qR+)~CgWQ*c-@A;9ia3N^VP979z0IRO7UliE&d+uDHtuEXepfXVNACo= zK_9s+^-I#cFj(dU{xfkD$$RM%C;>h36?5|QP`?U`?+s$<^Guiud5vx^+NN?q8L z70|fO4K6~vEw8*5k$g>%+Rbc$-V#V(9>~Xj+io~jh*=Zox`i*VW#%cE>cI)YCpT>A zqD4?=Yr_sQX&Z1@_~PqgxFbcWYPU)wC!DV8F*-?w1l*~WG_(lq7WsrSt(X~eJE_Iu zPE!ID>%7q0?9iS&A0Q2jvWC;tZ(C!gz+siJfbc^17a&|BljBbGJ&T}@*vks^=Nn$P zec0zPusj=PRdOe=Ob3symF18!mZfGqz=FL3RI;)9953`M7g-=exlxdqKN~S;cJC8} zM?`N}HiI=5>~kEG7E`SbjW$O6XRH7KW4(M|cC??*a@RY%hu=JbBP)Qh)}y+o_s-ld zLBBChmCwEW`P z>K0VC^sv5FzQ(Fz(Jo&zj(wC{5YTP2!8>(hQ)&qo7Gc4HS`$kZG7Kc#Z9E?NLs4;FUogC$=Udn)b$0|%= znV`?dq(t@BLYk;lEdgbQ7gyl}7{RqJqt0XW6jjb+S6ZC$4kh+;1TDn4z)Xn#tIgaC39c#drD|Mn`QXj9U{L}slXn_oE zif1v4IfGQBPVvIyr!83m$syM-cz)T}a_j9|T4udFbK*DNhgK_}RIGL&H0$ajN@~tA zQ*X?4obg-4_C#tf?NntuO30PSMvSr?1n`KN4hMwRm(Fo{A`3&Q=%i+;yBz2a(MP>_%)AVfxRj!OcCBZ4Dp?53lg)<~2c z+Vr8f4N!rOefQOIFY~n=YB0RjvveI0*msn^L(NXsD{Ax;DRWyBdl2(cr7>FUXHOJ> zb54C{*nD)^)dKxOglgil6;zOxV_;dI4nwJW$%*Vn>&F9_5lH}k|SIV9P=#~eGO;* z7JU}7ddPdy8P()INWDeH_!?MrL_=jVvO*N4z!sZ!`~cSjjecYyo8Yy+jXB=nXN;-7?Li{83_JiY<7mR%!Iq_c}9=mmp6Epc()vN$ckRZ`R zt6Q}%P(xm3KBo@~6JN3JE-nc?-JHs zs?eX`m)3rVBII>b4*Jdwyd>Wh;OT@q=Zd_n28-305!P z`L|rAK&w{W7wC#F4Pl*0l2nhUIV!G6rGY+KHWVRvv)+WrD4o&QM}kO1KRVB$R{CnK zF$KlUD{$QJTZ`?hi*)CX9zAyJ>!~+S1_sYx)uMiUIbEtbsLb*~+fxankAnp!sfqUA z{P8@-laGcb2Onhmq*H0wNBsQ6ji(=?{KNV&!+^Wg{EU{f%tlx}VuWLTIJZA>8r-&5 z)MD%!j82=6RgLI8V`G4u)0W5!yiPVVPLj?zO=3<`RZ)cXLXbdEIZ-;W=okb!QLR^C z1&Bj-@+~LHXG{9f-+cNcTeDks>0oE4#2Jo~B#*Zg8E;QN4iaI7NDemLDAG*Dze!gS zbtR}>iS!hQ`%rUP-_hV4(<%|u_7kYM-Z>2IwkPR2Pu@~y{Uj~+@&Nm7*R-=l^e^2V}0gJ zd#)i?_5#rxO|2(2w6R3Mof!^EMSOzP(|oGTXh?YJ-nG=kNwn>!B{*#|Lvu~wzT%cny3C>aga4ko`( z&&0Db&+fqC@agd!8q7^c6;JOyNs;PNJg_))xnK z>Pk|Z;?I7GR{UU0ttNikE7$0JX1A8vq6Wpi@0d(y9QtYR;hB4`C-S~cQtFv9Kzynx zYBMXxr!tW*F@y&n4e!iv1zTe>@;A71bylQDu5Y<>J$ zq7R5*PN#xAo#T z;5T#bpro-FOc$tCXXp+V57>7!l94PeBKhvQkd|bL$*vnbl6{%h7uuh3E8j^C7f`c_ zCge=6@5eO0N|+s#Qd))CBd3ye60f88$|0WmnoLvPkH@-m9XO-FQ}PUbpO&^leFK>g zvdTvVwf%Vy&M|i3qN*QcbasapI_W1G9bZw1hOl%?!ElB+!p*QTc7<@QNA5Q1X;qHlM+M z|FDY$+4;8)5=~Pj&tMN`KENaExg&Z>@l>=68uXFAKp%Ow==k-Q5!RwQ6eWS4MM*u6 zyH@~VW1UacmZogp9T@NMB^h0?PDOeP<~!w8M0qW2-I)xQ8L}W#H>A;@&HFff6AGu*WAQ!L&c@!CN`2ZZdZkXJ(}F z(SatbH@Tu6GMV{@(XijEo_U7)ss^)&Q`WIdxv`JL|HZkHnu-R;$M0IcQ9gXu>PPzU zMwtEnZ(U`0<##?>e^X4k^!ClGs=G=9H_8)~%IV%3boqK**L3b2l5}&@-OpMcX*6p1 zA*y{=5h-6aj_2_5JM6P^7>B*k%aEZqIho>qJ=e31WO|HnmJOWWPPC2Orygp#edS14 zf32SLhtjO>GZ6+n%J~?*nAt@bv3@|H+aZk5f^%wUFV(F@nTEY_rX9ZUwAz?(T0YjG zZ^at!P*%1wjz4zpt+`t7OO4Mq^A^OQg;&d!yB`+&ZB@$z8VuhW^c@$^;*Sv!d`4M# z$?F4~)X0@;IoD%(kIIZ+hf($3XtyXMc-kGPHiTo@MQro>*}34c*n-Zhb5|N&DoeK> zqBQFoZ2gv`(a6V*x#&#DJlDQx3}zDLyw7fUNs`b{C`W{GqV}ZA!-2^%!JApA+5J}u z9`+bY06$)4Cg1*2;=0ZXOT1SO{f8|_8Ki0S^W;8+NgZaU`6|LHBl`lYI*6>`J+^@q z8%`s*_%V}Hee8&x^@mqvqE?5M%bmUQqlo;H&B#C0$$M?9xEYi)LdJFqoWm&#els@Xs&ZM~0LYEKN(NnJgb?+NG z<6GQC>!aCGE^$`+R=wAfX+1Nfl@Zpun8kR;$kl6vo;|6R7&nCP~) zCRU2yC?D@Dm%l`=(sMcvZ_+g)wrK?jG3B@ra-91j6Z@-%6CVpy?oEZ}!kKd3OqzF0 z1C;mNW^YS+GE~1SC8(g&Empr7!&mw30RaucGgc{{G859WyLtZ4UZ&6prMHn$eswGhL5i4|jQ*dYnJ1lxlo4z=$~4tt)=`er`( zN~~LpVac*jeblX5!tS;HdtnXYxw;YN*(29*xWWhy3=nAEXUuh%)B6;BZ-(jOn-d>v zZrkd&o7{2d=?!*fUIDNNuj<@=aI-IV(9-VRFuX3tVJjYtFX(WbD(b(;d04MWu?x;r zy;Q$?0XvC&{lXralT33~C=r_XKFcSNRgj6w*PmVvnPlz~?-b}KI4oaJEIb4@ryriz zrW1;Beb8e%O@+gBk%D;Yf@c05y?Rv6%M+mmF7jdz{V6lrEyQcolft<@Y%6CSch=$; z_;caNq^@;&xp9Yi4+niJvuqFz0iW?lIVuCS?@oRwDR;J80p9kQd^^cG*{F{FDS-Id z!SS;s`P152td*YObT^!>Q|LkzW!SYA^EtJ2n^zx?D%;G8HWP<@r%ny7yo%T4mFD*& z`j-wCF6DZ=%o&{v7%sKdjGf%S)O7h~)sU8E8)ZcFlW*vCqH6K79%p~@UnxwWW+)Vlu8GbKMK7-gW)U2wxw_#LE=EAfZ*SmxEbzmc{2Qw#QfW)?4d0$I; z72Yt1U7vWNM6lX0$D7-~*w2tP=}heUDlZ_WjI6R%{kr@6a-XVz!Sl11XyDaHu<^{N zdkwEhy13qfT`~CfqM;V-W$!$|FEguYK4Qx_^6GJmb41 zA-KD{L$Gk}80A?uA&X+cxVs)`z~+8Ebn1mG97=k@8vyH5I5fv(=?*P zkUrpj!#xaSSh;G(5&*vKZEm--*(Wt$e@$#>t~Ofhdg4ik4&uoFjMB*eC>B@0vh1Gu zw7Ys>4V*oZ@j2C1NJ&~-UuS5=^9pyPGc*`B0UvqeQr0wRV~MP&(=<+cvZ{4a)o6UO zs_CoKG>YbuLBKJ&^O_l9&7UN!t36$`wNT2bBe23+^Z)o9;P^Ag`S=JUpScMpM+Dw7p15@<10<;MIE+h0d^VsH8 zqTaHQQrSQI^RUrIJY%~>^2`5k+YkJY)V6CUA4J~mSxsvDxYg#G$n#rqX-#8^6_rjp z%+GPvvT+`d7vW~ZuP->r+gStx3VovqhWrv3h|F(* z&Xn7jhH&=3_-goa4 zDCJcZE)&1#@q6%_gdZ}3EQJ<45sWA}c={o-mqP{|^?mR`$_x0iG^zmJYn`k|7+BMY zx)K_MrCyr&5=CxFFT0&a^NY~g7AZzj>$;d-mDc&l)Dwwq#kIUD1E9b>ofDsIMUiv& z&t|IWPZzkgpEa97RWBPDzX46H$lUs9nDadpBR>fm*E&|S=1cl|cll7pg&gP54wmWR z4x&Cy>^=tR)_$L9zY>0*Tzy=A(FfGQN?7_TjA0%(0`^Wa7@_RmMg`xB8JtxO`aQb= zC$^sTaqMT}8jof5?+TfH^l|7R8a$G{P@|!e)nfh60oX}VyQ?Ud~Q zQu$v6lK&5RORP~|XPdbA5dk#LqlE-1hh>^@XJQ_?5$UyXwr4wv4sJ~2j2|^hpVU=d zhVex<-`D*|R_+!v+;*6f@%y^}tu*B!YmB*Wr5f|Ou7o)E78&ti9k54u)_8dhY$#kO zOc(d<`u9ID(8xU}CJZbzRu7K^3;Q1Czmaxl8dlvk)MBnhHl(ULw=+b1A;jmCY5Zo)dS7!o@CI>q&arcVeWL-x ze_U_M;8jsQz$y?eRNvYMz0fjyM%Kga+}?1Pvk8L)C`dyC%X!gsMg!&3K5_IKMD- z(fxB_v^mg3ct=iHA_o>dcP>tj^m@!9eD5wo5&b1YmNM4)b{!~gRkp>Jvq($+V{}=H zA(%iXC=s0)JRle7ad)1Nd?r*E`+@RuS#28{K1CQMw&doLrWy6-4U4Q-_6E%{N@RJk&+=IkrKpT~D=lu&4)cJzGHD;2H-z*qh&j-6a1>6R0*Y zo|TWgH%P!a%y%f|Vuj0s6kRtBT=JF#V&>R8;1bK>U&RRGq*IG_Ds1VPf?#FU)pp8i zYe=Udu0C|6M)N=tihp2Q5x5=mezJxc)&Y||Fst@dWh+$>9-O}~ufnc;CM z@-x9dr~;Ss>cfC`U?d$o&|W{EcB1VPJ*DnI>L-f9wd4R}t?A-ErZ&G5*%eBwz5IXC z%fTkL({->j&D738|G=RqO#b~f1)(5z!B7*Ow>CTWj~;fY(e!w0gy6q$FJC$zBY%?v~N z=u5AH<+!KG_a)V-k%Gx=tZ4V&%p2Q=Z8xukA5DG3UTn?Rat4rbr%G2H#5W@W8=%RH zatHt%7XakJMZlNY0X=`=e9cVmBa-KOqSTYhC<@6J^oA$o3LR7Jt&IlXz3M!vP@D3^ zdmyOp43_kzHASxlL;#b{N_TY!Li70BqeoO7oJzCWPJDS(ur6NiFbKZ9sF#YHme&33 zqR!_P^Ps=lOz^uw75Rqkn9JOt7Pl|q%^JcRsgVN!_viTZZP)DhsbGOH_c~FZL(4?S zAlEF<6q}xX+g-f#>?NO#6}Aay>>7GjKtxB84x%1?+c%G!S_6%H&D7KNwE~c<4^o5A zAA`()3yF}?hW|d9;jyAk#Ne?RtP+A%bLmXOrWLQm{py|)E3S=?A7tRkP>_EM9z zLUA5mg$RU{x^xD4gIQ^uCsM>KRbb)_o$`@*L_vS)fc@(t9A>^vDn@9J=QW0JpTiG6 zQ>>z|TwPgSH`NZ&{mgfC^yUu!T5J++`Z#7y}3I=B@o06F-Ibp)L+ds&X zp93b(oq!MTyaloMoIS=r5eO-?ovHR)h?c{=Gp!nbTFX{3-Q=*hb{x$n9Y0%tKq}zi z4q*re60Tjw^NWW1);MLkB(c?%nX?o5d1L&nE#1Ye3jG=G`^zat_0!WFiOZBMlkHSq z-SZY47&(+2AD8|(BDtbuJzvmYxW=ePClehSuAE&R z;t{0hnTp zY7QNGvC{!mOPV&62KKjd%Q3nINxV3f_=fhkGArl>;y|^u)3Y9_3EBOX!xYuAxTT9{ z1Pak{KP;qMa89lYi<@a%N}9LRmZ(^U$oQWR(1tB~Cl%WDBW2^=n2p6b;-!iEB=aXr z9#QcKk#YN*k>%KRlJ+KT21j~gzLv$qShjJI?_sgG0xvD%Zi)jFzgQ^a2A#wLS-78e zhaGwCr)h0K28}ync-&N>lKw`LERyDJCYGp7wn=4mi!hy|(SqzCe_J;&V68pSuoJuH z7paR&mto(~6SN(iwuw7KO$HjDc1PU+c67JUX6lN#g(axj26+Ya4raL$k$gru!})<> zV4Pv^rIV&Q@eRd(RwmQX9^dPHSKw~e@~VcNJmU?xSQ1M=&TW$@Xg{lz+S@)D;WW^= z0M!QR@?a8GQ0eT)rZ%R9rS{1GA>Lnj=-$SDr12p3jVA%B^$u9n=8LXs5&P#;qd=X{$x9^zU*xWhGJJKca&Y7Q87W@1wH_<;>mzC_E3WnMcIsIN zEL0-SW_Q}C9;*jL7;ELvu)3-np^I-!7XB>Wue2dnkGwH5qC4KvCzML%Sx=3U=|{Qo4-QhQ&LBj49qFug&FzS zj?p?21s)Hy_vw1xyq5xC$jrlZz&+*Wdj7sF%Rl>dn!ClSIEVm2zp;%mmN`qJI|WdbIhJGNEARP$@l{hIxI70tE27c1>Mth?J9YHwZocm5gnO#(rUujM zt+jYX3NH0D(u`9qB%H!;d=Ig^nwlLj2p57lU~sOXz`nxk5o&5dgPQJ}JEGxb3&r)_`{298qSpN>m=5?+<|0K_f+Ixea>ru}D_}nJQ2sul zL1Y;TOwSv8vFy(<60A3w{H3lzu4V02uYSWJWzZiOnIl45yyZ{2tC3QpT!;6h0hD(D zwB4~}zsJ&)gEynWA8!RyaK_(6wxkLFUr(5apcgJ6v|#doVDNVflVnsV<+_GZp`t-I zYL%#q~y0gmGs&epl5JzdGI0NP&aqf@u@h@95@<&rE(ebv8! ze2BhWdnH;NA)3f14%0CVHZM|JY}0Sn9jq0>n;ZQ@Ne84}cs#g- zU+f(j9#%iCZRRpDIvKM>a2d^mhrQeNHd$Iv&LU3O@t#o~F~5hFJ>OwSvI zN_TAOF+SE_Ho%wo9vlWEtlCncZziyRTveBz&g#_U`{udJtI_m@d5Q-2A$iy0y9r2$ zC2L>$n{4S-H^_;6lNvj1?P|50pSAY)FrsN0+s3hCRNIg@+r?&i3~p?6zldh@FR}7v zr6Z!q82$p84Z7{P#e2MiP+Z|7al#jGmTh=!zmo76#Z@$DSi%pV(#eib>Vf-@)Kgw) zlzM*k_R!?hX08L{n&nJ-U}T0BlcQJ5-lV9H=C63CDFGho37yXALTpfR)@?Q$5eO$b z(?qUc#Hx8n9N(6OgM>nllL(C;Kd%E8sb%^gvB5Y{D*_y$jmE-dTlgyd9VZ82D0i4@va16Xj55pP=7;0}JrwDgs72~$F@N+g@gMtu z0Y(HoLY!aUkftepL!XIf9-^O*1U^93?h0y6yt@tAwE!B0Nw+(B82AbVD>J^r#=~3W z(EI9p^I+EZO+r;6Q}=SWgueEo=yUIGU_VL97J4QhD*v@XP%7qG78WJMYNsIG;vblHw2zNf-J}AX z*2E~SgHRnCm2;bKsnm@;6XU8ANg`?Eb|3&GbvbdY`3IRp$cU2yrFcpj@ zSjH5l7j8~xx^ZZ_6=o~$%s4+(IFGV`_Sz%BCyEL@Jq-o!{T%+sG&<{>{Z-u{L9}N3 zSI-qG6)h2}9OY4(KO{8diNECpMBSsHCXp+cgokRlV=-C7yQIJF?kwMF`bP0sE?j%F zzUJG3*KK4pCpyWib<1tO#tuod!!f`p(WP+UTO-qtm)L7A(S&2wffbNog$HN3PqYXf zx{^@k%d@QBy5F&jyr1TEWj5W>+4OGMjo;i-uu-H^_?Pwi@XohHg~Tpt0BBB5@L8iX z=-XQ!HI~U!1xiPBcnkg7AI9bP@n`pVr$T+GJu%-0_3Q9s{@sEB50CgB9_FuW=ieO} zFmRYyP`8dMHk-I}06fM=3XZ>?9Tyx*PDyp#?(bJ|@z?))cVPeH-6?J~t>=lLQM5J?s*88NeXMK*uoEV!V9V8jE;r!T>2r*bbaf&jfU$}MYx2e z7x5goUJOL%l=sD$JY$*OUVCFoK2fZYF6j69Vp*fKTQ1b|6E*vUb0KT{SF5G&`r>6%{vhZek2yDM#Iytko^bgDhahk`b+Gf*E22Y%s zu_bG47cH3=Tck9wk*`92q><-T7vCO2q&3!xm7AwF_TF7kXojtmB+FwQKuMecES|Sz zXSwnNhS5YRi8dQ~S;p~)OdFOgb=IOyj#L#Zj}lz@fXBm#CbHYv zkdoqC+jBfO> zpgexHH{J)4SL^%#2-Fymegm5^rU#&J+bsHn_E8DZW{t z$^ZHX2AIgoSNvMhi8HQM6X9%IeWGoN`CCv%V?OESV0a--c%*0DTj(~c(1a%LY^>CvyezG+&k_nZzv93 zBt`0Kx72M&ILXQe&s8f-7FX%4YNe(#8&-bA$Wy!3ORq5gWLHmLKkxU%vI8nC(N0Zg z${;4EqSN%9w6fcb$G4lH>4o)XXNyEDwVSzxPm~O%7MCbE;M6cspY02P&aqB;YWJ7;tks4M%Z@bLrW2 zzNS+&OU#-|3G}xQ4o_{v1Tu)|aC6#2vx5t(#3^8MbNA+Mn5q{$8<^P}c(j7ilO_}w zAEqluC}vYSe)94}g5J2x^uVN2rZ?eb8U8EWWn6lWov&ct2z(bJ?xa)o2An^QuNih` zL-F{hvQmw3KVSoc5)&t;LQY*9aG_ZVR^}E=CHO=7@lu-FUalT@AR_uj>SCU3Df1ip zus+I5xMadCXaolIedM_K!O`EN*48WBvoAl4EKcaimYc0H6;Mz$#tU(F^#`?q7FP}B zBLI1*tt3kRLOU}nAO;fW)(RQJB*$LnuQ$GZ6K4w=)jZp_+QB@vJ0SEJy5NX3znz=T zm0j5tCK{L$I$EM~Pz>QII#BB&I4)1^`e*7x=&19e1vnp+tr~9-#TT6s;jwJ}U^QC% zI5!KOX=ZsqKsZ<*VdBL{=?721=Aj)7|G?Z=K-Zb$r+>3zDk1SvYDKY5vd~oRi-r=f zQ4oaywPFWyytp#11LdQYTUU4@K43tV13k?O1S}cao{W?6!*c4x{#ph|q*Q>$XQ)+B zBhPEe^NUnH&95WlxQ1)nRtqBpK2mb$)66Y;MYJ@Quin;J8(&1!~_#2() z<_&HC5+GDEm1p1 zawUw#={1?Yu>YZoE?BShIU^&>Un{5brq{G8qq@&T;xEBUKCtB0C^d&<`}4kr1lfsnavTdYu)-9xLM}2Y??vBNxWXd)wUoq&`7$wb*WIuW4F#(ZmRbqZ!`ss|wSQRhL&n z>tZ>tlZL`exLSGO9v9#aAg~bOipQ<LoB6I3%^=n{t+zGT;(e z0jie&kPi%z&c6jq+1rZi<%VVeZu#XOIhfG824V0Gu6KF;k*Bc>{7P6!4G11XFNcM7 zKJ3kq$WtFW4*6I@mPt*mD`6Qvh&77+Yo8-TqUc92P6#dLEmfX;w}fRZz5&7LfSC#PdfNaxmQ8VXP;~9Zp3=WKRCI)OG3kd!FQ*O zRUSf5phXLwKNh8uDRighW+MW6rJ)B!!J?6U)F{I!NpcRCt2s51&_EB>_#Hx5x+1(i zkMuVmH*7EoQi8AXHl?W*8>nuz8LxZyarb-S3fpeTyuMB}OR0nj@nmY@G1<@v@$2(#r*6`Ga(HFFb2H6v1tnI^h~} zG6^<{>4@Dlp~;9l zHJ6JIQ-sD7rmCz*06Qc(wLm*NcO0eyB#GXu*(8a-r5cCOwSmx^#oWf~*K_<(u@cn) zZBE4Q1C^Bc`lHuVdw5bfcZedbKdo1#Y)^F<B7M&4r51DiqZ@__&4(id4^4|>rVbMZh>TIK$d!_l zfQ)s;Tz0@$v9+XQ#WuU$nBd*-b-GlgbH^MsF?a7*5GN6m0MM5Xy3C~)hb;!?H)s?o z5DH}nSgTyx+Ng<_2A48vTCck!kIP!q}^cgrfjZ;9wFS}~>%qvC5a1ywajp_5{S7$~{1 zu&h+gG1dY|8$Os8e$KuLu9zct1u?#p{UXtb$!I?rradIP!HIdfFnc* zVkYrk1CgakFbsU(SANz%;nxZbGxRAg+E^+P>Lymq6(lD!K&Emsi~4eF>JVcUG2vXH zGHnnN3muiDQfQ)u(?R+&%b5^IdH!)q2A5I}Di}Bq(gnPnBgV^8q!O=1*q!^l%Ty{> zc50Y*F_y3-l8y~QuFrLyrKuYM4FI5o1&;Od2F8d#^n_EZ~rv zg9RuIN_L*N?oO0IMGdoIoZ)n}tsj25gXf4u%baUirQQsc@V-1Dd%9+`TN=d{H^E6< znEkxNdjd5hNS#~T^l}+&KPV*y#{`s22j056;r=OdDkeoOxr9rw^Htv*N^+itdyK1J zsiGlt7XnNA@w3~U&4xOv0oTbK0}j+6Hc@+!$vHi3!J#Y#dWh)|&Pf&H5aZFP;E@QA zF;jUyk-ni);U&#M<=YDTq%6e`#@|Pn4-bww2R%hQ)Q7O`)#k1Krc7`DK^$DQbDom4 z0YsqY0Ygv)dK|CAqEnMb%1uk+u5K=z!^3|SwQu2ag-$n!sfZ<>&mkgsq!%@Qp&-ft zO^Q&rhIUAkW;6V3q3PtwV99|{lfwqFya0tp`Ud~nk#^sL;=-`HQ?bIS!?@cYcWKy@QRZ*rCI_f5nQ#o2^Ve&TY4=`rEILls2J>;Y zHCU+~Y@Qph?i{xtu}|<{B}%f`O0*A45BG_do1cydy~`PG_>N`8otOVAa@1+uK~ifg z{}s)KuR1VCBny3|^lajCc{8x`(QsT#wp^3+3T9_ZZB7v(Sx2-qr2hORx+gjNl3c&rf?P6k?CI@i%?r;SrAglP% zxS>tuFVcjlvzoWjKsm6Cjh8zC*Wid2J_&%H;XgLv)Q_q`QYVXY8xW6?Ry>ldghNaa ziGx63B8oUjidG`oE^v7_Uua{VD~gNWiif_7G^n`fp{(465Cs6jeV8s@DY*b3$eX<2 zP6h9EJm%b@9PV2_jF$D~(U}MTfEmJ;naaa> z>DIMuu4al?%RyhQrUG{=i}5WuGEjYhE|9+<=^6}q6CBYQu&#}x@oKXA4s<0P!Sq(6 zrlIfYU+&m;ZC!Y@&})m)%#46*1Wabx3>Jr&UdEhrPiB!|@7-S|(E2)pEC}~<4?QfOSlbN65L-im_vdUtBeGZo5-ci@e+LGuc zNl;PYvWny_);A4rX>3q8*YVu6xSpK1`XyB2Ks%2Bd0MiWul~#o_3rk>>1V>YprT7~G0oBuoVbt5>3i;utnJg|vcBas8!q}Jwc~7im zr5__>-Za(n;)r(RDDu-0sOApSJ&`1^mg=)3jQ~raiHctHLdg?QA4eO@1Q+F>lI-7OI2SI$?_X3Q8*2qyu<7;mXTtVgs&&2ci_kr=G;cSIp@1T9 zH;Df32oe}j5k*bTOXXgo@*?dXfu9GxplghWr98Dpx2OEf>U1l0wu18G;{>ioO!G*C z=(h?rI>9SaLOAO)^jjrS7cvV)mTMrVs(w7u#thht7h(g3UKP-?#5>lPpS2 zyBpz2O@BGMW9{?(+G2(9_$Vz51(_7VOyGyMO`UFy$fHxNCu;X58PZVu1)}#*FNcg+ zjmr`0L6{$^>cIc&dK~;OrZ8E|Z5;mZtnN#`M`_tRf5Azy|Di}gnMAZf{6O$NFS`5x z6h|i*E1on?G7o)K)UT6Uo|(RsR6hKDG`^Cgw=E=xWJni(ne~4!GJ?@q$7fG#LZ^3f!wjiJHKYZCrNUN^M45(TC=5P=B#D2F$y6aPJY&Q4ta0{&g6?gN1qj zufG_cf(D>L*Kk>1HFR$%A6WCOn*gjzd*7XGM;UA z?FT|!NHJ;_um|U{I%(R!AZ9L!3yF8mHLsM_9u5-zSrSqTk({(G5|{iMNT{HNG2>2$ zda#g@r0IEIu^6fs4O%Dp<;SdklsUR}^R$)yd3|D20DMk&NmE?iVFmT1ZrBRr4EloP zkkhul3QUCCDR2t>*%^kWe)>JLSW&~iwerW5c`bgjxKl61v}Q&;-eC+_^1ZiVoU=}U zd}PIgA#S`lVKBu4iyI2Z__NjzLPuMLkl~rBqIk z%wm7_40|=TRqE+psZ2xED&0yV#{?zp_8DK=eT2dgbz&?fX-R%tew_CFxs-AlP?1;N z6$|H zxJsmm;^Tl(JH9CGf;YpOI{vYd>f$-?HIr;Y^AGMEGui`>F2}x`xv}%#kWdj)mv*#k z`x>Ikn$&PAS$Sg+-(NA@J@FGt{~^doKz+n1EciIUa;cU>FgzJ^*Me*OS}#mR0L*Wj ze?^B??={{pZkULl?GS|2ZtR;#W>UnW@nDT#A*e{_6$2#-YVjSYwGtdNCvM`y~Em z_t}w1DEtn;fUfNLT$~jjTt-xos;9cZjVECXu6N=wZKkzt@tS!6g8~O29X~N~x=RG! zIF^0%v7Ndb8>cJn$%?917Fw4V0Yg6`JDOiNqB^@H(Q1oI(|^9=;f z97b~fu=nT)uQ!lr$6M}?R_HO*tL>;yH}%+E-J^ID$$R#mQCvM~*X?=B?Z0vutGt6- z2((>{b>pj66}5#xGwWNs{5Rb<6&F1#kjtB8Ets~vB14Q`U+xgD6LZt`QIW1R^yG7A~kU~<Ykhy<$NoeP*CSad69VPU=I$-G z^3(uAUPBQf@@568WndM!elMP=4q3NQWTmhH`ji{^bT3+<$cK|&pydC0)Jzq=D?XuuSg8g*t34+z>aoGCZ(fE zTw_rz8T^VFXlMr>*EAN3HWnKT3SjoLg{=Z+|0>TO9vw5B2cakuW9&_~IS4CZfM%`B z_(OBQ-G?3mUn+fFDrZafP$99I`H3BB%wS)!Lg!e73^VVWw-;}TO^k?0Tq0$YSzId? zKrtJdNg+O_=`}(nrj^N!R69`;m@s_o4mZ$OY-aXX>QQJu)7FmknxZ;r?1oR0RfUu$ zeXNI~er71@%0nC9?&eDMb6zTqzE_>)QzmE6KG(M8GcDZy1e4qTvt4gLpU5ocB*&lk z!5j-u4XnqJ2gDyWq|yeBk%6Je1ZGx)MboKe)#H-E3^on;V>5iTOt$7ZtQy8>j+pfM zr>z%u3YuDW|URqABbIAwIg zlvmZ%=;s;x6Q5$+&(c(hh-#*Ea@qyAcs1nJC_b*#v63=i+waoU`}&INvCwpI+Rezs zXu;|~j#TE5l~UW<&$~A!?%17NmlxL?f_$r?OP%w+D1?{mC|F-7jBwi>+0zcrYyAUr zTj>*C5jptj+9!Ov(HdLFXP)4($6@kT%V$Mn)|m2yT2R{oRkMJ@odL8+q)pc-?a!fi$ng*c# zmtWB}!5Kv={inM$9oY7k163i#Q$4n|&!NX3-Y9DpeF+OF(;kz3EoPLC7We!oOwd(( zYmk=uGe%Z8w65%Dcev&(2xTk$itPnuDvRXKB7F zF)HOHK$iR@-1CAfyqX|07Bfc2*Y5=yxUDKz4dnS48)D}^md?RD6lH!j7jWa2ZeMn_ z7%2o#H_;F<4w>E~qJ@-Ko|i>rs0g^uCHfYpbFS*^^_ZBH3M@`HGgMmHRZS!p7tkcw zDX*nLICOI6aH8xhoD{in=iK(?^ouiMHVg`4>P}E(uo#B1v}|pI*pqD9j)#$q%}H_y869FryK2L3xWM=_Zw~9cVpqcTL+tzaNNZ7%QXY)d z*4kDX^^}cH&)?g%-=uTf-1fqe|7yOdkVDd3Ms3psSiEspt`K|M%ov2du{n5y13j9+ z^L|$v56FZym9UCvDN5lX=ZL0ONL)!QhFO85T#Ea1K%26~URk8UC~yxpe=bJeV~AB1 zyB$HH5T8!3`J{({d3ikV1ooCjb}Or+s3d2u@iHsXhDdr1I*NrdvRPFTH(W;YB&K>K z`kG$jt&}|vVxdXir^8;f1qL&df;{t>c8wK8aCa6m{xa^uH$9Qp~T-t$#SrHa7Gv!yR52yQ2^=X$fv zj4$l=vYH63CLg`~w3uuw?CJGFD-=yu$U9X17?l!c^zaAP(drimo0oo!h{{Aa9t*e|z_%BwTl_E*XsqNq#wiFyLn zex}D=v6I1$=3t zEXWn2ow?lTo**kYLEHBTHN=s3<_(ne66VusU3tza%^2_D)zNt9c_NzbcY6`6sv~}a z&t~SS-&J^tZB*#RH4uDG3I{YO@gZ(kDiQ$ua)`8pfiGN*ni~Cte=H4rRX%9tsD8fF zEsv4UPx+t(wv%qEfY~dIh12#Ep9_kPQ2L~m0IQ+L%;Yt>Mz0l83T7uxl-*|OQVn=C zFWrlf?-K=de7XhFYZXw2Z_zZIU==d-j!IM!5Gk4Ph!tkCUk`72NjLh0*oOD2XiMF| z|3pzz3SEmVp))T2r8+A2!tKj}FAJ#^8~#Luq5xzH#o!-`M8-8W3(@BQrd3i} zeM${xvL$jwd(jE4@RKagfshdg86(^C6DbitAu5|(#i{}L-%k?2(2@#8sXH*Kx`3YL zU$|cVK9v=m{pxeF4eehZO5p0T^J%)rwBqRbfc1V(wn*Z0lRFXG8jQXk-9&OR?S2R<2ANuZ+*u{3$EI$mA-Kn<(@nEGm8(4uKETZ?qS{R9%@<0k?i7|%3Xye! zBzt{HAVu{csm1utF|S=|J!cou-($OSiMg`>wE#lTFqr&fqDp@50BT>_Fqt>oPmAsH zXUH`Z{5s*Mpuw+NcYJQD$4s-|0~7kAF}r%z)ly94LN3qs%cZ%w;Xa_N-CPgvO3#UH zW>29F3QV>e-A3moTN9}=dsaWMM0^UkCog0*wzgx$5|pzW=Lvk~KJ;~6!D*(omDSc| zzPENek&`md;Z*rRRFz+3tv%&^NaDSj$rIGmAzUE!u32H-CsB4`Zq08nzV!5H1-rle zemhMEg7galn{7A6(H$(?A^z$Tc@|`B-7y~AG@`I;Ii*EF-29#g&{RLKQ zxIhfD9U5{HGP(($#?-xiD_51aZ(Jne_3QbX{#lkV@^Gu(gjM8zgK8{ZP3& z_Y4_<68Bt394O4A>?#n~MSirHpr(1;wxeZuFOXq(5wUqMnJ|Mh>t5zWUo&Nysh3M4 zEF?dosbSD}Wu|0VgP}R=Q!dz3gK6yMR4!$c?^e{75%@d0lBB=zd$?3FBLQ)nGuKf1 zAWh-bRQ6Z>x?+-tI4sh#=KPqe;TayTgt+*Qe_)zXcz5P(g+ncds5yWox1t>)PeSXoL*w-+}A#s_{+1GuoOs?ag^iudS_>#@iEF0b1yuy3>) zyRIw4N!g!CigVjBYw$38Cm8g}m&kIbqrjnE2Leisc!;jQHlA)WW?bPJ8~7@{>{Vm4 z%8Gmbe?V+(=!T01`nuA{_bs`x`A;a#v0#(7M>k*`s1Rn~>hz-y#pQ4W2-eKo7SmXb zF7RTFsOC6Rd`|WU@O9w`$dw0fe=&dvPxucqZwTZPXKfL_+}X`z0-rE0umekjbXL6g{-sR#^#&(jKd&*tUnQ^?{Rck8}qmcs4!U;|f(OE(8&(GleZ&N$jp zExavwsh!Qw->4ywlb6x>-2bB8{o|qPJLb6oEaggLJpInsKi~(ir4s168rO&+RZHOz zx>gpAm)2~*jlp;lh*c_pvJV8iKO1!Jc0P+Lc&>SF${ahs#Jn8+VcvAv^dl>3yAZrA_%8}(49f3o7&!+2 zTpQ@OV&{y$NtbM-p9E6Kr4!eHhno` zaaEuoLs&kIXGe{bBa{|~*sXjTtFN^hB868f3Ze3n^cX6D`6KOw6;1DJTk&$ce_Ano z#CMCR-Qn?vz)v69`40~12U2sWfD}?c_|pvz^rf;oSlE;itqz6dwd*H%HIzT@^evZX zN)nNRPbzX(Hlq;%eEF96bg!yIkD&R|w!w(~2oXZIN+LRpBt?d=ya3`Zxo$5dsAgHJ z{t7@BqaItc(GYfi;v#KTlbCVAnB?k{yJLSAi1F6DN=2*1=<4v-`7QHgL;ayjo&$i6 ze0jFkrU1Eq$87t`_^ZJ;L{JA4%aUA+o<>IENaF4I%4CCVx14pyguE|lr8!i*)Xye; z`N2L_F`YGUBk#6IJ2`ip1Q!WhfP5@5hnJr!spCF7e!Trk1YLx^<^616F;oZr{kg8| zv}=Ucgz_a9LWGmZUX3%bj^v3S$x3chqa$+loDvJHg?T63 z8*zQ*Vvz?#M7pDI5biIC)k<}wZV2ERZMX~SNU^M|JNi+OZ^r>pPq=^O>to{aE6|Xf z)?ZO_^mic`a=~Cu2j*L^O?h44a&)E={y*$}1ymJX_ctn_NOwp`gCGb9C@Bq60@5WR zed$gGq>=6tK@e%AQ>8_uq`SL2{Vu2odQtRwc-H@0>s^fFnRE8p`?ur7%$zxQ`7ZlJ z(M_>NdO3A$iH?Wk=1Ic7L$g=O(d@{Zb#aYtFySMM1=|IY?>1_{WxlZZU``6fU{#Gw z#_A~%a&h+}q@zO_Tbk_tH(<5%R7TczvYg4d%*rLLJ zI6VF;{<$d*cU39W7Cosb9?PvKG3PN2*AdTq#|T{8d0=m>JiPpb12M|pzs zQih8dzHe6z)*HTlowi7$OPye3K_y=ai{3)ouhD1>F4cN^i*_sfY5}+zL*yXRBac#x z5o~P$@z&@$Wb5UcTR|ziif{$IJP8{<=lbmJ+f1NfylJ*a#rQREP*KFmwHHazHtmS) zap!dIiH^4_Ita*YWQ%8p=GeNm4FpA_z)wl=_yE^)D>L0PD~R+jT%lrrQMl<+V9rWD zULR{(fY|=(>9XRE6Niqgb>dyQ%TNM-etB|2*mpmJ?U=0cH|!GY7nzwx)l`)g8^Tde zjm96L-WHt?}!@T9h&Bq;9Vw+UQ@StCThp?y&$q?Sr zYv(iAZXPGQdw)%E5qs^lPke(lI{V_Icp11+~k~iDk17c<`{WBZuCq+{+>_~%{yi^m!2qG%hOj1+tI+N zWKwRqN=mRKF3vKzF_BLV(_fB*ugQ|aiqy)3kW}Ex#8rxKP-P7li;okM9*yNhEG;ly z)82=KpvAl))hztpmCf=+TQ?%a4ATBd{NU8yPF^!o%O^o@L4|MF0D$XPCiG;NXLa^4 zS12=8kB_=!irho+(KoZ&X>rF)Y{#h~aKbrWC;~WAdXN{SiOy44t=q_w5YGt7W%l0_ z7(?BWTN^E6GY(A4>PEcyafG3QV;iBp{d$*eB{?fk;M#Bng%IA3#n=l22-;p&4)aAw z5C2#hCg_4GX(KOT`8r`c3ALpC!P4i3nQpssQ%GwpL=9mw*RZQap?3PZAO}G2KRS%2ctK@X1!xMIdm5#Km{W1s@F%~ zRetbcjHgeUohlX^ZPta#7!qiyueefJ-gfTN=)Dw?5WlWD-R%ER_2T+e8$Q*mi>92} zuC7eNYH^E=mj(PEhhB$80e4y#uxchv@)^OkP2^eau=UM*I~F))4LYhTR0l)2=!_t~-nj+ZGiftD;$oZ>eKVcCihKfeR z!&mJM_5cMS(7r4`8n+EMKhDBC#r3>0l-uF-7L|MF%xrf43pIF;4b;1PHJz6E_~{h zgzs&dyobd|!^RWv&&4g|NmuVM)UIM`-;J2o6Os*hlgfOylcu=9Pfsygd-tbM&gfU4 zrlM!)`YWk0S=vGjX=cnfDwdkQx+YK|Kj8-*X-eitTFy&s{u#^;y~*#|^U?R(WUn{I z*HZct4I?>9i`{va5<(vs!RYKTnIV4fO^bc<=d#-`mnvL?SYm04uyVWlf(udI%_b4S zIiUiznSbnh78vkj%YHSBB|AsvD`f#Qh#kEm__L zbQJ4N?aAekm5H7*dga@ns+Zu|B%UufhkS}svCX=vul&4l6Eb0Hi3v)^{qZ?Yvs8x{ zMN=2LsDV@0J2pIf!SgTSwaS`%SI^C&182L>Sf2ysTYS3MuRNid7R?I(T$w7Mk`P?u zg7m?BZ@(wc!BZ?J(dC)p$7pd^XfvgAo3Lfn$Q}|maxuY#c_pGu;ycs0m4K=In(LJT z|3aUG2A31f<+`C)1ZS|o7X;7fzk8$&>gi+iO^4#Q%KWMBt{xtSCP*ku z;mKKc-8&H)qD2k?dbR5YOMo!8**)Rcq`hVJMM3R%Tf_8;H$5fHLuisdgQ=LUVA4jh znJ0=$i2G&|V7As5ikj9CD=}NYmQS;5kcMmjRS&{6BHfx&JR%l*u3~wFDI&4LXB#

`b%zWJVoybJJC+al7(vmUoDSw-d(zU?;>j| zJmmOH&(*62Q)-(RW5}DVCIzQNGD>B!7^#~SZJi{{tZ**kKA37xD~qE}=7jd;lX_ve zdMQvjU$!EphbMS;NH8z0l}CUc#kbbY+a{qzFuUlYrNf%->}roVHIi2O1+QW0!B;** z7E8ow4NDGe%|ds%oh6>djbAQ|Z@TwHoNFC9BrrhwO|q-J?=q7T>2n|bC$+K}JcTj9 zIcNL5jLMSDr%&3f!r)q31YaNN-0D8^U?H&SHuz5I#~`uKhtbO65a9%Tn=B#g4uE9Iu!^u1fbMP1_vPGWo=&+_=}^z-KUT1*V>j zm|k|W?eZN{q(ypi5|v2qqHV^H&5JDDqH=af>oYyiilq^d9~Mg?)rvJ1(y*7<;_No< z$$go?9P}t^@frvSJ`-4%l;!1G)U zSEbA{(KT{Hk!)C1JcN8aWffLP=$e=RZgW($5s5e&QG6I;SuCP4?ln^GOAv@TOO3Yw5N{~9ZMcaI5#yg6s!*bi}w$@ z{1yZF4{fbMncPe}azh8Nq|W5@j+nr4e@*_g0UzhKov~b2jP4iy>uXOJlCL zSb_!TsVZ)cyr?65jaX5*zwS8GD`nC%=pDUVWe-ZLLOm=?21bRqiLiw@cM6#CJi#l- zm|O(HReA>+Za2ii!YzooDVy8UkqwO@VRt2_H^+1i+hmCb4Z?+Qt{`l_|1>!T)0`cK zAWJnDPulFzZ>*I(*ZHZvint+qIwN?#bsKe!(LTL{I_zzh#QA zdPfjwdgBdRF|R&NSFPpjUGr5)ZE+zt$`EN)9MKoRk713-qi<#eHFG^TViVvllz%wD zI*OB;wZOLYw5`(;&x%i1uNb~KE+<#%VxL&ory#Qdws2u{5uAw* zIVERxPGr0g()eMa?W{=jvs!)`KZvNe@0cm%ymf;3G3%IIEm*HNpGRgXmoURA5+)A0 zOxtj6wdOiOpqo?#1z8ir4n4Y9OQwL1ixqzKs-rlR*h{d+k3r6^+5#bHB}h3$&Lx~E z0g+-C7IafK;wN?Gv!7@Z1a4KOirsj>g<_QQ61v*e)}B)P4HbU>Jbux$4e91j_x*!3 zmx}xBErmE z+zY*a9o_Kf=4xgDu8-E$%^520*kmzd87@4<##`%ko;EtT4P!P#8tf5FCD(BJB#r}{ zv4A`Cw5r1r-keWOkL5=`I%x;2%QRh0hXd}26cNg37Z>;%zy}VJE_{_y{st)Hipl_M zCyw_`g_@gq#P9e9KHY)Bbjf*9QC{d~QDFV(*{8t=DuW?~#*^ezZAm;FToo_XY$qsE zJ@8d}xd@FX&k+tLi?An%;wnF^hUYlHb!44TS5XM0!(vlMH!8&3 z#0+M~^fa!RqEAuEbZ0A`FcX zRRdhZxd2=#dIJFrxSas_c_?t;CXm42Z`|Kn01=;tLrld8;p&ZhhL8PX7w$aDeEXnj zaqx|A#$-dGpG9d(Bd=#ntYuy=n~dEC)4{o6kSA1mRgFd#fx+&RCnM zS~~m34Lu20AQY{~^0_hkdIcA_el$g^@BX{sxrHaP(QZaru(tRyJ;J=yE;_g7A>;8c zaUwV-4GiL@ag!tEyU*0rvOE$Q4RIBEQ#_y=bbFDV2dg#%Gbcj7h7-XV9}fTRvq{75 zbC=4{ol?@(!`6nHjAut1hF%6;4BWj0r6jwd_k6+I4&qhvQcZ4}VTgV*>wJ?QHRK|u zl|B>xWgrKjxPy~paUThNAYdIxehv{FSPbE~WEiC)K9J4{v&H)s zw7TII+d)x9-du=XypRl?jLR4Mp+kH1X2S@?KoJc?zkg{ee)dR57^5a0Cy{Mu(IQj%eD^C=oYBW)+!40`8F>pba zCQA;qcxcyW<E@jlXzb!B-w$p(vsRCI7{K9 z^62x?9z8DE1bjCBVpNm-qHxqa*)(2sfK+mfqjz1pl-m5rEepmva#zRK%mMw+j~M&A zIi0V1yAt1{Hr`rNEL*ZotMiOBIl;o7vqb7BCTHQ?-TOc}L&5yZ74WT#xaNSHbkFmwq9WX#>>{*|+jJsFT z6HrpUu^=5nxUSf*u}q5!uF%u|NQga@4pGGx&!Sb|zyZQ)!oGL#rv1xuIlA7uH!wrF zB5_eyv=j&N-|ZSLNDcdQyz-%UwPc0Ss!hEFCrfchxxwTfCBrht6@~5U$BB*!hP`F1 z!+zFAwPl$OOsZ(DuU07a^y*7&sx`%9UKXQjUPy0Q?bDAnrdz@!mPy&&oA}PE9}0+iumgR`W(N_F&gC z((Qgh7%6oN0Q-n=<7cpE15=gjeYpI~EI1FR6sYS^lS)=@@t?;<= z+QG}X9`A3`RHfifml=&Cvz99l!@L-wuC^cZtpelsd`C9S7x4TyP2o#eP-A}Ff!-*+ zHD`$V+wk27KM_t-UPFB;TudI)g}Igmcj9Ptov0mzQ#sptG8OCep)R+#56aO_;Rj9x zmsg!7zVSl@N=PaR>$rOikRIfdV- zJj5AU6MWtKZ8?5_eKYXOb^a_RWXYlJU3bfk1vN>D<17{QE36&=+=O-c-&MeFnQgPt)r8&a13H(^Uld_f2Hq0+$n|VEAY(JvVgAhdM}R zG|XDFPG$b98Pf#3ezGO~Ph>1&>-uLsE{0(NH>!bgxS?7t1TjJN8LT`~3A+^ah1gKE zQ*`k1seFWgNr5#UEmx|NeNd?SgOFvZ+o|mB6xjXr8h0?1_MjT33%~{cTC~pWfMSH}WzqwB3daEwLxoha^YC`7v5S^eprj(T)pqjtgUX z-18kao)eY*=E@K;WkZ6MBhckla&dz(+@}d^sHVO5XbKs5t!`zXM9O zig_n$`-uqdvy4T|(4cyost7(;dz;*e?fUR}yvcrdC2BRWQrPE<#JqST7}BuY%ZQAY zX-k3y0u^eRnC<;K+6itl#X@M0srb1SqJ2tNIvRW*dv&Zky+z0Bn9oMFobaM^kJyMN zV*;40%@;dV_Q44DjrJR8XE-a75%GD@*^6AjV!`cQijs7`nybKE;OjX5!jB@DGUYOn zJ9n{!fB=bb^zJhL>jA7+SyK$b`k3LoZngnf#!HCLwA%TWsd;QWK7)RJgBZolC1}}V zC#&=tUFjRU&uo|>T0ev7DBIQq&1X1nq+;naUXyR9+Kim0%*0uT5p9IREP&06D5(vP z^m@P3rr8jBvtJBZ^Jwvcf>pw5AMpM`5u<)8YSZ! z7MRG5M{b)TzQsDl;|NM7?gN}AW8g0Bh#URhwNq-!JGj2gR_R)?lfHHgIheEYnHf@0f+Fi%$w2^sJF^id&Ih7D7F zsc~@Hp}EEF%i>i53Zfgny#42VU({5^`LK`34roznIPkJhap)qFLaY&b7XUZ%R93Z= zaj4l%?}#aMAgZjhXR8P!-Z7@vwT{J+GyD@Re`qq6ntroxGJ(-!=w1$w?c5e_psHQ# z=fZj|YN~Pl>Klb_w`-g1-VYT!RjXMD;4*J9iQ(icJSr{k$Ax9IffGgd?*z1Iv@*n8 zcxaAs1<%X_ap0RZe~|ObOXyb+JPj;}QBZn#vhHFMH=%duGe$D~Q1vuCAuNVFNpUe3 zu0GVG6ZKYCU%$98lQaN)o$h!;2-XQuY%&vCcEK#8V&e*HX*p)fQW;KGc^INGOu04K zFGc>)+nY+9FSHEz>MB;o?Y^?8w(BLc`y|d;u);(&{@glu}MQ5Oi1BReNQKd{Lri(0~H zi?In$EI=Z-Uj@diSEgk$H09DxH5c1wuy;Gpwkg!8U+|1iNj zrsxc;6-_zDm~;=*xz-#?j8y=0LDPcEyx$z#VAZ_DXh>cM?nNtVV$V5x&2lj`$hO_i zv=D!ddXyCZTKN3bPJz)q&l!jav-vX50t}Z(8;_?5>nFzfM1KNDL2Kzq=L`4`$`2Gc ztm;HYWiTKYEckB0MZi%fq!)<21C%;EU`}f*ib79EJRvklnb4oL(dH%3*{x{KZf~D+ z?wSim><{a4^RKAYyO|Zf&P23HK1ZE#X&#<$yO+G$*v2F0iS-I7XUk_As?irEMiXyu zgFVbI2llTYrv%i6LX#i*&Ryg}TEDWoByS;^us4SH04B229=KYe%_%Wq%#hk3P2IZ~ z>67l#L#pZFjdk>ni=oYHik)8aJ8XrLJ)gnSW-Ng}bBfo|9ZxCP?xUu> z*}AUOT#OH1=MwP8pD%F{Rt;6YbCSpD*?=v5!$xXhL`>lq*_2R_R*5R>!UlO9GH|q~ zr>eWISqr7{XxnFiVH-?fb?4Ra5|1n@qgI8`G7lPe5zz!EZ-9cZ;GCbEckNClIi0o{ zp6ukuYbZXFKI|_!bC+Z?y|ZeKr{A%%0JqMzx{OYipCc1k2hr$gwV<4^Z13^Ghx8e5 z#V1|99w^lEjcqWOv9+xU4LH3rNEquF#*SOLrWj41KDoAK71P*p!Rc+9g*pcSMlXNV z5$$-Ml_i)~{SiI%Zq5ejYONHJR9*F&oIY#f^fW@N7{0JJCUGYXIWp6Q@{8e9MGW-F zf&RxQ6EM_SQ>|I<_>uyx__h23S}VAKb{7pb zvetBUs@pPK*yv^hN0E<2k7Eip+Q&B7KrOopqkd)CrT1!U7pfRPm5sNi==6&aNWEDd z?k2v$*UhM?7`g6utOr~k8!2>qgDnJuuJ>*rf0jn232UpUC~<51+;FF8@+-<7@5=6i zsko24o=JJ+Y!S}H+f%opGcWvqScqt{YB6_WI-xb!hK zt=hEV6ZNAF0w8byymKT9#U;yfZAJube0XZZzki&3?feIXiWnCAS85yByuy;+vtgmH ztGD2jYxC`hS>5!DT6y3GpZ`op^>som+|LKW&<#20DtmrZ@|=^ALV^M$m~!05^@VD+Bf@9y zkM#&LR1&hVKeHTO)sstc<77?GU=RXMlj>KqqPF=+IF&fqa@udJP23~GtzyvVSJo&9 z3WZPLLY8D@ym8SYjeuZD4c2z=Wz0OfWPUPAcJbmIjjnDjUfTl(ykrhLNA;T-a*H{u zFW>HT@WK>Nu=i;W(PW~Wqtod%u;_T`XX`BLl=zAMeppa|34)z9alRKG{6pZdBb zNrfJRHQG@&A-K2kRW|oH`Z8V{wFg{BbgYF4wvZ-7;z#xeGtLXE#B&clJz2dd%eRL2 zkXJC=5>1-j7ao+pL*`M?FcmdX337?)H+&$4`}pN>gZ`*mMY0vXsKrxu70S0>EE*;6 z&Dk(gw~(9z1&NM#2?s$8;|bNZh-YkUXra1&S>rr!D?Ok``(qYH0ocQiQoSxQ121 z`?lOkg;0B-%_pDOmX}k^f(mb7L5Xk<=7~ue!8V+R!F7B4k|{y774&o?d)5!nbmHio z4bp94^el5x@rjXIW;l>|Us=O?yH8`q$cs6I^bE2O1+khg=*T zxW&|I2U(edoxP=q7EL-K_^4fajU|NczU*hPJAo}?sd!DZ;)%gT-?|oSr)E#|F)rZ*@_wY&(|c1yyX? zAvd~w@JFPU)K;i;?ZhQv))`^(YO?2BL2k8&SivJN11v?vKJ4Dv3Jo`(sB|@7QmCuQ zlV4pEa>XaCr(F*PJ_KxY@oJgfoGWv9mif%_n*+U;$nx?A3*mEl+1Bh4?n_!zXSo9rr|O-KMD0%cVCHh>3U) zITm8LXLA6>VU`=cj<0PAz!Bq!S8Rne%N|02|cBF|((DAy! z<_~(%RF7s>u}xIdT`KVl-JG$FfvQDZl{?xPQ2`Hn8OszA^{ivSNjE==;_H>x%W7jY z!gIV{QEM+MF4eS9(W@OzSK^sYR(De%*?7)*sh0Y6aFS-DW~>m$DqWNg?L7Yx(cg^s z)uX`QB;;;bVdZ9$Tyl$;@RbmdqkcV2{XSSsRm2ni&fL3fA!{RtD~gJp@}>;(rY~eE z&^O-c;HN2bAc;LFZH&jP$eA);rFvTrNnprl&-BgpKL|l^riAcU_FdANHV{{-hVVnZ zIbJ3~icY`w^da8}zE#Qyq%4jg^$fp`hOh-QhFsE1X8gO|O%O#E)UgPD{<3xnm$@SMZF*6K*Nh!C`Wcb_K*{epTYAxCydt8PSxxyJ;+Ysdj0kpJMIO=~tobGU!)Y zX5F73rTh#ww(=FQ=w~nu23|(9JvHNp)h}ObRFbtk3T3!Wo!4#h-tR-zHX+(Tl6MRV zT_trsy~Nu!(FfIl2m|Rh8EvdY*i>$1jJZYiqnlABOj zttCi(_yL9()S@9p_3b`dV`QF~S!PPp{Q3fBpNy_cw6fAF?mV_Sk3BZ18H7hnDf-ME zZ_a0(Z#xdSoC`QRF?A?p@7>Sgg{-cF;;v6%xq{3V*+XP0C)93?4ja7}7lR?`(USBI(pHPy5ki{ zhg{@ZaK7A)tfN!jlPY@C7PdblhQfY`^WzY3cc;y=i7!X6g7TV6k)kX-@g|I7N^`A& z?2<-xUZ{7V_R4);Ar_e3^5T4N#oamOpe6;dTGb-7C??a%mP8@$QiUKW-WHS=os!Ow z#NqXo2UIqatFl|H@8~F_#ZpN%pSg{qjk4JW^vCtDKJhXuPen&t5R_`hHgu=oo=r;= zgZ0*1H7bL~J^yh;ef2`PLVsE7a-v8m>+Z}Y5@_Mhx0E3f{2vL)>-9THQ6Ix44=IlB zgj{JrH5h({-Z#e}l^@@|G|8LSXne!ATB9y3B%_%yydp*Ptw^;~uUg{W5Cwp_`9^k# z1McXiA|Cqd+>PB`SPU=Rm;8p>2?cH%S4DTX86vP2W-@pw;{mnf8!6g+F|YC|{X5}j zQa^BWT2Z&mg#N)|FamD=$gz}$?t4?%N#o2#Bb*9VxkL7N>&gYAt*)hU3Z2!H&t zJxNdY=Awtew21b`G{Z-qOAQ8zoVm`a-DFS6^a2(;wRNgY8Aqf)1y!2T1ba@b=5NvH z6nDhmHPI|cu=3Pem^RdX@uK(Rjw?#b0B%ELfb8@Y%K3+R{^1lbU3@WG)qeBqS8YT~ z;b)}YC?F&~yPMLWx+dlVRqwd@qZt1rm2W#-uXN`=S1Hbhmj9OFYLxdEW$Qy<19qLb*Kj}e?@5+Lk2q93=LF1UU)@}GH$UWHs@`p zXN4GvwC5^Em#P#QEC6WqSmb!&BwTtSj72~$ui`_&79<(_0Svo5@tW=yhH0v3>|ha6U3f6V?}$r0AvahL4{oH7CLxnor zi8h68HpUtPx|=b-Xypgg>XWEBQfup`aco@HJ(RTyc5dB_6yA@OF4iyU3%} ztLGv`XzcLZfLr~m-8Q`Gqf=<4RrQggZ>X0oZ72XyyA}BT4ZvLYIekqeQg7aK`LMbO za6{SRsS!8h<-N3qKzpAcdmoQ7NX#W@ESigL76aO%>>OE7OFx5Yk4xFX(_O^vC{C>P zDsge;u*R2H532KgQv9$s0O`r7_Q)kftHg0X@OwiJWDo7xr?0=l8fN35!^{pCfnb@x z$pE2(R8QaJlb_Q>;`5QsSt+@vj3RDm&AcD4EN+k?TtMcc&2kA<1=A?4un6q^&5*|e zeN6KxQ&T-M;t;oTiEAoi;%>Clo7zh$c|P#^kj0&?NCEt~Sw{PM`rY7?=;v2c;d0)N zRh0ps4A@w6QPqz51oSpD)xF%3C_;=0znL$S>=vsUPU$a4ReCQLn^3gof!m!pu5}bU zOmDtIrc(2%$N~}%D~8WtjV58TZCf-EXxUfr(5nMm+nR~)MpE7f*w&_bC5U6)6ndwt zz1QpFg7K*U>EoD%T!$a&7!A!T9Slo;u&5Ng?kF<-Qg33s0$%`HAabAs4RzKPNMJu`w95EWJIo9WrWqjX%OFQP!+o z(WHKp+kKKNBPoKtWxO5O-{V2$CDthnMg;pfsc8|i^J?4(DXymQYE$B+Uy&Rmj{(om za~!IAO_IuAJ32T0DVDY+AJ?AzU5=vMyh9sWxg-m;GG>NVi9RHS5Us`oZ^VQLRf)Dw z&@-c!mE)4pC}nfnJRgd7RN^qn3f`Cmg11gs!|KP8J?_G7?nPUwUdDE1!nCcSQ0w=u zn-Y8XKZ6CakBWXxT`SsnrI{EASkW;(zq#A5G7OBZSj(#(Db~Hfp|*MXF^b1!EXN?# zv0IDNJNA1%&fT9zcjH;$^?E3HY3mh+WsBR_WASQsrDiK{whX!W*0VOaR8tnu)$q4u zd=T=fQ8M5Jw|Bfu6x{NvsDJGu>Gi-}VQ7LrD2KWpt3he3DH}j;Ry1zlLp$jKtN@vY zx4Qmue6v@2ByhcR+@p|JXx7Md7Mp(Z7JB7u3#%PEw@w*{^*P(U`HaQmLG!fuGJ#k^ z0Th)}M{oNGJ86>5Ej(C=y36Aq@VVoWtM{@Z9=y#)hg1-Z==UG49rZ~U% zsF~F@)}x7WD!pShty~O?CMUR$v#72Yh=DOL9_dTO&>cj~0S2=z!k#v?k-^7hRIk8#%H^xSTSx|aiSWbtyBTr zqEgdFYD(lvm9qA-F=j<*h-7x63J#>PJ}e)?NbC+$O@}Rf2eATLvnl&0!*NJcEXi9d3?2HN ziDGt(f{yk!q?0(whW(FS+j(aTw{Sm$5%r}@0V5G*hvWw_nAq7f#?w6?npFTQj^FJ>G5*5)iSWFfKx zMzr*$q1cbi7n9-j3O`he3LrBt1ti=NhOvs5Sl@yLD|N8wuw18pKe15~l~+AKu_0Vi z2pqFeW-Q*IkH=PN=;Mtu(@NAqyg^H^osV4nq(#M+jgnm5P#)MH>sn9eohNip*pqMY zVLH9hZJjl%6eYLJG5DDn@h6v2SSog#Z*QAhl{LQ873CWyrY1JRF6n0KHs8WpeZq#Y zu$(cf1i-=DV)Llt?-1z0T=z0$53W9^!QynIJx5I~?pwPz`f*cy$pf>Y*g zwWp5^MqrkeeXBL=r6Ka?tu&^+EE1}{xumtvyxAbkAz0GfIVOVz6=vCMudvBT4J&p* z*jcs+BnTIxFzQT(mlj9ft6RYW(Ex4C`aXlb(xU0?W1mzQ3yTO3Hhw#lZPcYZqXcZM z&}h|_tlAk3w~~iC?}2ABlACCmSx$$O2`l!aEa|Spm{5$iPZbIAQTwIYd+yZx*G~oZ z8VVAXS)^>=pTk4QloH$f(AwsZ>{ctoCQ6cP^EM({9hp}rde3`aB?du=fx!6uSMBZIHaG#|j;^WjD{DHUYvCqt=_u`lN_W@%SSwqZUt!-eigWQbnWzs1%R@H64!MS} z#p}3n3r@fghn0a?QNlhrMY;5Ropg~^UUjwY9GA2CrgzQzAt4`#d5o->E9`}g=_+<` zL=N;r)?qUyItCZ#5#Bp9$P`(q_H4~(iDUqujL->xcv2EEDgdW0QmoIW9&AQKgJcPw zZw>)#rwkRBw24_bBoa6@vD4sJ5xd@N7L0w{8q9aVo?#{u`AYc*LNy*~KVv1Cxz6;| z3f5=uZ!)62uk2vHzZ-p?gr+uEfH(rhY9y_FgR3s%?M%d7e?ytpAvPjx39Xiz`bMqQ z^d{=iNF!)`^z5mIo6tUMH)at!kb-1BU@709!Wh-o$$jbHW6{c=Y@h=6BJr9ZTSvd} z3&*f%Jt~2ZGFNLy=gqP&p~l!R$}+yLr_~ljy`K|`%gsuZq3vz9XU)y6X$b&FH`ebg?^*0m) zJhoXf<}C0q%Ep7i^RGyRLTO-dg`t}+`4gje=x$qxB7gmdCPFCuGJM2ma)q$2Mge^^ zJ&!j4K^W7GA-DqY(HbhBiQ+RD6y9yEc2;3|9ymCAO23ygqkreQ9e0|Rcr3tU`{ z;4eV*zvF)v_@4#-XMz7&;C~kQp9TKd0zAQY@1gv0Ezra6g-lB;TF^zO8m9dKx!vlP zOaFkwcSRbWb^~7P|2?Z)Xx%_G1{{CS;ZS9?m3>x#hqZ?}f0*F+-T#sd4D6!&A6EPs zykO%OR&YNToigX#EKnEV@%r391w$dY&j)y9ol^8qWNru5_n8#@vl!+N|AHj9TaWE0 zDc^(YmqnA`SO7|ePFV#sneCxged52A2)g=y6$0TyFu9B;ll|6%#8(*(!BqYwAAW*E z7TtQ0f2$FZKhM;6K7ijMKY>8-Xg*l;Uz(RFApIzx?7y@O#Ze{%Qhy1Cz`phfpS$XR z2PS|Wcy9&rZ)fW-ffa-1x1U>o1o5A6e{x(oxucq&nvbuw`%&>Ew~t=^L7Mbr{XT=~ z{S`Fe7gi_#?Vei0<5t24KYndj@CQnMt9s#wI)6K~(*MARsq=@7Q(Rt#`hn;h$RDzQ zd->?gVEFy~=b;do@xAsz3hFPxh&r6?`TdfeKgLF2@oSEIGk*!y;p@14IL4F`|JKyU z3HYlI>wZnNtN$GsUxQyOxnGKZT=?&rk>4p;j{X_TL*0O%BK_`fXZz21qx>dtfT2VF zXB-dFX8#b|z)OQaVnucJCl2Rp|A@nP;-v4%ZvYX0&N?|qIO}J}=l+~^svLChALF;% z;7{fx0o+ICGGAFWHlIrL&kC~q%&X&1-1Okb<_w$#gMTye&*FZabLD4dfW==|Ia-PZ zqI%&`f-YKnb+>^-gH<`|3o4t^%T)Uup;<2=xFykiOHi`(0xGD2|As`2UI>*|DR~T1d0VvG2-n%;j+^FF91gZZIfD0r+@K0uuI4$O# zfFJce1+rgMfh;?%YOlzLjnddBCIwJWTk|uRz)uSQGt`6)rWWW2{OnLEt zImY%?do=%BxgZGgQvQ9j0Kxc4v!4{o|7QNqyEE|WemIaZ9E)TShWoiui0@ZCi-QB_ zPuV)fo(+*T>fwb{|YRNyMf9i31@<@_D)AY|BN`-w& z39_Hg)+`4`A$W7D7BzQz3;q+zKX_~W>;7u=&;4>ruN)`)m%7uv&i@84-LI{7`qGWs z{|4~PDWbEa^tey{NdW$$uHXGdqn}5Y<2iamf}{Tl7^mEBM&NEDfB!cL96P=L3#eCd zfNR`hgpb?l*ub5=I1Rl1+x3Be6o;_;f(s)~t|NT!0O+;ijEoMh@JGL z4oW)D{|8_azO=Jt?GsERSo*agW}Q8l`ENE*1ucst@hd^+FIwxrR79NmP1X!ZF#Oct zy!W@??0{qoI+OjItnP+Kpx#E|e)SO`SL9z(|Ac4&!s9)Z)!lOy1Q>{KP6XsSpE($` z?_hNI`;s4ypzqh2XAZ`f;k$VIQ!HV7wTj2xi`{G!(c9j+$_ z4`_P)*<<3qo8=(eVE0I=f&8B`|5N%4N5$)R)7&i9A{%GKXH zb_p0cc4>OnV8oA!GZ;N)nNEgdr9+?{{fFwG%)}4vm^eV}Q83Q1N3U|bpP$U)s8B`VOvb?Kqe`(=z~Y zB;NQ5e*mNY>~QcpZ}%P70ji?-vjubK$`4>{D-H!l{ZIrbIikf`1dq^hN91-JF?`F( zm;V8b!C3$}$`kUNXrM>(8iCSvXTSO867YNYyrX#Rj#fN_^rLT*fkI84sW0YsOaC}- zt}t{{ijb@xA=EhoAcwI5OrU<3H8~|f1fAR6{v#;G+>gxy1d-nfduY!V)K%|8S+Dn7 zj&p9m@YkF^K=J;zt#XR&+-8O9wM{*g1mD-gM9_l#igIKpXGiCH@D&}p#Wt) zK18EayDwTkcVhoP;NdI(<*n&=hvvthEf{|0Z(ur`44obY8A1meSv(BOon zBmWvg&WLYdW)64~UoS#B0Ofx-_sd&<+HVBi7GDa^?hJkyo#p#r_!9x$U%k|tH*x^a z!YSa|xkFb0vcH1ehkiCk-yx>FdGR|` zfLzNTdt(Yf-ki9|k-Lh?v%+$yBI_Zj+=h#)-GHs@-!kF=xr@cXU3-Zha={{XNV)MTM?|l@EzT1(oh$uQ*WT*WX%>T5?F^K@6Hx7@k zh$9!>Cp@$KQ*pnf=U+Y|u|M>vm3^-qDVjO^=q2(O5N_b`?dR_!MXuuBS$fx zS^7v@D)_~Vx{B|}42phf_#+|sk3jQ%mk4nE9!dMTOGk=o{}V8GzfWq6jw={2_8m;t z@uGjE{x4W@9X`J8`$1wr+cz+Ia%Uy|2VjB}-$J|oO9}s_^IsA&hfd3i|Bt}j_523L z>_9kI9Dp$Rz$E?*UoB&m^q&L_&;-2lU%@m)>?iVpHw^aP2e4WX&VbxLk1v+`56;|0 zU%==cc!C7|OP|wOv41I8{{>GO=;iol;yaG7p0Yo13(@{r-~fgG?7@Eq{r{DlfCk`z z{$d=oeHhvY=`XwI34Y11`VSm*D1yKF2mp(HM0&ypCONQJ-X78+<$sXiN7@II2mgJD zy1Orx(BWIg;+1`Zm60)D&VOTem^7k;Qgz{=6@JD`v}j$0%aE; zU=95`f_5A@iI@S1sb=X!EzSrh3I}kb&|siwAS&RiEO}vIBDY%$czzQ9-?|B?;8ks4 zuQz*u0H6gXy>hKM;D72z(ue zBhj44bqv~n9@LM&jS9#ApVK}G{(qG32mI-VAOCj5|8w*F;2dA-A29*9#`}ThzrXZ7 zjHk1HnRW{MJ08w6zL;w76m`zpWWGpWK{);&0OPm)rPJm;YpqYi-ou6oxJ`NM#w{C5!Yjra?Y4hj(22=LwCw>FF{ z9PmtuAT@|2K-2(~Ei>@1eOW&qh>O4+QfmQ-E5I+2V6BM! z?*L;uhufd84clQmOMt|FzXqxHDv|%CWO0H0ok$+j{K(^Hu790Vy05*#mH^)L{v3S3 zoe2NSTzp5}pSNZ|xos>!x3rImS@ax{-&D9i2RBfd*M7A#ItbT*oCR%~`8TKBuY=VR z?RIUSTPN~oTkDB>XDkqNAh%1tfT;h?Cx1z=GlTI(JG?9)82LVbKH$9@HHH8)QY{e% zJCUC^kv|-XztF)AoyaFicW{5mcwcbvvjxMyyU)LG#h;DapP$;8|5CF65lk47cM_35 zWQG3&c|bdnzj-`4e+L3Rk*|UTpz+J=fU|KE-wY5;@Or%85|O{Kl|O&wez0r;mqh}A zy&c0y02J_Na)<(QuEO(=JWe9=MY@Uv*kAv4RtLK}kaJ!Mk&hpd|Aij^!>=f>2@vW4 z*SX~oeeH9S2xXFqU=MKk%A6S*ApdP3bK!+VMWb3Vn!CBqI5Dae{5*rSIJU)})zYep&WtAyND#wR(X`>LXJO%Xo|tHsqgy zbvjtKqOeYfozAWp@^1qO%a$m1(1rTg#uWXXy|S}0_sABG#{v{tv1SxCI~x`G{l@yK zhsMIQ#1xC|UeThn|4ycuXva>SVI;;*rVU#wJ$K3n>>}C>)(;*sVPpPZ;ImO7r`$wf z@6xY5!?N}7|HHbS{|~kNTotEo=jSN@Kaiceo&PP&-1h(9!U-0Wi#h*`nEBr$qyKR7 z9|Zn`z<&_<4+8%|;NOLS%t;e~hZukh0N~;hoWsGv`TjsA4lzC7?JEz}Zt&hRc6567 zuBdm@=y`Pg^j6)clTiRZ4lWLk%#{;BxKo<)9^DtZ6&ZR%IC8j~5?OW>U>I;j7$A{~ z>3uT*k1Wcr74O^w+V`Z$OCz|sk(&zYRVcZnk`0HwvuWow`R}2M#to}F%T|3d#7S3H zgDmp{MyHCAW;^6+_aDV&vON!B*)v`g3iHMc6(xP0DLM{U={|6WGS7?1G_GU90#IAW zerIFkUZ2w5Ey~NU9z}zn8u_4TUuv^B%zpp{gW#a{?3F{lkFGNQ)32wUv z`^VjBuikT-a#KZkD2$xZXp+Zd!=eHb!3ztHmG<}@v!?Mo(juhu*oK>FVaa;x#g?1WN<}^wi^e|V0Dq;cuodUSnH(Q&C1-i zwBGDp?*!7qW2aTk@M&P|`1*2AS>(JS1{1>D+q||-46WKY6p>22TEn_hq)~Xldc-tA z_NiRZuStZ?xOJ5IRi?~&$fub5oMp1jzQD5KLYKV#mzAcmwBkt;!Pg}SU)0pj=z++; zEO+kt!A)xQ_RI7d*l*5wMxib^X*+on3jzful(uDRn+;{$*RK91f*S}W31-Hg>VSp=NjMMom9`;Fl;sv)$iOMsh$Ctel__uF2 zKA!-zc1;D3%K{agF+~jjf)rcEC1Mm9l-@jD$nJ;L1un+8uL#X9;I274L7S)`0@S|rMkc> z<7!KweC;R2vMZSn)*X*mf7E*FKz=ji-%={`7{^r$^ko*04eOV&JQh+6LVM22Q-STM zH!@Wt#4`qHH-Y|z;IcPxDtz-*G3;HF=2wqv-%n%U*R)*Vu%ZO3fuu~T+`lXT*P6JS zmx%bnKkn%(iY}I4`WtS3rDnU&Tyf8|gwFJFDq3a@&aTXw)Tbho>(~mti}GH$u&{V2 zK^>Q_Eme(#X$PJFjE=LbRh=;#g_%aHcESS|TzGlDrm+!u$UUJGfYqS8L%e7&p@r$H zbEj2gEvhK{lGetu!lJ`z_}{qpL*)#r>iV=wO#@t6pHiiyW0^a%#N;c3-p2C^?v12< zsq2!1bkfa#3E%G+#v*VtM2|g4Pk<*!P%S67{PjO#f-Q1Ir<%NbdS5EMxPEO7LQy>8 z+@Y|$E$tBw;gm?s13HwME_Fr*GUQld5yXdf zr5~%iE=^)v+*U%9ZsCo3MkM_XYxDP@x!Xtq_^_@APhxQdo0rJ37YcJ6RZm0feF6wI zh>QDtF02gl#)B^QDxiuomX09nnyHriMTPx^Z69byJk_<+MghP*b~oO zB~U014e^(~^CgFaKZQ=_&GP)gJCtAi@8&)7{1*=Q_sFpm?jH7w82Bbg5hT<+kxkY- z0ld(#+|?+qHy?tGGPY9JSxt<%>QdSMz3=+HQxj^kuiidlxRCIknDOkta(KUG8gVx~ z0oZr+S@m=C+(7Qos?!_?#YO9pk**(X>`u*ZQ`-%V1SGS~NgcnT>A~9FJI4(2ImmGF zmFAJSHRIXGKL^c7wmS-Qp^nU=Sj$KLHx8Qk8V%KC@ft6UoJY}hGD%+ATj>P36L;qVQ&?^6;SeWJ2P_DaK zkAF_Xvn;Qr>m62;y;mgB`8g3PWEq8$>AJZ#Jy%yOKtuDzmK<96m4=f_hWtgYnFn`EXtT;v=ZP-%ImR!~T7h{CqimKuxght{ZBA=9nuY2!BvPF1ycrltKn24@< zBiF?amN8){g+}u&TdwcmSVsBaT7sxE}{K)2wq5n7#8K=mq`IRSN-`h~R1 z8s9OcBir@;gmR>CYCXsE7m}0S>r>Q-fay_JQi=pK%7}n9VcmJ}l>BQZHU5f>(vdz@?G|LUo_ryRVe!5D|)95Q!@8 zIw1A0ORm#xb*+9sNDzUJKyAB9oB8*=95`3!cNu)3@CePA>qp!VZV(4Cx%%B(rVDiC zX%L4@6TL)}^$7TAjr$Pq!DEBqQ6q^_cE@=6DRj70Q)cO76rkx#p3e&IHaitcry>2OmR?b&YZzC+np31M z|71=ZyL*wvSIy>p89wlR6wo)U?vo66Gw-!fI+MmPlIMj6jS0>V4F_G>S?1MGv^~IW zrhM>|y74>Z{Da>8S%-e5OPBNtBQ~nCX-Lg!T=fmKaZQq~cZ0tPBOutm5}&(z;dA_~ z(F0$?z3Ij>k!x=gE+}=%fE~4{Ht&fSczd)Z4QiX($`tH;O3*b@o*rAaGc(>thM9wO zrqj=D_W{!y?G~npI4*s){-n&Tx}5b@BLzd9y>01G_sD_7qQHA!xZqr5zb3wo8%u#i zkdQ;&YxQML^hFaZU&WWz7iP48{kC-xWh+xE!2yQvbxZ_ze$E~IWn(QkO|QU6#iUk{ zQ}P56pw4M0=lT$C zM(LW$gVXsW5Ha7`kjAMR7`4L^U*x)zF`^Blhj=jPB^ zt|s&D3^EMU|>7BvMQn1>iu65*v|M-XrvMd2B~AP4E7ub!_w z5(HJ>CNQRp%7u_D+IreP`MOD}%I0+f5a%bkF|J+vtjSsaPSO!KIjnbzzP;1rVT$M8 zv6q4uWf0m_&LpYwj$%%`*VFaG;AdV{ONsu6UsH0af|UN{;QYG{;?2|rhLS68@Z$MJ z&imoS+cSQIMZz-QdF}`Vx^HL-$~sjanJVVANcPon^LCKKRsG9Utb{1$B6drtTOWv9 zQ7HBi0m>1QKq)`ebL~MB;Ybe)Hq)(1_ov6@(mZ@Qh)uly!uL#y3Dat?`e@2rsOTwo z#HH<8h$=aTF0}-PxoAYEuQ*+K&(##_m=0KUf~ZD1-+$Nt^>5WZ(w6^9k-f^y z37{5mlnmTRpO0A79hhZ`33YL`J^{dZ08(C3Fg6hKFV*HzTm}{P_?A!?ose)RAPm3< zx_AQ6%ld1dbUQpkR`F)_)u9fbzNdRv7ynXSp9)?H;pz)>v>8KAos-_#t4vXr7dk4# zouq$gpF;~)@&VM-kzpWu1y6}Qj+~WeEk}~=3rk`*&%`1MCX(KFJzbn~_deii9A6*J zX6@s(yKq&n47U&hpf&Ka@8>XHw~veGB~P!a>XHF|`%b#zLUy8%xwz%{pSlZm60^|G zFA0_x)>S1jJ^+*Tp={MBpQoQO?;=G>tLFGLt4M9GnyDh8{e5WKhKrMWShY!`=XjOc z!Bik#;{O~?=8ixMoGr5uZn988qLMU45@)+K%Bhf%b-07*>Au8HIL@5^mp9EXC~71S zJKP2&OEenU>>u*z{Y7AE;kvcPS(gjx_}NowuS?}Q)Zz9o*OnpsG?R~?M~n=0P3r|k z2K%c`wB1Qn%j#X|EnzfpI^3WAEI)<=J6^XB34?00*bMs${2Ft$rxZ;lC~ zK|q#{x<6#&yY%*u#@p`=O4LC9UaVna;Fdpp=ou~2cxOXgZ+c^q$UA}#lo+d;!L08O z8=~)$7b;!o85B--mre{tq5-8GSuz3HuRAiuSVp0js_@QP7>^o8!yCR4ioWb!7IeG%k!D;MSVQqR<&jYC;s) zqoYK`)rbVFfl02zdIq6Bg=Q=Q1Z-Ummx^z=jiOHu@-$% zf3fUDX6RUc&;pm8Dd4xUMdrR=kTI@q0I|nuF$Ma zm&11{?3ER|n{swOXJgdNJ9J$)>12!lFuONoay7PT%K(oF zkle53nZGWAZ}|c~wlQ_B!{96j{q8zjvJg-rg7kugpJ59xgj1<_{wA&I#QdMkZCUlW zetT4rGF<^y|536gdXVrd1hUz?4l*(O1e8FZd7n35WB~8#Z~j_;;d7r(a-DZpdUn9! zK(f6bPWp$Qd!h8}fgG*Z6%x|;x=YU1r&nbYRr7j7hQ{jdh7*=4oFP{UA<&^t55>+H zpT$eg-kg)_B0L?(r*{Kn7^ONASZ);ScwC%D?D3B$TbSBa{z2~FG34%W`aJ$>rV&%OO|6Yy;rqo}dqfL_ptJpQm` zkIOTr9r>{9^-&hvg!lixP20-v+8MZeSP1(hG^S+UiFC$5e*lgdaR zC-qHfDHWsDyh;Y1esIO+$*cC|3OTsuz(xMt&LHJrx^X^@z1Te4z0+^*w^8xUJOTO} z%bmYtf+9^;vl6|x#I5>j`fRZw9*5+E{0^b7oTaH)rHy>smh3@Md?n~+wPNEt(=MOpE<8Wd!Aw`I;2@uOTG-c z<>_*mHa>^w@mf1v=_R%c*+ee0L2wUkQSp*mcd8E~uH!O$uC|FCi4ZKNtSuhad71m+ zyGAhz7rqpl!8|33`~lz1Vf4o06+b2sF9Iv}VWe|8y04zOfi3hhk?}48t2)TS&(pGp zQ`+>|(YZT23&Z~WQ^-xFF7ZeYq^uQtNBUh_-wQCOr}#v{xB7=>YuYU!=eRsXeOe!c z($Wbmq$5uN6+Pk=>+1oVz7NvA&}Zg#Mb_)uFkKh`pml*DKpgqt{=R*>558Hjs(YiG3SGI>lIT7bS<>axD$3>Gwn3h z+<37nBwo%J*RqWcA<5R9WCJUYXa=-;JDRO5BYE{NgPp3TFEmFD1WcB$MMJr%1>z?m zPkyHszo`s1m1wGWd!8wp>EW?*m0`LMqGKbhflwJ??OdXP@W84 z(_w6oJn{1#wQ#)#6Fc#+F7F*Asa{NG67=1g*AbfSk;u7pGR57Ng<$t-C$X>KmvdjK z(7&{0M-kttf>*=sB_T-1m3yLi)ojEnqb1o+Vh>few{7)zIxKD*Kih;Ry_hb#8LnM2NAKbwU^rpu zO()!3WZ6EjnwZi-tLG!uJk;JfCNv*AXEt21kkI+cn~bJP*s?^E^YEVjm=+0^$Kk^- zT%ppMU^_+z26{G8O3PAb2Zl%Zvc%4u(D>w57y~h}?W;(8Sy*hW$wImwKUXB7X43|1 zm4jQCcFAmsIuO7k6`5)>Try|9KUF-}QEJ)dX{WnGbSdwer&y|{WJ?vTe*P&$Bhj{< z`h-QZwbV>7`+S{k(Deilfaj{u7+EujL#sriQ`>sqxIV0Mx6 zlwIWta#ogRnB*5T{p{!C%woD&(U!dNOhI6?Sa+m$m|%+-$(`pP<0Gf%9_TdA8S^Bw zFwXunv*}o{9(0(rxj0Bqq-$9>CYw%uDbxg8_3xL*JCUk#-}$8smikq@xE$=27xHLyog}TQROvydI z#8+O0xa7YIlw%AQ9_S2}w&s$HnQJ;F`Q@tM`uNW0Pio$qJ-GR&R-Trzb%WZ8E;;>!TZqB>3KAEU3B`^vwEYgx~T8# zqG!IZi?)=m2<$ zxO!=;!FZW1cjS{scaCAKlOnv6+uu5*B-1Rk?@(P3E&qWXD#<#rXnJ{*w7jr;g=r#` zeD-C&q~#{KBCUNQczC4Hpj&5x{%l-t9NhXqN}u zjJi&RI9?|e5YnTgbQA2=6#E!^ZU+H+iq^P{ipk0h?+Gb$igUQn?OuLCTN3S=) z7QLx#x%m*6--eE|Z|Hlu@i-O1IHg+u#PI1yLSk}MN7eLU(j>RQsx=XFb!NaAI0)wS zWgz*l!U~gtJB_H};x{Ao-FBxP>7QGKe;bcQX@fBKz%R9FFfEiHwxi{3*wNE0Fjnul zUzYrrW#WBKAvSols#RsV609z2@O5|H%l#S#X@GhCu!vz}j}BTpnW^B`=4p&x)xuek z8e;k{m40L7HaAQ8Hp2RUbBA5#qRq;gpb%BY~Q^R{bj1cA3l&@YKz8K&I{Xjce`NT6gq6Ec}%v7c{z~UA+<5$#xX17iYEDMh`-}RUKSKq z+OVgKDdcT)!}Vz17&p-;W!@>>{yP{?kx}pfSFLK5FRcBg*8IqM<4bFA;-$2zA=Ew) z;l<6*1$zJ2;``1YUWnZgjJEmle19}_@Io5DAUp5V8VHd)Y87p}Itks^JgQGEQgq{j zGybdgTnQvGXGDRvHYRzHkChRg3zKVjHs=4ZW;7{bhzb4bec=QklV-7Gj~MXvzL1rB z0&vcE6NiK!w|LYRe;5H~o9ubthvcCK!{4at9!tB4XgVr9QN54xj{4_3q?VzP{?!fSevAs z){=bn@8&q)dd1T>OThTm{LJBg4QouIVw9uXk_odeV~<0O-sK;9l#; z>OqiS<4U4UaO39H4|1PY?V=1Ev61B+qRW+?jV0IVwl=V2X?GTdN2`zK(pqVGR^Ubb zE0l$MJJAs}uF=fAUf^Br^TI$L$IWH9!Kh0YvKFdioL}U#H+G$0@JR`%o%|5JCPfA> z$l$Q?b!Xbvu9avW-oFYX52{T%aGe=5mD|B9(UXCR3Y=T1aDv<}sn;VnK)kI?knWP8 zyZ^RJKxLhGbEO$}^iBdj({m85mchIO0aIlF?R?KN>AKyP5g6GU`b<@#Z-d)C87JXbDE(78 z6JzH6OEyLcish8$HI>pis#X}VoMQdxKfK*|j&RUByN^YW#M72V2O1l|iYBNaYg%gZs5(`PW7zllufZW%;?En=be8N|^nV{mukU#8Th1QEJ-^h&z9CIy{ z?10W(8}~J=JoTR&bIMr&%1PhT?rODp(JDgmm@k-_kSO728bpt;axZ5gD$)F2N~Bt} zPBFqM(y-{u0EqhGhb$trA@|gt$;yK51L=(-5;ab8^KhQ@G_-|~(Jujme}b86^l{pY z4wsQ*jw@T9NZ+4=m>!=mhEux$jEytCj9D#>QRPHI>P&@+G|JGjU&7Ce#n(a_65U}? z^EGvEN*~vw2d1(^XxeT;&~%D(&-|g)1QZOMqNLnvxq9#YYJJAB1T=o8@&q8*1%gqj z<>sLoh40q@>nabKJ!)mvr%hWX4|Z3ZUxmIHusz_f-#YX!fHr(% zGm`bFQ3nbFX7%N0*1^!EPz=TV5u9$v9XJ^u1d_R)^4^+nptEDj*QXTWe$mqbjcdi; zna85<6ew|Ym`W-WNY7wAQnI{hNt?d?Pk?<_-RM&H400epI|fzub81PC&)|gIDu2|w zIy3#EcaL+aAlmv>V&2s?q*!DUc41`U5`G>yzheF-tE`!pV1=-E-Zy`s%?$-4^ z83HoR7fQa&PaJx!*&2nk>Weh2z5hA7OeEXVHu$T}zWd%jr~moS2JYslV`=O%-r2CH zdJ@RclJQ+6cmp_d%rW5WIw)CUzB8q}va-@N{eBgbYpNcU7yi%v(5WYRpYDZNX_D=q zac!803g+AHi}c<7$DZi4BU2*8QweqGiCe?THBAi4vm7$auu;A3T9e|1_SxH~^v2%% zr2d)ZV~8PDp&*^%j0MMlQ?MR)hwvS{nIq)6@dWrgh1Gl7j)B} z1cJ{B!4lHOP5#kSok}SP$HSH+Ed!wu(JfUgGshL^hp)=Z#j)YSSu9Py!w)+~5Hz&Pr zGaqtp1rZuf_GOC)4Vaeh?0^jhTRq+Pg8I{a;l6I&bETViJlx(6sHMmRL+koo3N=*T z>B++K(gpDnO%9GWSK%ypN<2HL9Rk-fAnl$uVrt8Y{WD`fQTTr)vANo8$Z1f}b&XK_ z5Kq87(xgo|#Ds6ro=lc|sAqah=&skH8yn6C!&+H=(X}CL070SDsilv~x*#t?_$M9o zf1mT)UH7^2TQa@9En7CF;CT9t)~f<6#-+2S2Oui9{!Y7_NFS$3lkEcd^+1ytu6dR% z?_&vv=Gg055|O>=ODV*MZf6^q$(9Tuc$`UVYh9AMrk6w!R>cLCKj%>YD@uPYgiC2& z1SUx5Yt3oZmbp?5qNRw|y1@(o@9HpGQBqu>m6y$fkF6+9b%{%j-y!jaMyE9Wq`UrW zu79*Hppj86$jNhMZ~2K9IjL2sj+p*nzO{Li$SK%_x}5`{w;?Yr`BSsyxIR% zugByra%C9IJ~7F04%@m@IQR9A|X`zOxyl;7Om$87XwAuPfqFyY3I#?BKW^ zdB&mNVxa0kLZz+7*L*@oHiaE3X&It*9n zlj2aIP*4&W2yRu*e^}sx9aZ*tCJ%$05B*yFV^Xb41hLPZ$XexAF6aWY;f^z9+iI_d zy~`VG{ay&iU!_4EM&XS3#jBbGY!FkJ-X~$_0xF> zhXnz%Q9g0^rNJcr=2ec=!=8?Af z7qQ*Q+cr|&i1t*I=##iD~{ zi2y$BGk@=p0=ycr8;wk+VfZcNNUyZK%RkG&P45Bm6uY4TV~WB z$@GX0DpyQoKg#c94LW*9KzBQ0M?BTL&2!}lw|p19yZl-e8?_Nnq`!zaCVT{{wtzt3 zJrv3XJbJ6i;u-j>Pkp?Ia(bCl>BBz`P)sx)VsJK0{rZmd1_&ha`!>BWe;MYoBe;#= z+fyMZ6~Y|*JsYw#+*rv?8n9p_XYtpI*noMmr03>|z$9gE*>;!!WhV0!nMr=rmmev~ zYo-esxyZ*uutfrmmIryl!!W1+8Zo8H_Cdh%uq|gv=h(#o`|b@?X&bg^`|0X@oW<@5 z$g>skd*+o0(Jb<8eY6K*`&?wY_P!&p$em+s7k9AcD588Qs!yjd^!n`f28s#&h7VM- z!5t#NBseqnQA&It1JId-cpok)f}J9wOGKboMhDS;HRrS+R9%*1vJU+u$-5uCMKniY zyhNEI!taoRnGaCGCm@MfG-_ZA+5ZQpFthe z+c3ulN#P^OOH*YVy=wR69%RA{#nC%e&(~UL&;G$;L$lGe$JR!O4(CJidy}t0beonw z>TO#qkn8^Z0>0bO-SZXUN8oqInobU3?lw~lb6^9EfMQOko(R`i`B#@G(s^Uc#{xYm z*a*jh2>uspcmp!PKnN-&aZHjzMpC>J<=sLl7xdYpnn}pU+>{-|Ay(_&wR{BgW%V9E+LOa>+TSD@lfzV0#2b8n zJnp+sG<;yN0Z%S(Novb2MxS+X@=u&;MAZ8|S6p+4(SeEDTXuN;rD^-s^2IH*$bGzc zEYMa{qMbl}@Z*6V&N zNA~En*^s3CT4@o2OdGFa;N)E4cqv5*P;4XQ1VD$}5;+ShN)#d$bDI0CvE?rH#_DV7 zedYReWJwk3&`sCmU=Q@xiF1&naT~jdN}_Wb)Lo6Ck{p~AJ^?h$6%E)f>M81RrlR1` zHix+){5+GW#d1HHw-G%Q(rZ$VTj=4naS0!~ZIZ9SMO%_d73I4%=+_TIZD1?arkYy| z-JC+wQoH2jA*?LsA#E3bbes?D*UpwBxR8Iaw}oE4_R;p}X~%^FY}oG{O?n19y(c=!#dRY13-(vEjxJma z7G%(T|;XX&ta(hUpJj_5{t<40LIL?p38zg|=Mo3u>T)bZpOQ_ei zhHi=L?_zqgUzjr)o@cVz*8_apnG!}z1W{<|&KX1X+8zo(cU-S!j6gpvq?aSy)w>mQ zuzJ~i^hmWQc=e0Lml}7ZtH|dK2y|iAh?_{G1Y)Vqtbb#k&!3jkFRAdzs$rT zZ>pEAvXMroR(Jwvy>CdcE5IPKRITq(D2=vMGg1+gsKvYksZHe%VwH=~Is*amfB0eS zm4?gCM1@lt=JF;xylN`;d_U!AJqQ|E%G41dRhjT=0rapp6X}EYd!-DaTbPCI#Mm__ zyMv47lZ+3L76fT>b20_gK2BV1F#LEV^?iSLqO!h?7`6Xnz?uF-_PI@n1o;>dxuY67i=kw3p<3% z+)aws`f@B4wpTz4ugN=bKUUt6@`g{B32@G;32vhW#o{yct(v#cae|r$n;WbNT&V}+ zJiTsA8c;epf@W-(n!#zd$dB%KAszDD)lFIV0&jfvObybB`q90~l3Fnd)g#xo8ymOD z)PWT13{JuhVTp^_Nt(Hv7jSEf?mgOYyJH@c$n?XwiEymVzNJM7DSu1{0-1C&wSup7 z5VZtIOosShx@En;RkG{!&XqqGT;Nl1h&tx1ppG+;aP0SG>@Oi#=>o9^yMaQpMnNru z+^j@eaHtzyMwdPzc0A$ZgWbT1miVGIMhB*=(=KQFWeonrTBh#4Qp)}jC`97?AnFU( zY#9mWhPjfAzklo3q!R$a(_HMPyB7DShYre#n>SdjP#9Q)=^Zi_tq2(CIa}fq4c&Io z9-_1b_$;<3VHA^y`O%;&K`O~puYMisvsI1JO`QPFxF5*sr4KFflf=urM{jM-@&(#t zZ=@mp+YYD_Y4rMR{mz9$R~26@P5IwO^B4r;k}ut-5wNmEw%nl+vg=z3GxQZCuK3md zZ%;=mr{@0(`xWInIOIVjlB!0u?#ROc&Qs6xwTX%Snl_Q?vF&=R?PHq=sUxYgug7bC zQ<_;-wO>XaBGKl*MS!kEd&42}v3AVZI2j>JmtRdQH_un}t(ta7|2CpL_Wh@E$OVn4 z6klAc%h>VfrKL&C(bfA_!k`@oidVS?*)4Qg9*4@AEiC+c%@|#O;oX~e%z;4zd^-H4 z`d%a@i1z3P|1(;Nv@KksdmLUNs*Q#Z6(P3~p^LPgT$P@iNMf1fIq<8vj@^MIi3xvA z!@FdOR;I{>X;>;1VrMBbSo58;)K1{GPdO-yF*RN>u3XT%209zPD`Z z1_7NAh_cq+@j@S$@Q*d0zpynsYc+*{dY^-8&qBd3v(@mO)~3;s?2fHQ$IL)r_Q2aw zZJ81!TGf72d?Z?0QOV+%$icn$zYf-Zm5H6zLWS+&L`QO%sGX}X%01({E<7=@!$k2W z3cdjGUU*!ZaGgN0PDSxm-4V4z{Z^^7MUEV|rzblRJ8H03nKQ* zVz@UT|0r$5(@g$11^m^hunKzdB^84x$wcsStYX}+8u~keCWs~#Fez~vfi4YRM*OPL z-}P+v0dQa*V#xZd>7KS+b&w6aO`qi#n1RQgAtEsx#^oY-Q{$I}QZV*$Ar2gUAd9;W z0(e3)x-m5Z2L7qh-$yE3u%vkNaUr_L-OLc>h#4zrSE>~_@K?vx~)GKamS1Fq7n86JMU~_ zne9;gR3(jzY`gP(jc;o7LLcWLRSqq(H|3KL>OUNI@^)g?nazhB%739+`iN10?W8PH&*y2bm2o+>-NHv3eLqZVoTN? zUL1I(3ueyatapt17c6EycRQq&I#me0Jr_GYj9X7LrV_6$_N@(95S-?0m|v{0$p3iF zku9#iwH~{7ue;;2?q}+&nK#Q+^f$2uwHuYN53_LeXYyyiV`X`>Ivy#VY}uB)&H30f zr2b=Wi!CizC$e_EhqJ%+~tu;CltidM#S8$J;izn)^n~ED8*tgPcCw|EdyZ~Bv&Em zGd^BXNvN7ABEp!ca62!N&&9=A-0gbfHigN=E%2=_a+b){)bKZj{9GUO?tO{2V;H^r zIrPc7?FR?jLHA-PTW$wzp5kit!ug5~)9$ZZa{7kMkj(9Z z1@S;9*J>=c{V6PZuDjRy$-&UOUT02_hzPes-EYnMrW&xcC;iRwWk9jn;Ftv=M|rBJ zHY^?F_Ia#rrc90R?@x&s%zARWg~lqh)DU=ZE7M`iuzyah?|}%C+vXcejqb>JJJ6BV z)z!MQl;D#LQaV*I9o9(3u3a16fwdtK4k&5W+i{1vF0oN;ZmL}Z;>yigPZ!On9ha4Q z4pI7Gk>3IRoue#I`q_#ir`awqsY`VBFd9!zUeB0iS>mW*k9sq`)=yB-`&r%hSbK{K zc%W(UrlMlhStklXkGLm)+req}X33nkIJdn5cf<=VZg;G*oLY{BuK*U6E^VSG2-&e7 zB%#O6DmU#*DlwNP{X#$ZY&*rikFz6}_)R)vj8E;udn-lc7bmDQo(c~7G-KiIlZ@Kd z-(it!XXG%}yEv>yImz3j*RrxU*^s4>eVaB@F=3aAJLr*8%e=wG7w4mCeHM54smnRV zmO53|GZY-RWr`%!Lq z%x83ecj>bpNH$f6y5URw=YmW-5zxD%QxP0jE@F+z=4j=ccC8d*WqY*zA#hSE6gwRY zK0Vgu3J%~5;4Cg4-suL$({o*L0H?>gs2Mvwzwt2oUH#@2-dm2(ii~=HJ=O&W@a^OgUBnO*i1#12E~!`no3gIr3=nj;so>e} zUaftUyT*TY-oiC_9M8$;yuH?&$5e9%AIUVIfao=@JhqLTfO65^*}Y)DC3*q~Q8W@% zoWUg%QdF%k+K#*Acf*zQjld2q@QL=T^=4a2FuvFJGoCB0n5G=h8c%f8S(f^o3{o8a zRx#@^UB`FsF41GL9GSZV=$Y9vIKz+ETIWXPvyMmHPDBGunr4U5tG^mM zpFvd?xut)^i+a*bz}_-8%a?Gs^vR~bi?d*@4yHuWyQ~}8W0OJO!4;pFM3LM+S`Se4j%LG2+m;rG6QAT0&x^dSn?$|vK zjZnRyzm^||NNo^sHpz1zl6emRa9z`>&)GCr0KFIUO|h8b(jjg(UCcAg-9FMJ9ipG^ zG~0`pJVz&Tr1a@!`FM*ZurzsEHlyXCaVu>|DoLIRS;Xx?{v*vLo4%?_gNA1hDH->T zgLSlRDG%W5R?uaB{+E{RQgt7Q$Qebb0-#Aw^!p&bfX6Z;!D=rxI^{<{dN@=0DlAKd zgg98xeyFz`@p@T#m%Imm3kDuox)JDOa%2@mv*!{RUus{mwjcG;wdcA{F-qfU1gH1A z#Kx$;<RHn`T?N2U8E4eLi zn@5@tZn7!AOya)j`^Kc2*rpUFYnwY5kw5IPH}u76#7OjhizJP72Oqit)e;>@K`%K+d~7?ttaz{WmUl4q6Y>rW1Ee_TI(_vS1c&Vc zR}D03ki1Q3j!*oikfgg~*jZaA;wltpU0yo5$=2OA^SQp}_QfBIB$#<|4Ior=)=N z9*zCSNL+%i7KWH^Y!J0L>LuB<*P9y!dbF5r6pbUL+AWt?i%HqiNl&{xUm~E9E~uS& zuEY_I$z@t@Y$W&l>$sODhNe_L`uL!e7Fn5(*ypVt{%lf(SG>xyuCEDRcAT4_`$0Pj zthtwGyszbHJGpF)u=x<2&5$IMAqh93c=*cX(~K_hL}4EZ7^TF=YUwI*9fz^V5(TCd6i0YhwLMkv18f zYLR_D7~e6VhE`^YXrZ&T^tub8D1pBzER@w0wT>QXf;?T=e=P9K;Qs66fSSFHv$YJl znn=R#*v2E^LKdUIGaCP|!n~zC?}{3$&-6@ywv%vIbK9+)6k=jKs_h$HwMVik0|YML zTXj-OGKC%vh9BG=ZpY@iv914gVuMaeDf7@b!6@6-;)>dw!R(_Y?=WL>Ilif>peuk^ z!=P?W$AkoZNj1u=b_T$W>QC?c57g$P@Xn7su23ZpK$GsbBYbDSsRiJ@(1$wgKA{|8 zCA9zt^cZX2HFb?;y`yL@y{e5H-$-z5lT96qTr@B@aEXcs+FsBX3>ZqyFFD=h08=*L zMo-?BN#WIfMs7nac#U$X?xmFiuF8(gh3*dQ8K5AxoZ1(B`$^TdH%~1eFNh zx`s}vH}rP6iC7o#+w0g}=fUfKik!Q3H&FtwCLi5zdV0Q{3IvZH;tFRzK^HBNjt0gKeoYoWOT-b^w>l{D`m(}qc|IZ)e%b6nsjW4l{&fd64QO_h zh3Hf5EvFaWd$3xvqA@t?tMR~B9lE@gecRh-Gn|s!$|aH`1Eh9jHLtr)bKT4pfRcaM z2hZl4oIkH_&+|b;!_F0s*?1FicVEbdD|q0BEd`y$);0FI@Heim&<1haM7WrDi5LsVBHu*>ixQN3AuZ%D#h%2({hQ|`8Un`&S6|nY3_~QWrQor-e^+3e%OeU zL8=IrnqELZPjC(j&L+QEG_0jn8(K}Jf7x-g3;$?5WHv@3#2XH)(P}bWXHJGgS-jErW zxlG}@eEbePN^ty0h^DogEyUXFK+BI9r@+|b&0A_}5~!a{i>@^|P` zI~9CSA9wBIjBE|RvSE#s2?zYycTR97RL|?AB=SsnDS?_3-tm$)dA!*V&(za*@RLMs zey0IwO1t1N%&mAqKIW|vb6*TsxCfdDN3cR}eZPOE?gK@H@pzEZBY$_PX<##DY?<y0?6qEo|b&$7waL;yM0gr7U%}xOVgZc|uh9 zAx4t^=Lq@Vw9%ROalvRki{PsnfFmwrErg7d!eOk8tWs7e~f zcZ8OC@T|IailfH~fJ7Qk?H%c*`*_ucuDH|#8>96hevPP(e3r)myx>vm%`X3u!S|1n zHB;T!sdg8x5aRcHM_t$k%!Tw9ZFH;vP{y9Ef| zxQ5^k!Ce{%?oM!bO_0Wdy9Xx(x8Sb9oj|Yzhg{B_^Ua;-+;8UIneRTmpWge&mRf69 z?YFAlT5Byw2bUmu#DZqGYzI37|Lkp`WF#+rY?qg)A?dL71MkNZ9}8@S+5~0thriwi z(gBpm+?czQ$nWH;DE&Pu-|Eb~m19kS5mdKtS%`?=E9e0-Ra%^LjDy>|WVSviU@3dJ zqCSt{SI$6%S0xL-)lOfcaQY7oLEctjZSXeEVnqO!Juo97$L{03n)M#``G-{inp1ec z!?%f|i_B9aT?NzfCKasTaEOS+uR_<)B2q@8O^%ySe|}Tpff}U+FPvBp=q?JbP5vCv z-1hs2z^IZ^xY*pD$p@-RHU+9Fnly2B`LklRe{1;AlJR3}Q+r>0{9S&f#!*`doGXAAhT&_-;I#812d{XL(m&rwzKak)#FJ z$?xxWCq0N0k8Y~&7S0%;l_-<6A2pkc2Lo)garxC2w7vWqI02IGbT1tmY-UYrM4mb~ zpnhg+lfxuY4?sN?y*4RZ&CQNe11hbQ^`@`-61JuvjL4ygSRjd$M(cQC{$8!$fO*ef z^JxT0{(P$mh5Y;L-@hT4)v=u;Mzw|1bMNu&NSLwExs| zM}c*kA~lX7^s{BmzNy*s^e^WNP~E;eUppu;c8D0@xOmtk@B(T!Su6eV@kM; z9xC=-^5)h35Z|6!=$K_%R7c3}ucztFdcSa-KMQ=R(j~G9D8VTsH;prFji=E(Ceil) z%j8gPMnQC8KZU8*y<-eEwmW49X7pCqJOAAv`Q3-Mv5UdRe4l%O`QgCkZ}PS}r~Dn% zdmjuOKjiqcoiyubB;D24hwpo{;w5`T*?ziS3!wklSlW^QMhNvK{3osw6f|H78aM`|aE zo+R{^O5HG7aapr9|JpwT4S}q21fb(E}wG!>}>LQct#&H@*mp|y= z-2`$kjZiK$rT}6;7&2TXQn<@h(#CGf6dKX)b>_x9VOW3XbhM1_Hy_4SjnA9>Li_PB zqEOloRf_A7)3^pnyNVt1cEn)KAz*#j?N;DD<_q~e?PRlAlypA58HVo>R}gYXezg0L z$@FIKyBCk5NR>X6qpxUP9wH`l%ImpAyne(E_$qk-jxfz6ek3ao1h_`D~9H~3%z7<6kIprTt zn(QGrw<#gT6G)UM`QHBj!!7t1yp?}9$^YtLLH6uqpudJjJH3Y3yZ020H9H=6c3!xU z^H&_5k#X6->@xjV&;Hk(vFAH?jq{QonoQ1{kLYrnqC!CIUl`x*HWae`YJFc@b1WzKF~B4?`>G5ULDDJN2HeSt#7{N$(KVZj zVMCenD`Ov)DI%2E~#Y8zX5%kHeQYwUca8a z8KXO*trh0uB(BAW1^}p{>TjiTB)}eWa8SCY|8S-^r^Ir(3|7St?Ke>udzJ`K` zY*(C}Cq)*MILM&mNiC2ZXTXR*$0|)uWGa4=jKFK+T>xYPIZyV8$m@`a5-P1$<?z1WIQMX_!Gy zEVa0m`QQWA^ORRAlslC*?*5z~UT+h|DNKJbA^>jLpQUcJVWPxo<)9&Fn4QLwyCSBQ zeZQf~Rhi_PCew9@$Q_Y&dfhQO#p=YMtNh}p&JxI;6mSyXR+{5P zl(@hoGM}if$6>t)JWoV7UFQxgzC4i#-u~~6EAF@@Q8hD~FG`1C2lED$M~1l^bCoSQ zLBU%g%7+&W3x$p<+`W56I=NqoKH<*w?R1Sz!+yFa|Jr|``iE=?@;r++7nvr6VGh*} zmV4h^t3mG8C+(s|G|)_cgm~<_yB~+7aL98D2iUr1tyzPjr-1@vcT&k&6B`rJUsBkV zAPX+sQE9L{kj$%ESlPEXXeE_A4=7qtrUssPIKytrm4p8Fi&45Z3=(ChdP>?GtiPTN z1cvZYGs&J!U+_ee{d&rgF*0BFq_7}2a}V-lm5JP(Iir>At~@?s&ndvEoj9~pA9^BQ}i;njF+v}@lkYi)PIM0TF)gyfsF%13gjj>$C8JT-w6)?7g3vvxKexvC4lAl$H zLTy#Ly}{?Cthaxc$!5_(va0p-{?8Mh4Q?e1v|*L0iTjprX>_7D~bTIv-aA^tZOegu`IdkM&*XsZ4E5dD+U=r%W29pPhLS3wfWp`cg zS7R-C-2SBz1tdJF{k8l+Un6yaRQwul*I##ylcGFC3DV##!3GEg-wj$s{nYVj4>w1L z(4%dWdwNnR4B+aTs>NpP@=JXP6?f&iVWvC;j%1 z*8l_L{IekxI|*rL<&@R@0L>a2W6c(_oAiUhI_|tw*5vca0k^~ww_PFnrZ#x zDTt+yiZ5s4qBQ6CUX6N>tTuKS2hyJsZu@6XawmKjkZvGK&(5_p_r#fHly&l*($3SY zaoyi$dDY(fm}Gea{0%@cLDBIP$5OE)fn?ip9$w$4c+I)|_(MIx*ib(5TkKkqxkoag zlI6-8$>-Tdj@O)J&m-Jf4P{Ky=0&$0=Rb!`*v&`i9Px#iG`stZA|qsFWyBSFN=k_>%{q*pYH{y8$N6+M*z+Vrr6pa5-at|i;;fw+m7 za+cSS`lNveAB*Y0EV+ipp@}2BHadP=u37Fg^W|%G*Q5BdVMnFc0hve?-2Pm#w4&e; z_ApW9g%eCU@P;u@V%8-A%n3I)~Oqm==dDKqy5k8cqm zuVTL=U7|TBOMZy%wau1Kd?8-(qW$g?SIn+6|F@x)2+9&QUq{rMD=9MR(@$d=fsI}y zwLrCQcAi5-;N$^@G1YlE^x*Q_CWk;m<4h}MRW4tTlj5^79Nf)tn?+=_kbG%%L>mcL zt3VPMi_hCxN^9mOMO947{KkC^l zH_y&q7rq9(8UqO;fsShNsSZEq6GOFr%(>q7tFqXo{`^t$t>QB3O^xZWv*s2>?We|( z>+e5veghs0vA8~u`VXZnY_Zr1=A#-GZDD+@*B&ny*2oM{y`#6BJ4uLJC@1y@n9w}D zNZY9^e|eWwX|svRww;UAZy7q*Jn;oky!g>8+bq7gxzj9~b%bGf@8R+8k=_hKp-|R; ze++uIq!yoTj4swVL!+wB*KTZZll(+Cn8=&I_;gNQT3brTJq_XC0AV?;G~PV~Fjpc! z*;$c|)UN2q*J6*{Q84R8E`fzWUCRb9I%0Z1788p zn`!1mige^QJU9S&@jN4i%QR|J#UAHVaE0Ln+yu_6X^ZIbo9Ed=iZSaR{TR?+o3dVM zR@MHnagTDZ)sN4=?UAge&{sC9Rqs72E2=0;gGFo*XrQ_ap9}VP@IR_O$feV&kr10V zTaxeBT@2B~lU*U#XK{?k3Q1cE#2oSi0B~Q{uzNmB9~Xy*9Hh=X_U2MlsB(MxHp;QN zVTkfd#0z$?6DG`Ikjh)%izR6KQs2PaC66;~4~8wgsi5AIPig7$0vVjZ`aUIn6_KFe z2RjH~;S6^GKh%1JW-wsN)_lYnXKUQ%i(veFenbi@(4sW4B9M!e>&;smjVgPg!Fab` zx5#GazRzq1uUxYihkB_9FRdurM#yp``K^o1^WX>@em>!mh4(pGWJcfa}nw0d|Hk zf4K5-V+uPf7w??1qPdwiQR#0U-nCMugqk(lbAVr;Ud+Ni7`-MPY=c!X^K&0f&11cM ziP>f0gWv1wHKJ9#Vc~Tx(W(Sm2n89@4hvA~$SBDk_HDD8a9qQ(C!MX<)Haqb8TV@a zL5!KH7|RqTN4ywBo*bh1+~|h6*(>M=%i3VN|18x;R_xf+!ZLr;$KmBKj<_mIM$^9IcM8inuUw)DM0fyR-qEJ+&IN4Y{60P{vVd`V5Id{=@J1>l>PCSw)ZU&m&+d-(*WSaEb_6?_b-0j+ASuYK->jC--psA;g6M zHM&352q9Ajt!Fc~Qf4>4Yps_(t!CZpICWlpV!f4SvT_cOwIfvRrhWd2n+cEL9u z#JI0Rq0?%XA^Gb>{)lMtnAVpQy~xFQv@pT@&2Pxmk!<(w+R3GGfg=t$|BtkUHc2vG zPVnTfpD{`u?IVaEm|S>H%JJA-pm6wM{H1Nqmse4}gs zGhQwfW+lWS&Ex3)&im2AGB|5`BS7U#``1zSZn0TG8D$2d4Sk2NC7ci2<4=XK1M*iR zkJ?!R>uwCZ#NsK2hQ?tO9Ct8X2Q9a``)1PK#cO z=$TxH+l!ABs~^R~B3%V*CKTx+L5N48HlQ^o{Kb`Pqwgh(CuLrc^?!UL4EaZsFvJ5E zLbWhwnpm`fpL+-(4CHma1e76EZj5M0cIT<7x4dW0&hwPlhl=Uy)icd^EU3F_6ZkC- z45rq;TxMPhe!Tx^99TOu#gP@E8Z!#O7Nc4Eh@gFs7+|UM61}#wxRXGB$Kf|X9ke6R zd)Hqe>yI9_>r72AC|$Co+KYzk%5aDUH-{{am$6@y{ctyZ?`4k@$6U8Mudeu{0$?Ik z%N6`_h>>?f>U;O8{PY(yT=FHy1;aGO?eO_f8 zP)&Gsn6TH`oiIa3;BNr3-E*zvWgq}VNY&CtvUB*IM63B9lK+uCf^@TcwbHNE6uu;@ z*#`ib)C7zUj1PaBk+GnEi;Q%&JUn&|dj)W#3b^e?hc9bN_k!##}yKh~<1H{R}RS}~Z195U745j=^KY6p?wg0!rDc!{H;!c{o- z2pZANg*deHo8aWhIBanH=9S#t-f=#Sk;8S`{Vn6iL0$7vtQU##Z&@@;)U>)`V#-|n zURxHQ8VZOUR_~S*35C-G9R+<*9e?6s-6+5NofJhWlT1|SI9|gHvF!XaZ+p4CU^TGg z_a^&!En{e-E4cm0LTLN6>fuS)pA%~9n4LMY#6eZZ9CWbF8Ef^fx`whR_5(?m>VfMN zzhpF*R7XX>Q+VlZ_!}}h&j38knn{DO^#LBiDUz2d6(83j0FYqAFk_19$l&ZFu<0@! zY3$N|$QCEUJz{QR%z&a+^9er;D_1A02!pO-+pA$0ayZPL!&V))k#|xuDa=J>Pk<@& zPJ8-4vh#{4CBzD51Q-tasBU_rq`A z+|RSWC+uELsD%|s3~^Xs3r5(cMrZN^f+^W2g`_C!| zXvo&|Xd6i0kryDdz9h^lXI?7&`Yuw1VJXXKU_R_n^-QSlT}D?rSiW6)Ozm2r9+_9gvw6L%f_V?Vw0J z{oAbxJt0hcT*ir!U6e(B#ChyHXf;r zTCykq5CoLLLj&FM^y;%|dfS|tV~LhN^qtR%!aDH~6Q_7{o-(p$Sb>L*pLJ#Jnak8L ziMqFg@raDs6@yq5bMbvNqq1g^p>bVyn{TPRX51KUgw2)CC-m3xi}HZxCxSOCxx@fDzz}i z3$fsykI!_TU01O&j^0E!H4{&n?LuQhFA{ATL7%mXQ}uo{haM-uRjbh+U@c9T?~h3m zPfTv};k<5V!nU8 zamB@D5M9^I1|6<3D1Sc7+hhW#o_rXx!=Z5uLdDL^6M+}P6N5`{z{DQ%CvGp+CkxY? zK0234E~{RA0z}qrHh%b43)hYuPQ(7XV}7_;kmvMCO7u_(ihdIYIs@hv>*j*+4U4LZ z-bzJFozigBg+);eChlr$j}zi$O{4})4L*_u%nZ_^vctp~js=fOQs~xH)9EdI!-s{# z1%ZV!FIF}N$Ya2aokX=Xx7TBi2@&_}`(sqf@I+J%#$f+9HAY{&e|?`WpbWCZcXEl+ zjp9{Ja^)DZiKyk$4Y}Dscq!4+||qCA$pAIHf^=A zpYq5B(aiw~CqJJ`{-BpS>{Tl3~JkJF)xAJldHai}vV*}x# z-u(<{F6hXd01^q5$thhDsD0?w<7Ymx)Mjteo}NjTHcJhi)t_<77TaPSiTcFMlt`mi zK%%C8tyndEO@C>{Db8rdEDYU9#Z#hb<35yWf~evA;1vp2<8{3<1+UB_^$l^;Co90Y z?CcAc#iW6R;V;+XVW3Eb8tn$jH`q65g#L?yHzhSze&rZVL(QW7(@aC0CU$EUdiHP? zZRm0XXYC>+7#O;vXy2^_415_wv2C}3TqH;G{0PSh1SE=d(Vj^bwJsz*msAFufo&m3 zyGdZAEHdIZSsW|5-Arc};`>>st?TGYswpHIsJLluNLoZ@Zjb$Pv%HgX^vzF zdWA0u!@-1Ns_aZirWJ>XTpUPH)N~M`tVe~-bHM0Kf!Y1qscTGAR1`s}4#$FT5a#qX zI!(a1OcNMq-WxTG$(gN2xsCIfI=%2Jy99$i;KkFr7?xQjOJWyxcg5#I4s{M-h$f5# zO&Y+@qEhZ=9MV{Xw=F6n8%;6@_ME^(W_F>2xr|9RPHxDXFje>I5n146C=dY(yWj$c zKdv`hs`xgizJva}@7ZRnest>QBkYOwZs+$}|H=z>a)iT|@mra-j=AwsW*x2 z-GpJgpjx!tK_y=)=j%%=TD2NbD-G6??&>B=#Q{1@yGDA@EaSzH^Pfy!B2wWfGSMa61}CvbWF=lHP&Z= zDYUIGjmnpLvP0imv1&>s=sCgWz$2onqA}a%@77wJ1{;jeO>HlXztG+Eniqqhm4Se+ zP#pZ@R=d5FJ~k!^p&d;_^8&=Mx=OIYI>MTLetROB(2FnVYj1N)7(3e91usiH13m}l>-{^yejX2K+^gqaZfmeySUrhEk>6M;TzNrJ$Tuc z`;&QCG~>|4<_g?$+o}1xrvmaq0^U=bu|yVZMUJ|;Vv9i4K<2<+Cu*@-1sO@E0@9l?BrK{iK~Mey@eoHz|95 zLO3$RyNgrjrdJ%bOxTfNk|`y#?F(dtlZ;8nG@y=_DUW?M;j_oLoo1=)_uU0x&`n0J zBwKgsig0A7QT{xtnyK;v#hs4}yBp8W1|6oZEL%njR&h3oqb{~9b8#-ihaW^h%HPBC z&OJAs=ojcsSe{`nj~zmEtuS>rAi07xFka`5ohVabSE1BrfPn8zd@d!sENmw_-ylHD zaop^^_~w~h`Q9elixdSIjSf6=5Vp*Qa#{g=zo)kJPu}|U@W%?}0HEqs6gR-MdWLW| zETe?>ggEDl6Xh3m`N z&QgO#rWhmcLchW3t7W!xQEi5lU>G$oziytCB(CY|uydzRK!?c0?9oPR;SAF1U}V=~z{2GT#S>)NYBbZ`#>excH^i0KUZtFs94 zJB4O*NeP?Y6$<;^RDT+T|Ehz4jTasjJ<#q%Cx!5qHk4%zdFlS~L#-8kM*#Dv$BV&~ zXZtq$Aw>W9d7gMih6sMLgL%wXU@9D`l7=ZR*4smvBCL7$JiVXw@@LLa!`8sW5!-9j zf%Pt^mq%*W-fsZ?M}aJ1yh{;Eg68Pn<@3ipbZ$?$u<})n=TTXdH%b5gk5gX7J(;Q* zuce9rKbb-u=0z26;jlR7gD_oUvBfOQqRwl#Li-Ky$H;oZ`O@hy`vw=Q zMNR8*T=M}%xrX8T^p#4F6JR(Iw zrP-b^g={m<3D{K3`}dU)ripBSa=dso5iqc(UB7$tihh&h_3Uff z66I_`w*$d0!1SJLX)M>tW5Yh*t;TbvqUqobm_wl1U8Kp`n|{>>PQKX`!EIyLhJ}zoJu_@;G+h zBBn*f((%ov=5(Z~;x4*^;dkE_B;&kHu?_@mP!cK!pct(;I~E95I(@0_B?_g|WqL^f z{4}dMMne%uiy_b$wTgjzj&u~zGx1RQ8!$YMl3it{6U#RS2Q(_%1bHa)*n;!ThMX;s zWzt!N%LqbrDiAD^_ocC{y=?v5XHJWiyK^&cA8I%jKTv3!$@C|*9A{oFoqm22yzuZi zxkOPYGj3dV&3q_#A=_N>4sgtkEYfECerM3~@T-F@Ngz0o{NFuaSc0o7m2KbVb!VsmkTP zT)F`DMsc`ru-t2ZTg zFT!F7Saj-42V*~`9-*S4E$9=cA+mQ7hr*=>qB@`G{jCjCZc#>KdE98rIMJrxW}|@? zaKdsC(V*@z2kdf48!^!a3tykBbPQn9K7Y1odL5(pFUjAzVz9-!PW(_{KDsT1femuV zg*6sR);X!YY4@4Q(l*cDpd)QQTAlKO*;6rdhPPF{KI8ue(EViiqIgjgUb~7V{ypG& zp{`(S@SBIyz5S+sSHVdDalB0C{jm$0uaOx0`sClcd&(`&{dEmEK(%+aJpW@)k;l3C zEZkC}eJWyY9_mYkKpm4jUx1eIH|}ljGmHwZI_1?} z#7=qUx`tk>hUewjw~8gd0rj6`oh9lHKNwvntV;<_udqE)FKnzyKlHu9ip?+?Q(NP? zh~tmaqeYMg%5O=RVX>Jn66;!-yf6Y zq;;0I0jeeV`XsRfSU6DAtc94i$WM6D+3Ug;!R4Dz_e3kE_AI?+O(a`RePL>aEsfFF z+h{%Rcu_Xw8exCo%X`KRJrdR?Qg32$%0Oi4RiZoQGys5%Q9-trwJhAphiv)5>% zf$}FGP}1v~s<|XBv`9Z*lhu6|bh^cRITPP_`Z0-4VE8@Br?-2E^r$8fMhS5Zgt>9$ z@q`#k=Ow^6{eqc*}Z0X*4w}%h@CYx=tagtZpysk`?mNK_SQIl-aaGjc9 zuGg~FDgqvR3tL3&bElgX^)6K@&TGP&H=6w5&hueL#eOIiT zV>?>Ce;AeF)0}C4N>yS{c)74e+j97vyFa+qYq`QJNuAW3U(X3jMtZin^y~{p&_f_h znrErQX-V(xmvHG7V*>33yc`9L(=izX6Yr=p~Q3QjRG4r{JOc7KZ zZO3hu?85bj1N;r^nKPv3T|=2TODd{R4jgQ0eB?d_elN`mHmQxswx?|h!azrXIe+-> zXl6x+_s!1H?=;V4Nd~_hmX??4D=n#1 z=`Jbax5jk;;%;QNXbp=v3wXF7J0bO|mX&ip*vZ}f_t+y$zF7NGt{KPZHDkY)!v7tsY{~71K^jGCifWLu3AY%oS2?0X898y zIRia0W}#+T7}n2f?Ld$z7-Oc{LpT5Z@;1QD=FoD_w`>@}+=-wvU&Y1{=dz5{!- z)ONC9804Dwu`-Sqq*vreW6UQc_oIX%&Mi{A(`7yq$z|i$VI79VFK&n+5ThYU_XNq; zi77!wlr>k#ofNrX3#g#s0gr^?bPGehlq@o=}LZ9Ee;5lxX4#1S-Rxziur`^ zKbyYlodxSA7>mM^R2>K;0#VW(Q}H4w<{gs2w!kRU{w93_2{vG)Ky(sq0IHSBu2e1u zw9|s-tS;<*F+rL9Eg}gQ+&La&o9JMn|HL~~>twqg{1+@#5NqC}27;g&C=kfQ)g6;Y zF>HlBpWkIGV<0+D=i4aryvh+9JL>l`wO&P%_3e1O3DWWx1#!|l^MqEwj4F6Ul@&5~ z%FNWWUZLS4Ke1`7M&_T%4klq==P)i#moXrE&V1J)(*~CiYXP3}=JvTF{hh^w)F3j~ zIlI0_-g&!t!+fx3zcgvHYJU%px#GB}f`@jc$%}!!l3Zb@&2T!oi5#5A3Srdx2-d(Y@o zS)`hDNs*msN+#)Gs=;Q9D&~)LYC7ap{#{%!l#LbytOXh~=hoF`_IbsF>=nSj0WD|c zsNgzg+gqaO0_@MjMHGuQ8_j9Rq=s?b(V)f>p?=25kG6r$CfW(Zr|X^mkN4L<@VY+M zWT+jw=do6_HPu@p>iRmm5mYftgBx2m_jNyi`E*iEn7dx|u%8?zAR!ty + + + + + edge0 + OpenEMS Edge #0 + DEMO_API_KEY + + + + diff --git a/addons/openems/data/ir_config_parameter.xml b/addons/openems/data/ir_config_parameter.xml new file mode 100644 index 0000000..b1da5cf --- /dev/null +++ b/addons/openems/data/ir_config_parameter.xml @@ -0,0 +1,9 @@ + + + + + edge_monitoring_url + http://localhost:8082/device/ + + + diff --git a/addons/openems/data/res_partner_category.xml b/addons/openems/data/res_partner_category.xml new file mode 100644 index 0000000..f56c0e0 --- /dev/null +++ b/addons/openems/data/res_partner_category.xml @@ -0,0 +1,11 @@ + + + + + Created via IBN + + + Customer + + + diff --git a/addons/openems/i18n/de.po b/addons/openems/i18n/de.po new file mode 100644 index 0000000..cc4c660 --- /dev/null +++ b/addons/openems/i18n/de.po @@ -0,0 +1,1666 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * openems +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 16.0-20240218\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2024-02-18 11:57+0000\n" +"PO-Revision-Date: 2024-02-18 11:57+0000\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: openems +#: model:mail.template,body_html:openems.setup_protocol_email_installer +msgid "" +"\n" +"\n" +"\n" +"\n" +"\n" +" OpenEMS setup protocol \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +"\n" +"\n" +"\n" +"

\n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +"
\n" +" \n" +"
\n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +"
\n" +" \n" +"
\n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +"
\n" +"

\n" +"

\n" +" \n" +"
\n" +"
Dear \n" +" ,\n" +"
\n" +"
\n" +"
please find the setup protocol for your customer attached.\n" +"
\n" +"
\n" +"
Best Regards
\n" +"
\n" +"
OpenEMS Association e.V.
\n" +"
\n" +"
\n" +" \n" +"
\n" +"
\n" +" \n" +"
\n" +"
\n" +"\n" +"\n" +"\n" +" \n" +" " +msgstr "" + +#. module: openems +#: model:mail.template,body_html:openems.registration_email +msgid "" +"\n" +"\n" +"\n" +"\n" +"\n" +" Registrierung erfolgreich \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +"\n" +"\n" +"\n" +"
\n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +"
\n" +" \n" +"
\n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +"
\n" +" \n" +"
\n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +"
\n" +"

\n" +"

\n" +" \n" +"
\n" +"
Guten Tag \n" +" ,\n" +"
\n" +"
\n" +"
Ihr Zugang zu OpenEMS UI wurde erstellt.
\n" +"
\n" +"
Sie können sich auf OpenEMS UI einloggen, um auf das Online-Monitoring zuzugreifen.
\n" +"
\n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +"
Ihre Zugangsdaten:
E-Mail\n" +" \n" +"
Passwort\n" +" \n" +"
\n" +"
\n" +"
Best Regards
\n" +"
\n" +"
OpenEMS Association e.V.
\n" +"
\n" +"
\n" +" \n" +"
\n" +"
\n" +" \n" +"
\n" +"
\n" +"\n" +"\n" +"\n" +" \n" +" " +msgstr "" + +#. module: openems +#: model:mail.template,body_html:openems.setup_protocol_email_customer +msgid "" +"\n" +"\n" +"\n" +"\n" +"\n" +" Your OpenEMS Edge setup protocol \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +"\n" +"\n" +"\n" +"
\n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +"
\n" +" \n" +"
\n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +"
\n" +" \n" +"
\n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +"
\n" +"

\n" +"

\n" +" \n" +"
\n" +"
Welcome to OpenEMS,
\n" +"
\n" +"
please find your setup protocol for OpenEMS Edge attached.
\n" +"
\n" +"
Best Regards
\n" +"
\n" +"
OpenEMS Association e.V.
\n" +"
\n" +"
\n" +" \n" +"
\n" +"
\n" +" \n" +"
\n" +"
\n" +"\n" +"\n" +"\n" +" \n" +" " +msgstr "" + +#. module: openems +#: model:mail.template,body_html:openems.alerting_email_generic +msgid "" +"\n" +"\n" +"\n" +"\n" +"\n" +" OpenEMS Alert - Edge is offline\n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +"\n" +"\n" +"\n" +"
\n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +"
\n" +" \n" +"
\n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +"
\n" +" \n" +"
\n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +"
\n" +"

\n" +"

\n" +" \n" +"
\n" +"
Dear \n" +" ,\n" +"
\n" +"
\n" +"
Your OpenEMS Edge with number is offline since:
\n" +"
\n" +"
\n" +" \n" +" \n" +" \n" +" \n" +" \n" +" (UTC)\n" +" \n" +"
\n" +"
\n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +"
Info
\n" +" Edge-Version\n" +" \n" +" \n" +"
\n" +" Type\n" +" \n" +" \n" +" \n" +"
\n" +"
\n" +"
Best Regards
\n" +"
\n" +"
OpenEMS Association e.V.
\n" +"
\n" +"
\n" +" \n" +"
\n" +"
\n" +" \n" +"
\n" +" \n" +"
\n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +"
\n" +" \n" +"
\n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +"
\n" +"
Wenn Sie keine E-Mail Benachrichtigung mehr wünschen, können Sie die Funktion hier deaktivieren.
\n" +"
\n" +"
Dies ist eine automatisch generierte Nachricht. Bitte antworten Sie nicht auf diese Nachricht!
\n" +"
\n" +"
\n" +" \n" +"
\n" +"
\n" +" \n" +"
\n" +"\n" +"\n" +"\n" +" \n" +" " +msgstr "" + +#. module: openems +#: model:ir.actions.report,print_report_name:openems.action_openems_setup_protocol_report +msgid "" +"('IBN-' + object.openems_device_id.name + '-' + " +"object.create_date.strftime('%d.%m.%Y'))" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__apikey +msgid "API-Key" +msgstr "" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.openems_device_form +msgid "Access Role in Online-Monitoring" +msgstr "Zugriffsrollen im Online-Monitoring" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__message_needaction +msgid "Action Needed" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__active +msgid "Active" +msgstr "" + +#. module: openems +#: model:ir.model.fields.selection,name:openems.selection__openems_device_user_role__role__admin +#: model:ir.model.fields.selection,name:openems.selection__res_users__global_role__admin +msgid "Admin" +msgstr "" + +#. module: openems +#: model:ir.ui.menu,name:openems.menu_openems_admin +msgid "Administration" +msgstr "" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.device_search_view +msgid "Archived" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__message_attachment_count +msgid "Attachment Count" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_res_users__branding_partner_id +msgid "Branding Partner" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol_item__category +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol_production_lot__category +msgid "Category" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__comment +msgid "Comment" +msgstr "" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.openems_device_form +msgid "Configuration" +msgstr "Konfiguration" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.openems_device_form +msgid "Configuration Updates" +msgstr "Konfigurationsänderungen" + +#. module: openems +#: model:ir.model,name:openems.model_res_partner +msgid "Contact" +msgstr "Kontakt" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__create_uid +#: model:ir.model.fields,field_description:openems.field_openems_device_tag__create_uid +#: model:ir.model.fields,field_description:openems.field_openems_device_user_role__create_uid +#: model:ir.model.fields,field_description:openems.field_openems_openemsconfigupdate__create_uid +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol__create_uid +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol_item__create_uid +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol_production_lot__create_uid +#: model:ir.model.fields,field_description:openems.field_openems_systemmessage__create_uid +msgid "Created by" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__create_date +#: model:ir.model.fields,field_description:openems.field_openems_device_tag__create_date +#: model:ir.model.fields,field_description:openems.field_openems_device_user_role__create_date +#: model:ir.model.fields,field_description:openems.field_openems_openemsconfigupdate__create_date +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol__create_date +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol_item__create_date +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol_production_lot__create_date +#: model:ir.model.fields,field_description:openems.field_openems_systemmessage__create_date +msgid "Created on" +msgstr "" + +#. module: openems +#: model:res.partner.category,name:openems.res_partner_category_created_via_ibn +msgid "Created via IBN" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_systemmessage__timestamp +msgid "Creation date" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol__customer_id +#: model:res.partner.category,name:openems.res_partner_category_customer +msgid "Customer" +msgstr "" + +#. module: openems +#: model:ir.model.fields.selection,name:openems.selection__res_users__openems_language__cz +msgid "Czech" +msgstr "" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.report_openems_setup_protocol_template +msgid "Datum:" +msgstr "" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.device_search_view +#: model_terms:ir.ui.view,arch_db:openems.openems_device_tree +msgid "Description" +msgstr "Bezeichnung" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.openems_openemsconfigupdate_tree +msgid "Details" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_stock_lot__device_id +#: model:ir.model.fields,field_description:openems.field_stock_lot__device_ids +msgid "Device" +msgstr "" + +#. module: openems +#: model:ir.actions.act_window,name:openems.action_openems_openemsconfigupdate +#: model:ir.ui.menu,name:openems.menu_openems_admin_openemsconfigupdate +msgid "Device Configuration Updates" +msgstr "" + +#. module: openems +#: model:ir.actions.act_window,name:openems.action_openems_device +#: model:ir.ui.menu,name:openems.menu_openems_content_devices +msgid "Devices" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol__different_location_id +msgid "Different Location" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__display_name +#: model:ir.model.fields,field_description:openems.field_openems_device_tag__display_name +#: model:ir.model.fields,field_description:openems.field_openems_device_user_role__display_name +#: model:ir.model.fields,field_description:openems.field_openems_openemsconfigupdate__display_name +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol__display_name +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol_item__display_name +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol_production_lot__display_name +#: model:ir.model.fields,field_description:openems.field_openems_systemmessage__display_name +msgid "Display Name" +msgstr "" + +#. module: openems +#: model:ir.model.fields.selection,name:openems.selection__res_users__openems_language__nl +msgid "Dutch" +msgstr "" + +#. module: openems +#: model:mail.template,name:openems.alerting_email_generic +msgid "E-Mail Alerting" +msgstr "" + +#. module: openems +#: model:mail.template,name:openems.registration_email +msgid "E-Mail Kunden Registrierung" +msgstr "" + +#. module: openems +#: model:mail.template,name:openems.setup_protocol_email_customer +msgid "E-Mail setup protocol for customer" +msgstr "" + +#. module: openems +#: model:mail.template,name:openems.setup_protocol_email_installer +msgid "E-Mail setup protocol for installer" +msgstr "" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.report_openems_setup_protocol_template +msgid "E-Mail-Adresse" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__emshardware +msgid "EMS Hardware" +msgstr "" + +#. module: openems +#: model:ir.model.fields.selection,name:openems.selection__res_users__openems_language__en +msgid "English" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol__item_ids +msgid "Entry Items" +msgstr "" + +#. module: openems +#: model:ir.model.fields.selection,name:openems.selection__openems_device__openems_sum_state_level__fault +msgid "Fault" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol_item__field +msgid "Field Identifier" +msgstr "" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.report_openems_setup_protocol_template +msgid "Firmenname" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__first_setup_protocol_date +msgid "First Setup Protocol Date" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__message_follower_ids +msgid "Followers" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__message_partner_ids +msgid "Followers (Partners)" +msgstr "" + +#. module: openems +#: model:ir.model.fields.selection,name:openems.selection__res_users__openems_language__fr +msgid "French" +msgstr "" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.openems_device_form +msgid "General" +msgstr "" + +#. module: openems +#: model:ir.model.fields.selection,name:openems.selection__res_users__openems_language__de +msgid "German" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_res_users__global_role +msgid "Global Role" +msgstr "" + +#. module: openems +#: model:ir.model.fields.selection,name:openems.selection__openems_device_user_role__role__guest +#: model:ir.model.fields.selection,name:openems.selection__res_users__global_role__guest +msgid "Guest" +msgstr "" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.openems_device_form +msgid "Hardware" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__has_message +msgid "Has Message" +msgstr "" + +#. module: openems +#: model:ir.model.fields.selection,name:openems.selection__res_users__openems_language__hu +msgid "Hungarian" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__id +#: model:ir.model.fields,field_description:openems.field_openems_device_tag__id +#: model:ir.model.fields,field_description:openems.field_openems_device_user_role__id +#: model:ir.model.fields,field_description:openems.field_openems_openemsconfigupdate__id +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol__id +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol_item__id +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol_production_lot__id +#: model:ir.model.fields,field_description:openems.field_openems_systemmessage__id +msgid "ID" +msgstr "" + +#. module: openems +#: model:ir.model.fields,help:openems.field_openems_device__message_needaction +msgid "If checked, new messages require your attention." +msgstr "" + +#. module: openems +#: model:ir.model.fields,help:openems.field_openems_device__message_has_error +#: model:ir.model.fields,help:openems.field_openems_device__message_has_sms_error +msgid "If checked, some messages have a delivery error." +msgstr "" + +#. module: openems +#: model:ir.model.fields.selection,name:openems.selection__openems_device__openems_sum_state_level__info +msgid "Info" +msgstr "" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.report_openems_setup_protocol_template +msgid "Installateur" +msgstr "" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.openems_device_form +msgid "Installation" +msgstr "Inbetriebnahme" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.openems_device_form +msgid "Installation Log" +msgstr "Inbetriebnahme Protokolle" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__setup_password +msgid "Installation key" +msgstr "Installateursschlüssel" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_res_partner__installer_setup_protocols_ids +#: model:ir.model.fields,field_description:openems.field_res_users__installer_setup_protocols_ids +msgid "Installed OpenEMS Edge" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol__installer_id +#: model:ir.model.fields.selection,name:openems.selection__openems_device_user_role__role__installer +#: model:ir.model.fields.selection,name:openems.selection__res_users__global_role__installer +msgid "Installer" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__internalnote +msgid "Internal note" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__message_is_follower +msgid "Is Follower" +msgstr "" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.openems_device_form +msgid "Is connected" +msgstr "" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.report_openems_setup_protocol_template +msgid "Kontaktdaten Endkunde" +msgstr "" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.report_openems_setup_protocol_template +msgid "Land" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device____last_update +#: model:ir.model.fields,field_description:openems.field_openems_device_tag____last_update +#: model:ir.model.fields,field_description:openems.field_openems_device_user_role____last_update +#: model:ir.model.fields,field_description:openems.field_openems_openemsconfigupdate____last_update +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol____last_update +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol_item____last_update +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol_production_lot____last_update +#: model:ir.model.fields,field_description:openems.field_openems_systemmessage____last_update +msgid "Last Modified on" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__write_uid +#: model:ir.model.fields,field_description:openems.field_openems_device_tag__write_uid +#: model:ir.model.fields,field_description:openems.field_openems_device_user_role__write_uid +#: model:ir.model.fields,field_description:openems.field_openems_openemsconfigupdate__write_uid +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol__write_uid +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol_item__write_uid +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol_production_lot__write_uid +#: model:ir.model.fields,field_description:openems.field_openems_systemmessage__write_uid +msgid "Last Updated by" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__write_date +#: model:ir.model.fields,field_description:openems.field_openems_device_tag__write_date +#: model:ir.model.fields,field_description:openems.field_openems_device_user_role__write_date +#: model:ir.model.fields,field_description:openems.field_openems_openemsconfigupdate__write_date +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol__write_date +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol_item__write_date +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol_production_lot__write_date +#: model:ir.model.fields,field_description:openems.field_openems_systemmessage__write_date +msgid "Last Updated on" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__lastupdate +msgid "Last data update" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__lastmessage +msgid "Last message" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device_user_role__last_notification +msgid "Last notification sent" +msgstr "" + +#. module: openems +#: model:ir.model,name:openems.model_stock_lot +msgid "Lot/Serial" +msgstr "Los/Serie" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__message_main_attachment_id +msgid "Main Attachment" +msgstr "" + +#. module: openems +#: model:res.groups,name:openems.group_openems_manager +msgid "Manager" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__manual_setup_date +msgid "Manual Setup Date" +msgstr "" + +#. module: openems +#: model:res.groups,comment:openems.group_openems_manager +msgid "Members of this group can manage all devices" +msgstr "" + +#. module: openems +#: model:res.groups,comment:openems.group_openems_reader +msgid "Members of this group have reading access to all devices" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_systemmessage__text +msgid "Message" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__message_has_error +msgid "Message Delivery error" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__message_ids +msgid "Messages" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__name +#: model:ir.model.fields,field_description:openems.field_openems_device_tag__name +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol_item__name +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol_production_lot__name +msgid "Name" +msgstr "" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.report_openems_setup_protocol_template +msgid "Name Installateur" +msgstr "" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.report_openems_setup_protocol_template +msgid "Name Kontaktperson" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__name_number +msgid "Name Number" +msgstr "" + +#. module: openems +#: model:ir.model.constraint,message:openems.constraint_openems_device_unique_name +msgid "Name needs to be unique" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device_user_role__time_to_wait +msgid "Notification" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__message_needaction_counter +msgid "Number of Actions" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__message_has_error_counter +msgid "Number of errors" +msgstr "" + +#. module: openems +#: model:ir.model.fields,help:openems.field_openems_device__message_needaction_counter +msgid "Number of messages requiring action" +msgstr "" + +#. module: openems +#: model:ir.model.fields,help:openems.field_openems_device__message_has_error_counter +msgid "Number of messages with delivery error" +msgstr "" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.openems_device_tree +msgid "OE Connected" +msgstr "" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.openems_device_tree +msgid "OE State" +msgstr "" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.openems_device_tree +msgid "OE Version" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__oem +msgid "OEM Branding" +msgstr "" + +#. module: openems +#: model:ir.model.fields.selection,name:openems.selection__openems_device__openems_sum_state_level__ok +msgid "Ok" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__monitoring_url +msgid "Online-Monitoring" +msgstr "" + +#. module: openems +#: model:ir.model.fields.selection,name:openems.selection__openems_device__oem__openems +#: model:ir.module.category,name:openems.module_category_openems +#: model:ir.ui.menu,name:openems.menu_openems +#: model_terms:ir.ui.view,arch_db:openems.openems_users_form +msgid "OpenEMS" +msgstr "" + +#. module: openems +#: model:mail.template,subject:openems.alerting_email_generic +msgid "OpenEMS Alert - Edge is offline" +msgstr "" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.report_openems_setup_protocol_template +msgid "OpenEMS Association e.V." +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__openems_config_components +msgid "OpenEMS Config" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__openems_config +msgid "OpenEMS Config Full" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__openems_config_update_ids +msgid "OpenEMS Config Updates" +msgstr "" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.openems_openemsconfigupdate_tree +msgid "OpenEMS Configuration Updates" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device_user_role__device_id +#: model:ir.model.fields,field_description:openems.field_openems_openemsconfigupdate__device_id +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol__device_id +#: model:ir.model.fields,field_description:openems.field_openems_systemmessage__device_id +#: model:ir.model.fields.selection,name:openems.selection__openems_device__producttype__openems-edge +#: model:ir.ui.menu,name:openems.menu_openems_content +msgid "OpenEMS Edge" +msgstr "" + +#. module: openems +#: model:ir.model,name:openems.model_openems_device +msgid "OpenEMS Edge Device" +msgstr "" + +#. module: openems +#: model:ir.model,name:openems.model_openems_openemsconfigupdate +msgid "OpenEMS Edge Device Configuration Update" +msgstr "" + +#. module: openems +#: model:ir.model,name:openems.model_openems_device_tag +msgid "OpenEMS Edge Device Tag" +msgstr "" + +#. module: openems +#: model:ir.model,name:openems.model_openems_device_user_role +msgid "OpenEMS Edge Device User Role" +msgstr "" + +#. module: openems +#: model:ir.model,name:openems.model_openems_setup_protocol_item +msgid "OpenEMS Edge Setup Protocol Entry Item" +msgstr "" + +#. module: openems +#: model:ir.model,name:openems.model_openems_setup_protocol_production_lot +msgid "OpenEMS Edge Setup Protocol Serial Number" +msgstr "" + +#. module: openems +#: model:ir.model,name:openems.model_openems_setup_protocol +msgid "OpenEMS Edge Setup Protocols (IBN)" +msgstr "" + +#. module: openems +#: model:ir.model,name:openems.model_openems_systemmessage +msgid "OpenEMS Edge Systemmessage" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__openems_is_connected +msgid "OpenEMS Is connected" +msgstr "" + +#. module: openems +#: model:ir.actions.report,name:openems.action_openems_setup_protocol_report +msgid "OpenEMS Setup Protocol" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__openems_sum_state_level +msgid "OpenEMS State" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__openems_version +#: model_terms:ir.ui.view,arch_db:openems.device_search_view +msgid "OpenEMS Version" +msgstr "" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.device_search_view +#: model_terms:ir.ui.view,arch_db:openems.openems_device_tree +msgid "OpenEMS-Number" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_res_users__openems_language +msgid "Openems Language" +msgstr "" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.report_openems_setup_protocol_template +msgid "Ort" +msgstr "" + +#. module: openems +#: model:ir.model.fields.selection,name:openems.selection__openems_device_user_role__role__owner +#: model:ir.model.fields.selection,name:openems.selection__res_users__global_role__owner +msgid "Owner" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_res_partner__customer_setup_protocols_ids +#: model:ir.model.fields,field_description:openems.field_res_users__customer_setup_protocols_ids +msgid "Owner of OpenEMS Edge" +msgstr "" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.report_openems_setup_protocol_template +msgid "PLZ" +msgstr "" + +#. module: openems +#: model:ir.model.fields,help:openems.field_openems_device__setup_password +msgid "Password for commissioning by the installer" +msgstr "Passwort für die Inbetriebnahme durch den Installateur" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.openems_setup_protocol_form +msgid "Print" +msgstr "" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.openems_device_form +msgid "Product" +msgstr "Produkt" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__producttype +msgid "Product type" +msgstr "" + +#. module: openems +#: model:res.groups,name:openems.group_openems_reader +msgid "Read access" +msgstr "" + +#. module: openems +#: model:mail.template,subject:openems.registration_email +msgid "Registrierung erfolgreich" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device_user_role__role +msgid "Role" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__user_role_ids +#: model:ir.model.fields,field_description:openems.field_res_users__device_role_ids +msgid "Roles" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__message_has_sms_error +msgid "SMS Delivery error" +msgstr "" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.openems_device_form +msgid "Security" +msgstr "Sicherheit" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol_production_lot__lot_id +msgid "Serial Number" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol__productionlot_ids +msgid "Serial Numbers" +msgstr "" + +#. module: openems +#: model:ir.model.constraint,message:openems.constraint_openems_device_unique_stock_production_lot_id +msgid "Serial number needs to be unique" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol_item__setup_protocol_id +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol_production_lot__setup_protocol_id +#: model_terms:ir.ui.view,arch_db:openems.report_openems_setup_protocol_template +msgid "Setup Protocol" +msgstr "" + +#. module: openems +#: model:ir.actions.act_window,name:openems.action_openems_admin_setup_protocol +#: model:ir.model.fields,field_description:openems.field_openems_device__setup_protocol_ids +#: model:ir.ui.menu,name:openems.menu_openems_admin_setup_protocol +#: model_terms:ir.ui.view,arch_db:openems.res_partner_form +msgid "Setup Protocols" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol_item__sequence +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol_production_lot__sequence +msgid "Sort" +msgstr "" + +#. module: openems +#: model:ir.model.fields.selection,name:openems.selection__res_users__openems_language__es +msgid "Spanish" +msgstr "" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.report_openems_setup_protocol_template +msgid "Speicherstandort" +msgstr "" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.openems_device_form +msgid "Status" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__stock_production_lot_id +msgid "Stock Production Lot" +msgstr "" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.report_openems_setup_protocol_template +msgid "Straße / Hausnummer" +msgstr "" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.openems_device_form +msgid "System Messages" +msgstr "" + +#. module: openems +#: model:ir.actions.act_window,name:openems.action_openems_systemmessage +#: model:ir.model.fields,field_description:openems.field_openems_device__systemmessage_ids +#: model:ir.ui.menu,name:openems.menu_openems_admin_systemmessages +msgid "Systemmessages" +msgstr "" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.openems_device_form +msgid "Systemstatus" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__tag_ids +msgid "Tags" +msgstr "" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.report_openems_setup_protocol_template +msgid "Telefonnummer" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_systemmessage__text_teaser +msgid "Text Teaser" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_openemsconfigupdate__details +msgid "Update Details" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_openemsconfigupdate__teaser +msgid "Update Details Teaser" +msgstr "" + +#. module: openems +#: model:ir.model,name:openems.model_res_users +#: model:ir.model.fields,field_description:openems.field_openems_device_user_role__user_id +msgid "User" +msgstr "Benutzer" + +#. module: openems +#: model:ir.model.constraint,message:openems.constraint_openems_device_user_role_device_user_uniq +msgid "User already exists for this device." +msgstr "" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.openems_systemmessage_tree +msgid "Users" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol_item__value +msgid "Value" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol_item__view +msgid "View Identifier" +msgstr "" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.report_openems_setup_protocol_template +msgid "Vor- Nachname" +msgstr "" + +#. module: openems +#: model:ir.model.fields.selection,name:openems.selection__openems_device__openems_sum_state_level__warning +msgid "Warning" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__website_message_ids +msgid "Website Messages" +msgstr "" + +#. module: openems +#: model:ir.model.fields,help:openems.field_openems_device__website_message_ids +msgid "Website communication history" +msgstr "" + +#. module: openems +#: model:mail.template,subject:openems.setup_protocol_email_customer +#: model:mail.template,subject:openems.setup_protocol_email_installer +msgid "Your OpenEMS setup protocol for {{object.openems_device_id.name}}" +msgstr "" diff --git a/addons/openems/i18n/openems.pot b/addons/openems/i18n/openems.pot new file mode 100644 index 0000000..c02fb93 --- /dev/null +++ b/addons/openems/i18n/openems.pot @@ -0,0 +1,1666 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * openems +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 16.0-20240218\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2024-02-18 11:56+0000\n" +"PO-Revision-Date: 2024-02-18 11:56+0000\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: openems +#: model:mail.template,body_html:openems.setup_protocol_email_installer +msgid "" +"\n" +"\n" +"\n" +"\n" +"\n" +" OpenEMS setup protocol \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +"\n" +"\n" +"\n" +"
\n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +"
\n" +" \n" +"
\n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +"
\n" +" \n" +"
\n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +"
\n" +"

\n" +"

\n" +" \n" +"
\n" +"
Dear \n" +" ,\n" +"
\n" +"
\n" +"
please find the setup protocol for your customer attached.\n" +"
\n" +"
\n" +"
Best Regards
\n" +"
\n" +"
OpenEMS Association e.V.
\n" +"
\n" +"
\n" +" \n" +"
\n" +"
\n" +" \n" +"
\n" +"
\n" +"\n" +"\n" +"\n" +" \n" +" " +msgstr "" + +#. module: openems +#: model:mail.template,body_html:openems.registration_email +msgid "" +"\n" +"\n" +"\n" +"\n" +"\n" +" Registrierung erfolgreich \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +"\n" +"\n" +"\n" +"
\n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +"
\n" +" \n" +"
\n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +"
\n" +" \n" +"
\n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +"
\n" +"

\n" +"

\n" +" \n" +"
\n" +"
Guten Tag \n" +" ,\n" +"
\n" +"
\n" +"
Ihr Zugang zu OpenEMS UI wurde erstellt.
\n" +"
\n" +"
Sie können sich auf OpenEMS UI einloggen, um auf das Online-Monitoring zuzugreifen.
\n" +"
\n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +"
Ihre Zugangsdaten:
E-Mail\n" +" \n" +"
Passwort\n" +" \n" +"
\n" +"
\n" +"
Best Regards
\n" +"
\n" +"
OpenEMS Association e.V.
\n" +"
\n" +"
\n" +" \n" +"
\n" +"
\n" +" \n" +"
\n" +"
\n" +"\n" +"\n" +"\n" +" \n" +" " +msgstr "" + +#. module: openems +#: model:mail.template,body_html:openems.setup_protocol_email_customer +msgid "" +"\n" +"\n" +"\n" +"\n" +"\n" +" Your OpenEMS Edge setup protocol \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +"\n" +"\n" +"\n" +"
\n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +"
\n" +" \n" +"
\n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +"
\n" +" \n" +"
\n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +"
\n" +"

\n" +"

\n" +" \n" +"
\n" +"
Welcome to OpenEMS,
\n" +"
\n" +"
please find your setup protocol for OpenEMS Edge attached.
\n" +"
\n" +"
Best Regards
\n" +"
\n" +"
OpenEMS Association e.V.
\n" +"
\n" +"
\n" +" \n" +"
\n" +"
\n" +" \n" +"
\n" +"
\n" +"\n" +"\n" +"\n" +" \n" +" " +msgstr "" + +#. module: openems +#: model:mail.template,body_html:openems.alerting_email_generic +msgid "" +"\n" +"\n" +"\n" +"\n" +"\n" +" OpenEMS Alert - Edge is offline\n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +"\n" +"\n" +"\n" +"
\n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +"
\n" +" \n" +"
\n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +"
\n" +" \n" +"
\n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +"
\n" +"

\n" +"

\n" +" \n" +"
\n" +"
Dear \n" +" ,\n" +"
\n" +"
\n" +"
Your OpenEMS Edge with number is offline since:
\n" +"
\n" +"
\n" +" \n" +" \n" +" \n" +" \n" +" \n" +" (UTC)\n" +" \n" +"
\n" +"
\n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +"
Info
\n" +" Edge-Version\n" +" \n" +" \n" +"
\n" +" Type\n" +" \n" +" \n" +" \n" +"
\n" +"
\n" +"
Best Regards
\n" +"
\n" +"
OpenEMS Association e.V.
\n" +"
\n" +"
\n" +" \n" +"
\n" +"
\n" +" \n" +"
\n" +" \n" +"
\n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +"
\n" +" \n" +"
\n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +"
\n" +"
Wenn Sie keine E-Mail Benachrichtigung mehr wünschen, können Sie die Funktion hier deaktivieren.
\n" +"
\n" +"
Dies ist eine automatisch generierte Nachricht. Bitte antworten Sie nicht auf diese Nachricht!
\n" +"
\n" +"
\n" +" \n" +"
\n" +"
\n" +" \n" +"
\n" +"\n" +"\n" +"\n" +" \n" +" " +msgstr "" + +#. module: openems +#: model:ir.actions.report,print_report_name:openems.action_openems_setup_protocol_report +msgid "" +"('IBN-' + object.openems_device_id.name + '-' + " +"object.create_date.strftime('%d.%m.%Y'))" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__apikey +msgid "API-Key" +msgstr "" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.openems_device_form +msgid "Access Role in Online-Monitoring" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__message_needaction +msgid "Action Needed" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__active +msgid "Active" +msgstr "" + +#. module: openems +#: model:ir.model.fields.selection,name:openems.selection__openems_device_user_role__role__admin +#: model:ir.model.fields.selection,name:openems.selection__res_users__global_role__admin +msgid "Admin" +msgstr "" + +#. module: openems +#: model:ir.ui.menu,name:openems.menu_openems_admin +msgid "Administration" +msgstr "" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.device_search_view +msgid "Archived" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__message_attachment_count +msgid "Attachment Count" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_res_users__branding_partner_id +msgid "Branding Partner" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol_item__category +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol_production_lot__category +msgid "Category" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__comment +msgid "Comment" +msgstr "" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.openems_device_form +msgid "Configuration" +msgstr "" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.openems_device_form +msgid "Configuration Updates" +msgstr "" + +#. module: openems +#: model:ir.model,name:openems.model_res_partner +msgid "Contact" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__create_uid +#: model:ir.model.fields,field_description:openems.field_openems_device_tag__create_uid +#: model:ir.model.fields,field_description:openems.field_openems_device_user_role__create_uid +#: model:ir.model.fields,field_description:openems.field_openems_openemsconfigupdate__create_uid +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol__create_uid +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol_item__create_uid +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol_production_lot__create_uid +#: model:ir.model.fields,field_description:openems.field_openems_systemmessage__create_uid +msgid "Created by" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__create_date +#: model:ir.model.fields,field_description:openems.field_openems_device_tag__create_date +#: model:ir.model.fields,field_description:openems.field_openems_device_user_role__create_date +#: model:ir.model.fields,field_description:openems.field_openems_openemsconfigupdate__create_date +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol__create_date +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol_item__create_date +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol_production_lot__create_date +#: model:ir.model.fields,field_description:openems.field_openems_systemmessage__create_date +msgid "Created on" +msgstr "" + +#. module: openems +#: model:res.partner.category,name:openems.res_partner_category_created_via_ibn +msgid "Created via IBN" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_systemmessage__timestamp +msgid "Creation date" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol__customer_id +#: model:res.partner.category,name:openems.res_partner_category_customer +msgid "Customer" +msgstr "" + +#. module: openems +#: model:ir.model.fields.selection,name:openems.selection__res_users__openems_language__cz +msgid "Czech" +msgstr "" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.report_openems_setup_protocol_template +msgid "Datum:" +msgstr "" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.device_search_view +#: model_terms:ir.ui.view,arch_db:openems.openems_device_tree +msgid "Description" +msgstr "" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.openems_openemsconfigupdate_tree +msgid "Details" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_stock_lot__device_id +#: model:ir.model.fields,field_description:openems.field_stock_lot__device_ids +msgid "Device" +msgstr "" + +#. module: openems +#: model:ir.actions.act_window,name:openems.action_openems_openemsconfigupdate +#: model:ir.ui.menu,name:openems.menu_openems_admin_openemsconfigupdate +msgid "Device Configuration Updates" +msgstr "" + +#. module: openems +#: model:ir.actions.act_window,name:openems.action_openems_device +#: model:ir.ui.menu,name:openems.menu_openems_content_devices +msgid "Devices" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol__different_location_id +msgid "Different Location" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__display_name +#: model:ir.model.fields,field_description:openems.field_openems_device_tag__display_name +#: model:ir.model.fields,field_description:openems.field_openems_device_user_role__display_name +#: model:ir.model.fields,field_description:openems.field_openems_openemsconfigupdate__display_name +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol__display_name +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol_item__display_name +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol_production_lot__display_name +#: model:ir.model.fields,field_description:openems.field_openems_systemmessage__display_name +msgid "Display Name" +msgstr "" + +#. module: openems +#: model:ir.model.fields.selection,name:openems.selection__res_users__openems_language__nl +msgid "Dutch" +msgstr "" + +#. module: openems +#: model:mail.template,name:openems.alerting_email_generic +msgid "E-Mail Alerting" +msgstr "" + +#. module: openems +#: model:mail.template,name:openems.registration_email +msgid "E-Mail Kunden Registrierung" +msgstr "" + +#. module: openems +#: model:mail.template,name:openems.setup_protocol_email_customer +msgid "E-Mail setup protocol for customer" +msgstr "" + +#. module: openems +#: model:mail.template,name:openems.setup_protocol_email_installer +msgid "E-Mail setup protocol for installer" +msgstr "" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.report_openems_setup_protocol_template +msgid "E-Mail-Adresse" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__emshardware +msgid "EMS Hardware" +msgstr "" + +#. module: openems +#: model:ir.model.fields.selection,name:openems.selection__res_users__openems_language__en +msgid "English" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol__item_ids +msgid "Entry Items" +msgstr "" + +#. module: openems +#: model:ir.model.fields.selection,name:openems.selection__openems_device__openems_sum_state_level__fault +msgid "Fault" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol_item__field +msgid "Field Identifier" +msgstr "" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.report_openems_setup_protocol_template +msgid "Firmenname" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__first_setup_protocol_date +msgid "First Setup Protocol Date" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__message_follower_ids +msgid "Followers" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__message_partner_ids +msgid "Followers (Partners)" +msgstr "" + +#. module: openems +#: model:ir.model.fields.selection,name:openems.selection__res_users__openems_language__fr +msgid "French" +msgstr "" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.openems_device_form +msgid "General" +msgstr "" + +#. module: openems +#: model:ir.model.fields.selection,name:openems.selection__res_users__openems_language__de +msgid "German" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_res_users__global_role +msgid "Global Role" +msgstr "" + +#. module: openems +#: model:ir.model.fields.selection,name:openems.selection__openems_device_user_role__role__guest +#: model:ir.model.fields.selection,name:openems.selection__res_users__global_role__guest +msgid "Guest" +msgstr "" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.openems_device_form +msgid "Hardware" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__has_message +msgid "Has Message" +msgstr "" + +#. module: openems +#: model:ir.model.fields.selection,name:openems.selection__res_users__openems_language__hu +msgid "Hungarian" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__id +#: model:ir.model.fields,field_description:openems.field_openems_device_tag__id +#: model:ir.model.fields,field_description:openems.field_openems_device_user_role__id +#: model:ir.model.fields,field_description:openems.field_openems_openemsconfigupdate__id +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol__id +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol_item__id +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol_production_lot__id +#: model:ir.model.fields,field_description:openems.field_openems_systemmessage__id +msgid "ID" +msgstr "" + +#. module: openems +#: model:ir.model.fields,help:openems.field_openems_device__message_needaction +msgid "If checked, new messages require your attention." +msgstr "" + +#. module: openems +#: model:ir.model.fields,help:openems.field_openems_device__message_has_error +#: model:ir.model.fields,help:openems.field_openems_device__message_has_sms_error +msgid "If checked, some messages have a delivery error." +msgstr "" + +#. module: openems +#: model:ir.model.fields.selection,name:openems.selection__openems_device__openems_sum_state_level__info +msgid "Info" +msgstr "" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.report_openems_setup_protocol_template +msgid "Installateur" +msgstr "" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.openems_device_form +msgid "Installation" +msgstr "" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.openems_device_form +msgid "Installation Log" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__setup_password +msgid "Installation key" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_res_partner__installer_setup_protocols_ids +#: model:ir.model.fields,field_description:openems.field_res_users__installer_setup_protocols_ids +msgid "Installed OpenEMS Edge" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol__installer_id +#: model:ir.model.fields.selection,name:openems.selection__openems_device_user_role__role__installer +#: model:ir.model.fields.selection,name:openems.selection__res_users__global_role__installer +msgid "Installer" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__internalnote +msgid "Internal note" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__message_is_follower +msgid "Is Follower" +msgstr "" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.openems_device_form +msgid "Is connected" +msgstr "" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.report_openems_setup_protocol_template +msgid "Kontaktdaten Endkunde" +msgstr "" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.report_openems_setup_protocol_template +msgid "Land" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device____last_update +#: model:ir.model.fields,field_description:openems.field_openems_device_tag____last_update +#: model:ir.model.fields,field_description:openems.field_openems_device_user_role____last_update +#: model:ir.model.fields,field_description:openems.field_openems_openemsconfigupdate____last_update +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol____last_update +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol_item____last_update +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol_production_lot____last_update +#: model:ir.model.fields,field_description:openems.field_openems_systemmessage____last_update +msgid "Last Modified on" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__write_uid +#: model:ir.model.fields,field_description:openems.field_openems_device_tag__write_uid +#: model:ir.model.fields,field_description:openems.field_openems_device_user_role__write_uid +#: model:ir.model.fields,field_description:openems.field_openems_openemsconfigupdate__write_uid +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol__write_uid +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol_item__write_uid +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol_production_lot__write_uid +#: model:ir.model.fields,field_description:openems.field_openems_systemmessage__write_uid +msgid "Last Updated by" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__write_date +#: model:ir.model.fields,field_description:openems.field_openems_device_tag__write_date +#: model:ir.model.fields,field_description:openems.field_openems_device_user_role__write_date +#: model:ir.model.fields,field_description:openems.field_openems_openemsconfigupdate__write_date +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol__write_date +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol_item__write_date +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol_production_lot__write_date +#: model:ir.model.fields,field_description:openems.field_openems_systemmessage__write_date +msgid "Last Updated on" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__lastupdate +msgid "Last data update" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__lastmessage +msgid "Last message" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device_user_role__last_notification +msgid "Last notification sent" +msgstr "" + +#. module: openems +#: model:ir.model,name:openems.model_stock_lot +msgid "Lot/Serial" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__message_main_attachment_id +msgid "Main Attachment" +msgstr "" + +#. module: openems +#: model:res.groups,name:openems.group_openems_manager +msgid "Manager" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__manual_setup_date +msgid "Manual Setup Date" +msgstr "" + +#. module: openems +#: model:res.groups,comment:openems.group_openems_manager +msgid "Members of this group can manage all devices" +msgstr "" + +#. module: openems +#: model:res.groups,comment:openems.group_openems_reader +msgid "Members of this group have reading access to all devices" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_systemmessage__text +msgid "Message" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__message_has_error +msgid "Message Delivery error" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__message_ids +msgid "Messages" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__name +#: model:ir.model.fields,field_description:openems.field_openems_device_tag__name +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol_item__name +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol_production_lot__name +msgid "Name" +msgstr "" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.report_openems_setup_protocol_template +msgid "Name Installateur" +msgstr "" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.report_openems_setup_protocol_template +msgid "Name Kontaktperson" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__name_number +msgid "Name Number" +msgstr "" + +#. module: openems +#: model:ir.model.constraint,message:openems.constraint_openems_device_unique_name +msgid "Name needs to be unique" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device_user_role__time_to_wait +msgid "Notification" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__message_needaction_counter +msgid "Number of Actions" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__message_has_error_counter +msgid "Number of errors" +msgstr "" + +#. module: openems +#: model:ir.model.fields,help:openems.field_openems_device__message_needaction_counter +msgid "Number of messages requiring action" +msgstr "" + +#. module: openems +#: model:ir.model.fields,help:openems.field_openems_device__message_has_error_counter +msgid "Number of messages with delivery error" +msgstr "" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.openems_device_tree +msgid "OE Connected" +msgstr "" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.openems_device_tree +msgid "OE State" +msgstr "" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.openems_device_tree +msgid "OE Version" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__oem +msgid "OEM Branding" +msgstr "" + +#. module: openems +#: model:ir.model.fields.selection,name:openems.selection__openems_device__openems_sum_state_level__ok +msgid "Ok" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__monitoring_url +msgid "Online-Monitoring" +msgstr "" + +#. module: openems +#: model:ir.model.fields.selection,name:openems.selection__openems_device__oem__openems +#: model:ir.module.category,name:openems.module_category_openems +#: model:ir.ui.menu,name:openems.menu_openems +#: model_terms:ir.ui.view,arch_db:openems.openems_users_form +msgid "OpenEMS" +msgstr "" + +#. module: openems +#: model:mail.template,subject:openems.alerting_email_generic +msgid "OpenEMS Alert - Edge is offline" +msgstr "" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.report_openems_setup_protocol_template +msgid "OpenEMS Association e.V." +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__openems_config_components +msgid "OpenEMS Config" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__openems_config +msgid "OpenEMS Config Full" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__openems_config_update_ids +msgid "OpenEMS Config Updates" +msgstr "" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.openems_openemsconfigupdate_tree +msgid "OpenEMS Configuration Updates" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device_user_role__device_id +#: model:ir.model.fields,field_description:openems.field_openems_openemsconfigupdate__device_id +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol__device_id +#: model:ir.model.fields,field_description:openems.field_openems_systemmessage__device_id +#: model:ir.model.fields.selection,name:openems.selection__openems_device__producttype__openems-edge +#: model:ir.ui.menu,name:openems.menu_openems_content +msgid "OpenEMS Edge" +msgstr "" + +#. module: openems +#: model:ir.model,name:openems.model_openems_device +msgid "OpenEMS Edge Device" +msgstr "" + +#. module: openems +#: model:ir.model,name:openems.model_openems_openemsconfigupdate +msgid "OpenEMS Edge Device Configuration Update" +msgstr "" + +#. module: openems +#: model:ir.model,name:openems.model_openems_device_tag +msgid "OpenEMS Edge Device Tag" +msgstr "" + +#. module: openems +#: model:ir.model,name:openems.model_openems_device_user_role +msgid "OpenEMS Edge Device User Role" +msgstr "" + +#. module: openems +#: model:ir.model,name:openems.model_openems_setup_protocol_item +msgid "OpenEMS Edge Setup Protocol Entry Item" +msgstr "" + +#. module: openems +#: model:ir.model,name:openems.model_openems_setup_protocol_production_lot +msgid "OpenEMS Edge Setup Protocol Serial Number" +msgstr "" + +#. module: openems +#: model:ir.model,name:openems.model_openems_setup_protocol +msgid "OpenEMS Edge Setup Protocols (IBN)" +msgstr "" + +#. module: openems +#: model:ir.model,name:openems.model_openems_systemmessage +msgid "OpenEMS Edge Systemmessage" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__openems_is_connected +msgid "OpenEMS Is connected" +msgstr "" + +#. module: openems +#: model:ir.actions.report,name:openems.action_openems_setup_protocol_report +msgid "OpenEMS Setup Protocol" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__openems_sum_state_level +msgid "OpenEMS State" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__openems_version +#: model_terms:ir.ui.view,arch_db:openems.device_search_view +msgid "OpenEMS Version" +msgstr "" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.device_search_view +#: model_terms:ir.ui.view,arch_db:openems.openems_device_tree +msgid "OpenEMS-Number" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_res_users__openems_language +msgid "Openems Language" +msgstr "" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.report_openems_setup_protocol_template +msgid "Ort" +msgstr "" + +#. module: openems +#: model:ir.model.fields.selection,name:openems.selection__openems_device_user_role__role__owner +#: model:ir.model.fields.selection,name:openems.selection__res_users__global_role__owner +msgid "Owner" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_res_partner__customer_setup_protocols_ids +#: model:ir.model.fields,field_description:openems.field_res_users__customer_setup_protocols_ids +msgid "Owner of OpenEMS Edge" +msgstr "" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.report_openems_setup_protocol_template +msgid "PLZ" +msgstr "" + +#. module: openems +#: model:ir.model.fields,help:openems.field_openems_device__setup_password +msgid "Password for commissioning by the installer" +msgstr "" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.openems_setup_protocol_form +msgid "Print" +msgstr "" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.openems_device_form +msgid "Product" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__producttype +msgid "Product type" +msgstr "" + +#. module: openems +#: model:res.groups,name:openems.group_openems_reader +msgid "Read access" +msgstr "" + +#. module: openems +#: model:mail.template,subject:openems.registration_email +msgid "Registrierung erfolgreich" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device_user_role__role +msgid "Role" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__user_role_ids +#: model:ir.model.fields,field_description:openems.field_res_users__device_role_ids +msgid "Roles" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__message_has_sms_error +msgid "SMS Delivery error" +msgstr "" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.openems_device_form +msgid "Security" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol_production_lot__lot_id +msgid "Serial Number" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol__productionlot_ids +msgid "Serial Numbers" +msgstr "" + +#. module: openems +#: model:ir.model.constraint,message:openems.constraint_openems_device_unique_stock_production_lot_id +msgid "Serial number needs to be unique" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol_item__setup_protocol_id +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol_production_lot__setup_protocol_id +#: model_terms:ir.ui.view,arch_db:openems.report_openems_setup_protocol_template +msgid "Setup Protocol" +msgstr "" + +#. module: openems +#: model:ir.actions.act_window,name:openems.action_openems_admin_setup_protocol +#: model:ir.model.fields,field_description:openems.field_openems_device__setup_protocol_ids +#: model:ir.ui.menu,name:openems.menu_openems_admin_setup_protocol +#: model_terms:ir.ui.view,arch_db:openems.res_partner_form +msgid "Setup Protocols" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol_item__sequence +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol_production_lot__sequence +msgid "Sort" +msgstr "" + +#. module: openems +#: model:ir.model.fields.selection,name:openems.selection__res_users__openems_language__es +msgid "Spanish" +msgstr "" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.report_openems_setup_protocol_template +msgid "Speicherstandort" +msgstr "" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.openems_device_form +msgid "Status" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__stock_production_lot_id +msgid "Stock Production Lot" +msgstr "" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.report_openems_setup_protocol_template +msgid "Straße / Hausnummer" +msgstr "" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.openems_device_form +msgid "System Messages" +msgstr "" + +#. module: openems +#: model:ir.actions.act_window,name:openems.action_openems_systemmessage +#: model:ir.model.fields,field_description:openems.field_openems_device__systemmessage_ids +#: model:ir.ui.menu,name:openems.menu_openems_admin_systemmessages +msgid "Systemmessages" +msgstr "" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.openems_device_form +msgid "Systemstatus" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__tag_ids +msgid "Tags" +msgstr "" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.report_openems_setup_protocol_template +msgid "Telefonnummer" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_systemmessage__text_teaser +msgid "Text Teaser" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_openemsconfigupdate__details +msgid "Update Details" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_openemsconfigupdate__teaser +msgid "Update Details Teaser" +msgstr "" + +#. module: openems +#: model:ir.model,name:openems.model_res_users +#: model:ir.model.fields,field_description:openems.field_openems_device_user_role__user_id +msgid "User" +msgstr "" + +#. module: openems +#: model:ir.model.constraint,message:openems.constraint_openems_device_user_role_device_user_uniq +msgid "User already exists for this device." +msgstr "" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.openems_systemmessage_tree +msgid "Users" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol_item__value +msgid "Value" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol_item__view +msgid "View Identifier" +msgstr "" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.report_openems_setup_protocol_template +msgid "Vor- Nachname" +msgstr "" + +#. module: openems +#: model:ir.model.fields.selection,name:openems.selection__openems_device__openems_sum_state_level__warning +msgid "Warning" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__website_message_ids +msgid "Website Messages" +msgstr "" + +#. module: openems +#: model:ir.model.fields,help:openems.field_openems_device__website_message_ids +msgid "Website communication history" +msgstr "" + +#. module: openems +#: model:mail.template,subject:openems.setup_protocol_email_customer +#: model:mail.template,subject:openems.setup_protocol_email_installer +msgid "Your OpenEMS setup protocol for {{object.openems_device_id.name}}" +msgstr "" diff --git a/addons/openems/mail/openems/alerting_offline.xml b/addons/openems/mail/openems/alerting_offline.xml new file mode 100644 index 0000000..2d2a38d --- /dev/null +++ b/addons/openems/mail/openems/alerting_offline.xml @@ -0,0 +1,275 @@ + + + + + E-Mail Offline-Alerting + + ]]> + {{object.user_id.partner_id.id}} + OpenEMS Alert - Edge is offline + + + + + OpenEMS Alert - Edge is offline + + + + + + + + + + + + + + + +
+ + + + + + +
+ +
+ + + + + + +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+

+

+ +
+
+ + + , + + Ms/Mr , + Customer, +
+
+
Your OpenEMS Edge with number is offline since: +
+
+
+ + + + + + + (UTC) + + +
+
+ + + + + + + + + + + + +
Info
+ OpenEMS-Version + + + + + UNKNOWN +
+ Type + + + + + + + +
+
+
Best Regards
+
+
OpenEMS Association e.V.
+
+
+ +
+
+ +
+ +
+ + + + + + +
+ +
+ + + + + + + + + + + + + + + +
+
If you do no longer wish to receive email notifications, you can disable the feature here .
+
+
This is an automatically generated message. Please do not reply to this message!
+
+ + + + + + +
+ OpenEMS Logo +
+
+

+

+ +
+
+ +
+
+ +
+ + + + ]]> +
+
+
+
diff --git a/addons/openems/mail/openems/alerting_sum_state.xml b/addons/openems/mail/openems/alerting_sum_state.xml new file mode 100644 index 0000000..5ac49f6 --- /dev/null +++ b/addons/openems/mail/openems/alerting_sum_state.xml @@ -0,0 +1,268 @@ + + + + + E-Mail SumState Alerting + + ]]> + {{object.user_id.partner_id.id}} + OpenEMS Alert - Edge is in {{object.device_id.openems_sum_state_level}} State + + + + + OpenEMS Alert - Edge is in fault + + + + + + + + + + + + + + + +
+ + + + + + +
+ +
+ + + + + + +
+ +
+ + + + + + + + + + + + + + + + + + + + + +
+

+

+ +
+
+ + + , + + Ms/Mr , + Customer, +
+
+
Your OpenEMS Edge with number is in a continuous + + + + + + + UNKNOWN + state! +
+
+ + + + + + + + + + + + +
Info
+ OpenEMS-Version + + + + + UNKNOWN +
+ Type + + + + + + + +
+
+
Best Regards
+
+
OpenEMS Association e.V.
+
+
+ +
+
+ +
+ +
+ + + + + + +
+ +
+ + + + + + + + + + + + + + + +
+
If you do no longer wish to receive email notifications, you can disable the feature here .
+
+
This is an automatically generated message. Please do not reply to this message!
+
+ + + + + + +
+ OpenEMS Logo +
+
+

+

+ +
+
+ +
+
+ +
+ + + + ]]> +
+
+
+
diff --git a/addons/openems/mail/openems/setup_protocol_customer.xml b/addons/openems/mail/openems/setup_protocol_customer.xml new file mode 100644 index 0000000..3b1e781 --- /dev/null +++ b/addons/openems/mail/openems/setup_protocol_customer.xml @@ -0,0 +1,170 @@ + + + + + E-Mail setup protocol for customer + + ]]> + {{object.customer_id.id}} + Your OpenEMS setup protocol for {{object.openems_device_id.name}} + false + + + + + Your OpenEMS Edge setup protocol + + + + + + + + + + + + + + + +
+ + + + + + +
+ +
+ + + + + + +
+ +
+ + + + + + + + + + + + + + + + + + +
+

+

+ +
+
Welcome to OpenEMS,
+
+
please find your setup protocol for OpenEMS Edge attached.
+
+
Best Regards
+
+
OpenEMS Association e.V.
+
+
+ +
+
+ +
+
+ + + + ]]> +
+
+
+
diff --git a/addons/openems/mail/openems/setup_protocol_installer.xml b/addons/openems/mail/openems/setup_protocol_installer.xml new file mode 100644 index 0000000..13afd9d --- /dev/null +++ b/addons/openems/mail/openems/setup_protocol_installer.xml @@ -0,0 +1,173 @@ + + + + + E-Mail setup protocol for installer + + ]]> + {{object.installer_id.id}} + Your OpenEMS setup protocol for {{object.openems_device_id.name}} + false + + + + + OpenEMS setup protocol + + + + + + + + + + + + + + + +
+ + + + + + +
+ +
+ + + + + + +
+ +
+ + + + + + + + + + + + + + + + + + +
+

+

+ +
+
Dear + , +
+
+
please find the setup protocol for your customer attached. +
+
+
Best Regards
+
+
OpenEMS Association e.V.
+
+
+ +
+
+ +
+
+ + + + ]]> +
+
+
+
diff --git a/addons/openems/mail/openems/user_registration.xml b/addons/openems/mail/openems/user_registration.xml new file mode 100644 index 0000000..cfd4183 --- /dev/null +++ b/addons/openems/mail/openems/user_registration.xml @@ -0,0 +1,197 @@ + + + + + E-Mail Kunden Registrierung + + ]]> + {{object.id}} + Registrierung erfolgreich + false + + + + + Registrierung erfolgreich + + + + + + + + + + + + + + + +
+ + + + + + +
+ +
+ + + + + + +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+

+

+ +
+
Guten Tag + , +
+
+
Ihr Zugang zu OpenEMS UI wurde erstellt.
+
+
Sie können sich auf OpenEMS UI einloggen, um auf das Online-Monitoring zuzugreifen.
+
+ + + + + + + + + + + + +
Ihre Zugangsdaten:
E-Mail + +
Passwort + +
+
+
Best Regards
+
+
OpenEMS Association e.V.
+
+
+ +
+
+ +
+
+ + + + ]]> +
+
+
+
diff --git a/addons/openems/migrations/16.0.1.0.1/post-migrate.py b/addons/openems/migrations/16.0.1.0.1/post-migrate.py new file mode 100644 index 0000000..1eab6fe --- /dev/null +++ b/addons/openems/migrations/16.0.1.0.1/post-migrate.py @@ -0,0 +1,9 @@ +def migrate(cr, version): + cr.execute(""" + INSERT INTO openems_alerting (device_id, device_name, user_id, user_login, offline_delay, warning_delay, fault_delay, offline_last_notification) + SELECT device_id, dev.name, user_id, usr.login, time_to_wait, 0, 0, last_notification + FROM openems_alerting_migrate AS migrate + LEFT JOIN openems_device AS dev ON dev.id = migrate.device_id + LEFT JOIN res_users AS usr ON usr.id = migrate.user_id + """) + cr.execute('DROP TABLE openems_alerting_migrate') diff --git a/addons/openems/migrations/16.0.1.0.1/pre-migrate.py b/addons/openems/migrations/16.0.1.0.1/pre-migrate.py new file mode 100644 index 0000000..341e4a5 --- /dev/null +++ b/addons/openems/migrations/16.0.1.0.1/pre-migrate.py @@ -0,0 +1,7 @@ +def migrate(cr, version): + cr.execute(""" + SELECT device_id, user_id, time_to_wait, last_notification + INTO openems_alerting_migrate + FROM openems_device_user_role + WHERE time_to_wait > 0; + """) diff --git a/addons/openems/models/__init__.py b/addons/openems/models/__init__.py new file mode 100644 index 0000000..c4a7e59 --- /dev/null +++ b/addons/openems/models/__init__.py @@ -0,0 +1 @@ +from . import device, partner, setup_protocol, user, stock_production_lot diff --git a/addons/openems/models/device.py b/addons/openems/models/device.py new file mode 100644 index 0000000..bdbda80 --- /dev/null +++ b/addons/openems/models/device.py @@ -0,0 +1,321 @@ +from odoo import api, fields, models, exceptions, _ +from datetime import datetime +from odoo.exceptions import ValidationError +import random +import re +import string + +class Device(models.Model): + _name = "openems.device" + _description = "OpenEMS Edge Device" + _inherit = "mail.thread" + _order = "name_number asc" + _sql_constraints = [ + ("unique_name", "unique(name)", "Name needs to be unique"), + ("unique_stock_production_lot_id", "unique(stock_production_lot_id)", + "Serial number needs to be unique") + ] + + name = fields.Char(required=True) + active = fields.Boolean("Active", default=True, tracking=True) + comment = fields.Char(tracking=True) + internalnote = fields.Text("Internal note", tracking=True) + tag_ids = fields.Many2many("openems.device_tag", string="Tags", tracking=True) + monitoring_url = fields.Char( + "Online-Monitoring", compute="_compute_monitoring_url", store=False + ) + stock_production_lot_id = fields.Many2one("stock.lot") + first_setup_protocol_date = fields.Datetime( + "First Setup Protocol Date", compute="_compute_first_setup_protocol" + ) + manual_setup_date = fields.Datetime("Manual Setup Date") + + @api.depends("setup_protocol_ids", "manual_setup_date") + def _compute_first_setup_protocol(self): + for rec in self: + if rec.manual_setup_date: + rec.first_setup_protocol_date = rec.manual_setup_date + elif len(rec.setup_protocol_ids) > 0: + rec.first_setup_protocol_date = rec.setup_protocol_ids[ + (len(rec.setup_protocol_ids) - 1) + ]["create_date"] + else: + rec.first_setup_protocol_date = None + + @api.depends("name") + def _compute_monitoring_url(self): + # Corrected the parameter key to 'edge_monitoring_url' + base_url = self.env["ir.config_parameter"].sudo().get_param("edge_monitoring_url", default='#') + for rec in self: + if isinstance(rec.name, str) and rec.name: + # Ensuring there is a '/' between base_url and rec.name if it's not already present + separator = '' if base_url.endswith('/') else '/' + rec.monitoring_url = base_url + separator + rec.name + "/live" + else: + rec.monitoring_url = base_url + + producttype = fields.Selection( + [ + ("openems-edge", "OpenEMS Edge"), + ], + "Product type", + tracking=True, + ) + emshardware = fields.Selection([], "EMS Hardware", tracking=True) + oem = fields.Selection( + [ + ("openems", "OpenEMS"), + ], + "OEM Branding", + default="openems", + ) + + # Settings + openems_config = fields.Text("OpenEMS Config Full") + openems_config_components = fields.Text("OpenEMS Config") + openems_version = fields.Char("OpenEMS Version", tracking=True) + + # Security + setup_password = fields.Char( + "Installation Key", + help="Password for commissioning by the installer", + ) + apikey = fields.Char("API-Key", required=True, tracking=True) + + # 'openems_sum_state_level' is updated by OpenEMS Backend + openems_sum_state_level = fields.Selection( + [("ok", "Ok"), ("info", "Info"), ("warning", "Warning"), ("fault", "Fault")], + "OpenEMS State", + ) + # 'openems_is_connected' is updated by OpenEMS Backend + openems_is_connected = fields.Boolean("OpenEMS Is connected") + + # System Status + lastmessage = fields.Datetime("Last message") + lastupdate = fields.Datetime("Last data update") + + # Verknüpfungen + systemmessage_ids = fields.One2many( + "openems.systemmessage", "device_id", string="System Messages" + ) + user_role_ids = fields.One2many( + "openems.device_user_role", "device_id", string="Roles", tracking=True + ) + alerting_settings = fields.One2many( + "openems.alerting", "device_id", string="Alerting", tracking=True + ) + openems_config_update_ids = fields.One2many( + "openems.openemsconfigupdate", "device_id", string="OpenEMS Config Updates" + ) + setup_protocol_ids = fields.One2many( + "openems.setup_protocol", "device_id", "Setup Protocols" + ) + + # Helper fields + name_number = fields.Integer(compute="_compute_name_number", store="True") + + @api.depends("name") + def _compute_name_number(self): + for rec in self: + rec.name_number = int(rec.name[4:]) if rec.name.startswith("edge") else -1 + + def _get_openems_state_number(self, string): + state = 0 + if string == "info": + state = 1 + elif string == "warning": + state = 2 + elif string == "fault": + state = 3 + return state + + def write(self, vals): + """Prohibit to change name field after creation.""" + if 'name' in vals: + for record in self: + if record.id and record.name != vals['name']: + self.env.cr.execute(""" + SELECT EXISTS ( + SELECT 1 FROM openems_device + WHERE name = %s AND id != %s + ) + """, (vals['name'], record.id)) + exists = self.env.cr.fetchone()[0] + if exists: + # This means there's already a device with the intended new name + raise exceptions.UserError( + "The name '{}' is already in use or does not follow the required pattern.".format( + vals['name'])) + + # If you simply want to prevent name changes, the following UserError suffices + raise exceptions.UserError("The name of the device cannot be changed after creation.") + return super(Device, self).write(vals) + + @api.model + def create(self, vals): + + # Generate setup password if not provided + if 'setup_password' not in vals or not vals['setup_password']: + vals['setup_password'] = self._generate_unique_setup_password() + + # Generate API key if not provided + if 'apikey' not in vals or not vals['apikey']: + vals['apikey'] = self._generate_api_key() + + return super(Device, self).create(vals) + + def _generate_unique_setup_password(self): + is_unique = False + setup_password = '' + while not is_unique: + # Generate a random setup password + raw_password = ''.join(random.choices(string.ascii_uppercase + string.digits, k=16)) + setup_password = '-'.join([raw_password[i:i + 4] for i in range(0, len(raw_password), 4)]) + # Check if the generated setup password already exists + existing = self.search_count([('setup_password', '=', setup_password)]) + # If the password does not exist, it is unique, and we can exit the loop + if existing == 0: + is_unique = True + return setup_password + + def _generate_api_key(self): + # Initialize a flag to indicate whether the generated key is unique + is_unique = False + api_key = '' + while not is_unique: + # Generate a random API key + api_key = ''.join(random.choices(string.ascii_letters + string.digits, k=20)) + # Check if the generated API key already exists + existing = self.search_count([('apikey', '=', api_key)]) + # If the key does not exist, it is unique, and we can exit the loop + if existing == 0: + is_unique = True + return api_key + + @api.onchange('setup_password') + def _check_setup_password_format(self): + for record in self: + if not record.setup_password: + continue + if not re.match(r"^[A-Z0-9]{4}-[A-Z0-9]{4}-[A-Z0-9]{4}-[A-Z0-9]{4}$", record.setup_password): + raise ValidationError("The device ID must be formatted as XXXX-XXXX-XXXX-XXXX") + + @api.onchange('apikey') + def _check_api_key_uniqueness(self): + for record in self: + if record.apikey: + # Prepare the domain for searching duplicates + domain = [('apikey', '=', record.apikey)] + # If the record is already saved (has a valid database ID), exclude it from the search + if record.id and isinstance(record.id, (int,)): + domain.append(('id', '!=', record.id)) + # Check if any other records with the same API key exist + existing = self.search_count(domain) + # If there are duplicates, raise a ValidationError + if existing: + raise ValidationError( + _("The API key already exists and must be unique. Please choose a different API key.")) + + +class DeviceTag(models.Model): + _name = "openems.device_tag" + _description = "OpenEMS Edge Device Tag" + name = fields.Char(required=True) + + +class DeviceUserRole(models.Model): + _name = "openems.device_user_role" + _description = "OpenEMS Edge Device User Role" + _sql_constraints = [ + ( + "device_user_uniq", + "unique(device_id, user_id)", + "User already exists for this device.", + ), + ] + device_id = fields.Many2one("openems.device", string="OpenEMS Edge") + user_id = fields.Many2one("res.users", string="User") + role = fields.Selection( + [ + ("admin", "Admin"), + ("installer", "Installer"), + ("owner", "Owner"), + ("guest", "Guest"), + ], + default="guest", + required=True, + ) + + +class OpenemsConfigUpdate(models.Model): + _name = "openems.openemsconfigupdate" + _description = "OpenEMS Edge Device Configuration Update" + _order = "create_date desc" + + device_id = fields.Many2one("openems.device", string="OpenEMS Edge") + teaser = fields.Text("Update Details Teaser") + details = fields.Html("Update Details") + + +class Systemmessage(models.Model): + _name = "openems.systemmessage" + _description = "OpenEMS Edge Systemmessage" + _order = "create_date desc" + + timestamp = fields.Datetime("Creation date") + device_id = fields.Many2one("openems.device", string="OpenEMS Edge") + text = fields.Text("Message") + text_teaser = fields.Char(compute="_compute_text_teaser") + + @api.depends("text") + def _compute_text_teaser(self): + for rec in self: + # get up to 100 characters from first line + rec.text_teaser = rec.text.splitlines()[0][0:100] if rec.text else False + +class Alerting(models.Model): + _name = "openems.alerting" + _description = "OpenEMS Edge AlertingSettings" + _sql_constraints = [ + ( + "device_user_uniq", + "unique(device_id, user_id)", + "User already has Alerting Settings.", + ), + ] + + device_id = fields.Many2one("openems.device", string="OpenEMS Edge") + user_id = fields.Many2one("res.users", string="User") + + offline_delay = fields.Integer(string="Offline Notification", default=1440) + warning_delay = fields.Integer(string="Warning Notification", default=1440) + fault_delay = fields.Integer(string="Fault Notification", default=1440) + + offline_last_notification = fields.Datetime(string="Last Offline notification sent") + sum_state_last_notification = fields.Datetime(string="Last SumState notification sent") + + device_name = fields.Text(compute="_compute_device_name", store="True") + user_login = fields.Text(compute="_compute_user_login", store="True") + + user_role = fields.Selection( + [("admin", "Admin"), ("installer", "Installer"), ("owner", "Owner"), ("guest", "Guest"),], + compute="_compute_user_role", store="False") + + @api.depends("device_id") + def _compute_device_name(self): + for rec in self: + rec.device_name = rec.device_id.name; + + @api.depends("user_id") + def _compute_user_login(self): + for rec in self: + rec.user_login = rec.user_id.login; + + @api.depends("user_id", "device_id") + def _compute_user_role(self): + for rec in self: + user_role: DeviceUserRole = rec.user_id.device_role_ids.search([('device_id','=',rec.device_id.id)]) + if user_role: + return user_role.role + else: + return rec.user_id.global_role diff --git a/addons/openems/models/partner.py b/addons/openems/models/partner.py new file mode 100644 index 0000000..37ab8e5 --- /dev/null +++ b/addons/openems/models/partner.py @@ -0,0 +1,12 @@ +from odoo import fields, models + + +class ResPartner(models.Model): + _inherit = "res.partner" + + installer_setup_protocols_ids = fields.One2many( + "openems.setup_protocol", "installer_id", "Installed OpenEMS Edge" + ) + customer_setup_protocols_ids = fields.One2many( + "openems.setup_protocol", "customer_id", "Owner of OpenEMS Edge" + ) diff --git a/addons/openems/models/setup_protocol.py b/addons/openems/models/setup_protocol.py new file mode 100644 index 0000000..548576e --- /dev/null +++ b/addons/openems/models/setup_protocol.py @@ -0,0 +1,49 @@ +from odoo import fields, models + + +class SetupProtocol(models.Model): + _name = "openems.setup_protocol" + _description = "OpenEMS Edge Setup Protocols (IBN)" + _order = "create_date desc" + + customer_id = fields.Many2one("res.partner", "Customer", required=True) + different_location_id = fields.Many2one("res.partner", "Different Location") + installer_id = fields.Many2one("res.partner", "Installer", required=True) + device_id = fields.Many2one("openems.device", "OpenEMS Edge", required=True) + productionlot_ids = fields.One2many( + "openems.setup_protocol_production_lot", "setup_protocol_id", "Serial Numbers" + ) + item_ids = fields.One2many( + "openems.setup_protocol_item", "setup_protocol_id", "Entry Items" + ) + + +class SetupProtocolProductionLot(models.Model): + _name = "openems.setup_protocol_production_lot" + _description = "OpenEMS Edge Setup Protocol Serial Number" + _order = "setup_protocol_id, category, sequence asc" + + sequence = fields.Integer("Sort") + category = fields.Char("Category") + name = fields.Char("Name") + lot_id = fields.Many2one("stock.production.lot", "Serial Number") + setup_protocol_id = fields.Many2one( + "openems.setup_protocol", "Setup Protocol", ondelete="cascade" + ) + + +class SetupProtocolItem(models.Model): + _name = "openems.setup_protocol_item" + _description = "OpenEMS Edge Setup Protocol Entry Item" + _order = "setup_protocol_id, category, sequence asc" + + sequence = fields.Integer("Sort") + category = fields.Char("Category") + name = fields.Char("Name") + value = fields.Char("Value") + setup_protocol_id = fields.Many2one( + "openems.setup_protocol", "Setup Protocol", ondelete="cascade" + ) + view = fields.Char("View Identifier") + field = fields.Char("Field Identifier") + diff --git a/addons/openems/models/stock_production_lot.py b/addons/openems/models/stock_production_lot.py new file mode 100644 index 0000000..37ebb22 --- /dev/null +++ b/addons/openems/models/stock_production_lot.py @@ -0,0 +1,23 @@ +from odoo import fields, models, api + + +class ProductionLot(models.Model): + _inherit = "stock.lot" + + device_id = fields.Many2one( + 'openems.device', compute='compute_device_id', inverse='device_inverse') + device_ids = fields.One2many('openems.device', 'stock_production_lot_id') + + @api.depends('device_ids') + def compute_device_id(self): + if len(self.device_ids) > 0: + self.device_id = self.device_ids[0] + + def device_inverse(self): + if len(self.device_ids) > 0: + if len(self.device_id.stock_production_lot_id) > 0: + raise ValueError("A serial number has already been assigned to the device") + + device = self.env['openems.device'].browse(self.device_ids[0].id) + device.stock_production_lot_id = False + self.device_id.stock_production_lot_id = self diff --git a/addons/openems/models/user.py b/addons/openems/models/user.py new file mode 100644 index 0000000..321dd87 --- /dev/null +++ b/addons/openems/models/user.py @@ -0,0 +1,37 @@ +from odoo import fields, models + + +class ResUsers(models.Model): + _inherit = "res.users" + + branding_partner_id = fields.Many2one("res.partner", string="Branding Partner") + global_role = fields.Selection( + [ + ("admin", "Admin"), + ("installer", "Installer"), + ("owner", "Owner"), + ("guest", "Guest"), + ], + default="guest", + required=True, + ) + device_role_ids = fields.One2many( + "openems.device_user_role", "user_id", string="Roles" + ) + alerting_settings = fields.One2many( + "openems.alerting", "user_id", string="Alerting" + ) + openems_language = fields.Selection( + [ + ("EN", "English"), + ("DE", "German"), + ("CZ", "Czech"), + ("NL", "Dutch"), + ("ES", "Spanish"), + ("FR", "French"), + ("HU", "Hungarian"), + ("JA", "Japanese"), + ], + default="DE", + required=True, + ) diff --git a/addons/openems/report/setup_protocol.xml b/addons/openems/report/setup_protocol.xml new file mode 100644 index 0000000..c9db4ec --- /dev/null +++ b/addons/openems/report/setup_protocol.xml @@ -0,0 +1,311 @@ + + + + OpenEMS Setup Protocol + openems.setup_protocol + qweb-pdf + openems.report_openems_setup_protocol_template + ('IBN-' + object.openems_device_id.name + '-' + object.create_date.strftime('%d.%m.%Y')) + + + diff --git a/addons/openems/security/ir.model.access.csv b/addons/openems/security/ir.model.access.csv new file mode 100644 index 0000000..1ccc0f1 --- /dev/null +++ b/addons/openems/security/ir.model.access.csv @@ -0,0 +1,31 @@ +id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink +access_openems_device_portal,access_openems_device_portal,openems.model_openems_device,base.group_portal,1,0,0,0 +access_openems_device_user,access_openems_device_user,openems.model_openems_device,base.group_user,1,0,0,0 +access_openems_device_manager,access_openems_device_manager,openems.model_openems_device,openems.group_openems_manager,1,1,1,0 +access_openems_device_tag_portal,access_openems_device_tag_portal,openems.model_openems_device_tag,base.group_portal,1,0,0,0 +access_openems_device_tag_user,access_openems_device_tag_user,openems.model_openems_device_tag,base.group_user,1,0,0,0 +access_openems_device_tag_manager,access_openems_device_tag_manager,openems.model_openems_device_tag,openems.group_openems_manager,1,1,1,1 +access_openems_device_user_role_portal,access_openems_device_user_role_portal,openems.model_openems_device_user_role,base.group_portal,1,0,0,0 +access_openems_device_user_role_user,access_openems_device_user_role_user,openems.model_openems_device_user_role,base.group_user,1,0,0,0 +access_openems_device_user_role_manager,access_openems_device_user_role_manager,openems.model_openems_device_user_role,openems.group_openems_manager,1,1,1,1 +access_openems_alerting_portal,access_openems_alerting_portal,openems.model_openems_alerting,base.group_portal,1,0,0,0 +access_openems_alerting_user,access_openems_alerting_user,openems.model_openems_alerting,base.group_user,1,0,0,0 +access_openems_alerting_manager,access_openems_alerting_manager,openems.model_openems_alerting,openems.group_openems_manager,1,1,1,1 +access_openems_systemmessage_portal,access_openems_systemmessage_portal,openems.model_openems_systemmessage,base.group_portal,1,0,0,0 +access_openems_systemmessage_user,access_openems_systemmessage_user,openems.model_openems_systemmessage,base.group_user,1,0,0,0 +access_openems_systemmessage_manager,access_openems_systemmessage_manager,openems.model_openems_systemmessage,openems.group_openems_manager,1,1,1,1 +access_openems_openemsconfigupdate_portal,access_openems_openemsconfigupdate_portal,openems.model_openems_openemsconfigupdate,base.group_portal,1,0,0,0 +access_openems_openemsconfigupdate_user,access_openems_openemsconfigupdate_user,openems.model_openems_openemsconfigupdate,base.group_user,1,0,0,0 +access_openems_openemsconfigupdate_manager,access_openems_openemsconfigupdate_manager,openems.model_openems_openemsconfigupdate,openems.group_openems_manager,1,1,1,1 +access_openems_setup_protocol_portal,access_openems_setup_protocol_portal,openems.model_openems_setup_protocol,base.group_portal,1,0,0,0 +access_openems_setup_protocol_user,access_openems_setup_protocol_user,openems.model_openems_setup_protocol,base.group_user,1,0,0,0 +access_openems_setup_protocol_manager,access_openems_setup_protocol_manager,openems.model_openems_setup_protocol,openems.group_openems_manager,1,1,1,1 +access_openems_setup_protocol_production_lot_portal,access_openems_setup_protocol_production_lot_portal,openems.model_openems_setup_protocol_production_lot,base.group_portal,1,0,0,0 +access_openems_setup_protocol_production_lot_user,access_openems_setup_protocol_production_lot_user,openems.model_openems_setup_protocol_production_lot,base.group_user,1,0,0,0 +access_openems_setup_protocol_production_lot_manager,access_openems_setup_protocol_production_lot_manager,openems.model_openems_setup_protocol_production_lot,openems.group_openems_manager,1,1,1,1 +access_openems_setup_protocol_item_portal,access_openems_setup_protocol_item_portal,openems.model_openems_setup_protocol_item,base.group_portal,1,0,0,0 +access_openems_setup_protocol_item_user,access_openems_setup_protocol_item_user,openems.model_openems_setup_protocol_item,base.group_user,1,0,0,0 +access_openems_setup_protocol_item_manager,access_openems_setup_protocol_item_manager,openems.model_openems_setup_protocol_item,openems.group_openems_manager,1,1,1,1 +access_openems_production_lot_portal,access_openems_production_lot_portal,stock.model_stock_lot,base.group_portal,1,0,0,0 +access_openems_production_lot_user,access_openems_production_lot_user,stock.model_stock_lot,base.group_user,1,0,0,0 +access_openems_production_lot_manager,access_openems_production_lot_manager,stock.model_stock_lot,openems.group_openems_manager,1,0,0,0 diff --git a/addons/openems/security/openems.xml b/addons/openems/security/openems.xml new file mode 100644 index 0000000..ef87c2f --- /dev/null +++ b/addons/openems/security/openems.xml @@ -0,0 +1,54 @@ + + + + OpenEMS + 30 + + + + Read access + Members of this group have reading access to all devices + + + + + Manager + Members of this group can manage all devices + + + + + + + Website: Show only approved devices to Portal and User + + ['|', ('user_role_ids.user_id','in',[user.id]), ('alerting_settings.user_id','in',[user.id])] + + + + + + + + + Website: Show all devices to readers group + + [(1,'=',1)] + + + + + + + + diff --git a/addons/openems/setup/.setuptools-odoo-make-default-ignore b/addons/openems/setup/.setuptools-odoo-make-default-ignore new file mode 100644 index 0000000..207e615 --- /dev/null +++ b/addons/openems/setup/.setuptools-odoo-make-default-ignore @@ -0,0 +1,2 @@ +# addons listed in this file are ignored by +# setuptools-odoo-make-default (one addon per line) diff --git a/addons/openems/setup/README b/addons/openems/setup/README new file mode 100644 index 0000000..a63d633 --- /dev/null +++ b/addons/openems/setup/README @@ -0,0 +1,2 @@ +To learn more about this directory, please visit +https://pypi.python.org/pypi/setuptools-odoo diff --git a/addons/openems/static/description/icon.png b/addons/openems/static/description/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..ee0aed1a0d5b623df9c4f3ead2a8d92ab7efc315 GIT binary patch literal 53271 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

`b%zWJVoybJJC+al7(vmUoDSw-d(zU?;>j| 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 + + + + Device: Tree + openems.device + + + + + + + + + + + + + + + + + Device: Search + openems.device + + + + + + + + + + + + + + + + + + + + + Device: Form + openems.device + +

+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + +
+ + + + + + Device DeviceUserRole: Tree + openems.device_user_role + + + + + + + + + + Devices + ir.actions.act_window + openems.device + tree,form + + + + + + Device Configuration Updates + openems.openemsconfigupdate + + + + Device Configuration Updates: Tree + openems.openemsconfigupdate + + + + + + + + + + + Device Configuration Updates: Form + openems.openemsconfigupdate + +
+ + + + + + + +
+
+
+ + + + Systemmessages + openems.systemmessage + + + + Device Systemmessage: Tree + openems.systemmessage + + + + + + + + + + + Device Systemmessage: Form + openems.systemmessage + +
+ + + + + + + +
+
+
+ + + + + + + + + diff --git a/addons/openems/views/partner.xml b/addons/openems/views/partner.xml new file mode 100644 index 0000000..874530e --- /dev/null +++ b/addons/openems/views/partner.xml @@ -0,0 +1,28 @@ + + + + OpenEMS Partner: Form + res.partner + + + + + + + + + + + + + + + + + + + + + + + diff --git a/addons/openems/views/setup_protocol.xml b/addons/openems/views/setup_protocol.xml new file mode 100644 index 0000000..bf2eee2 --- /dev/null +++ b/addons/openems/views/setup_protocol.xml @@ -0,0 +1,82 @@ + + + + SetupProtocol: Form + openems.setup_protocol + +
+ + +
+ + +
+ + + diff --git a/addons/web_m2x_options/static/src/components/form.esm.js b/addons/web_m2x_options/static/src/components/form.esm.js new file mode 100644 index 0000000..ecb37d2 --- /dev/null +++ b/addons/web_m2x_options/static/src/components/form.esm.js @@ -0,0 +1,404 @@ +/** @odoo-module **/ + +import { + Many2ManyTagsField, + Many2ManyTagsFieldColorEditable, +} from "@web/views/fields/many2many_tags/many2many_tags_field"; + +import {Dialog} from "@web/core/dialog/dialog"; +import {FormController} from "@web/views/form/form_controller"; +import {FormViewDialog} from "@web/views/view_dialogs/form_view_dialog"; +import {Many2OneAvatarField} from "@web/views/fields/many2one_avatar/many2one_avatar_field"; +import {Many2OneBarcodeField} from "@web/views/fields/many2one_barcode/many2one_barcode_field"; +import {Many2OneField} from "@web/views/fields/many2one/many2one_field"; +import {ReferenceField} from "@web/views/fields/reference/reference_field"; +import {X2ManyField} from "@web/views/fields/x2many/x2many_field"; +import {isX2Many} from "@web/views/utils"; +import {is_option_set} from "@web_m2x_options/components/relational_utils.esm"; +import {patch} from "@web/core/utils/patch"; +import {sprintf} from "@web/core/utils/strings"; +import {useService} from "@web/core/utils/hooks"; + +const {Component} = owl; + +/** + * Patch Many2ManyTagsField + **/ +patch(Many2ManyTagsField.prototype, "web_m2x_options.Many2ManyTagsField", { + setup() { + this._super(...arguments); + this.actionService = useService("action"); + }, + /** + * @override + */ + getTagProps(record) { + const props = this._super(...arguments); + props.onClick = (ev) => this.onMany2ManyBadgeClick(ev, record); + return props; + }, + async onMany2ManyBadgeClick(event, record) { + var self = this; + if (self.props.open) { + var context = self.context; + var id = record.data.id; + if (self.props.readonly) { + event.preventDefault(); + event.stopPropagation(); + const action = await self.orm.call( + self.props.relation, + "get_formview_action", + [[id]], + {context: context} + ); + self.actionService.doAction(action); + } else { + const view_id = await self.orm.call( + self.props.relation, + "get_formview_id", + [[id]], + {context: context} + ); + + const write_access = await self.orm.call( + self.props.relation, + "check_access_rights", + [], + {operation: "write", raise_exception: false} + ); + var can_write = self.props.canWrite; + self.dialog.add(FormViewDialog, { + resModel: self.props.relation, + resId: id, + context: context, + title: self.env._t("Open: ") + self.string, + viewId: view_id, + mode: !can_write || !write_access ? "readonly" : "edit", + onRecordSaved: () => self.props.value.model.load(), + }); + } + } + }, +}); + +Many2ManyTagsField.props = { + ...Many2ManyTagsField.props, + open: {type: Boolean, optional: true}, + canWrite: {type: Boolean, optional: true}, + nodeOptions: {type: Object, optional: true}, +}; + +const Many2ManyTagsFieldExtractProps = Many2ManyTagsField.extractProps; +Many2ManyTagsField.extractProps = ({attrs, field}) => { + const canOpen = Boolean(attrs.options.open); + const canWrite = attrs.can_write && Boolean(JSON.parse(attrs.can_write)); + return Object.assign(Many2ManyTagsFieldExtractProps({attrs, field}), { + open: canOpen, + canWrite: canWrite, + nodeOptions: attrs.options, + }); +}; + +/** + * Many2ManyTagsFieldColorEditable + **/ +patch( + Many2ManyTagsFieldColorEditable.prototype, + "web_m2x_options.Many2ManyTagsFieldColorEditable", + { + async onBadgeClick(event, record) { + if (this.props.canEditColor && !this.props.open) { + this._super(...arguments); + } + if (this.props.open) { + Many2ManyTagsField.prototype.onMany2ManyBadgeClick.bind(this)( + event, + record + ); + } + }, + } +); + +Many2ManyTagsFieldColorEditable.props = { + ...Many2ManyTagsFieldColorEditable.props, + open: {type: Boolean, optional: true}, + canWrite: {type: Boolean, optional: true}, + nodeOptions: {type: Object, optional: true}, +}; + +/** + * CreateConfirmationDialog + * New customized component for Many2One Field + **/ + +class CreateConfirmationDialog extends Component { + get title() { + return sprintf(this.env._t("New: %s"), this.props.name); + } + + async onCreate() { + await this.props.create(); + this.props.close(); + } + async onCreateEdit() { + await this.props.createEdit(); + this.props.close(); + } +} +CreateConfirmationDialog.components = {Dialog}; +CreateConfirmationDialog.template = + "web_m2x_options.Many2OneField.CreateConfirmationDialog"; + +/** + * Many2OneField + **/ + +patch(Many2OneField.prototype, "web_m2x_options.Many2OneField", { + setup() { + this._super(...arguments); + this.ir_options = Component.env.session.web_m2x_options; + }, + /** + * @override + */ + get Many2XAutocompleteProps() { + const props = this._super(...arguments); + return { + ...props, + searchLimit: this.props.searchLimit, + searchMore: this.props.searchMore, + canCreate: this.props.canCreate, + nodeOptions: this.props.nodeOptions, + }; + }, + + async openConfirmationDialog(request) { + var m2o_dialog_opt = + is_option_set(this.props.nodeOptions.m2o_dialog) || + (_.isUndefined(this.props.nodeOptions.m2o_dialog) && + is_option_set(this.ir_options["web_m2x_options.m2o_dialog"])) || + (_.isUndefined(this.props.nodeOptions.m2o_dialog) && + _.isUndefined(this.ir_options["web_m2x_options.m2o_dialog"])); + if (this.props.canCreate && this.state.isFloating && m2o_dialog_opt) { + return new Promise((resolve, reject) => { + this.addDialog(CreateConfirmationDialog, { + value: request, + name: this.props.string, + create: async () => { + try { + await this.quickCreate(request); + resolve(); + } catch (e) { + reject(e); + } + }, + createEdit: async () => { + try { + await this.quickCreate(request); + await this.props.record.model.load(); + this.openMany2X({ + resId: this.props.value[0], + context: this.user_context, + }); + resolve(); + } catch (e) { + reject(e); + } + }, + }); + }); + } + }, +}); + +const Many2OneFieldExtractProps = Many2OneField.extractProps; +Many2OneField.extractProps = ({attrs, field}) => { + return Object.assign(Many2OneFieldExtractProps({attrs, field}), { + searchLimit: attrs.options.limit, + searchMore: attrs.options.search_more, + nodeOptions: attrs.options, + }); +}; + +Many2OneField.props = { + ...Many2OneField.props, + searchMore: {type: Boolean, optional: true}, + nodeOptions: {type: Object, optional: true}, +}; + +/** + * FIXME: find better way to extend props in Many2OneField + * Override ReferenceField + * Since extracted/added props: nodeOptions and searchMore into Many2OneField props + * and this component inherited props from Many2OneField + * So, must override props here to avoid constraint validateProps (props schema) in owl core + */ + +ReferenceField.props = { + ...ReferenceField.props, + searchMore: {type: Boolean, optional: true}, + nodeOptions: {type: Object, optional: true}, +}; + +/** + * FIXME: find better way to extend props in Many2OneField + * Override Many2OneBarcodeField + * Since extracted/added props: nodeOptions and searchMore into Many2OneField props + * and this component inherited props from Many2OneField + * So, must override props here to avoid constraint validateProps (props schema) in owl core + */ + +Many2OneBarcodeField.props = { + ...Many2OneBarcodeField.props, + searchMore: {type: Boolean, optional: true}, + nodeOptions: {type: Object, optional: true}, +}; + +/** + * FIXME: find better way to extend props in Many2OneField + * Override Many2OneAvatarField + * Since extracted/added props: nodeOptions and searchMore into Many2OneField props + * and this component inherited props from Many2OneField + * So, must override props here to avoid constraint validateProps (props schema) in owl core + */ +Many2OneAvatarField.props = { + ...Many2OneAvatarField.props, + searchMore: {type: Boolean, optional: true}, + nodeOptions: {type: Object, optional: true}, +}; + +/** + * FIXME: find better way to extend props in Many2OneField + * Override mailing_m2o_filter + * Since extracted/added props: nodeOptions and searchMore into Many2OneField props + * and this component inherited props from Many2OneField + * So, must override props here to avoid constraint validateProps (props schema) in owl core + * This component is in module mass_mailing as optional module, + * So need to import dynamic way + */ +try { + (async () => { + // Make sure component mailing_m2o_filter in mass mailing module loaded + const installed_mass_mailing = await odoo.ready( + "@mass_mailing/js/mailing_m2o_filter" + ); + if (installed_mass_mailing) { + const {FieldMany2OneMailingFilter} = await odoo.runtimeImport( + "@mass_mailing/js/mailing_m2o_filter" + ); + FieldMany2OneMailingFilter.props = { + ...FieldMany2OneMailingFilter.props, + searchMore: {type: Boolean, optional: true}, + nodeOptions: {type: Object, optional: true}, + }; + } + })(); +} catch { + console.log( + "Ignore overriding props of component mailing_m2o_filter since the module is not installed" + ); +} + +/** + * X2ManyField + **/ +patch(X2ManyField.prototype, "web_m2x_options.X2ManyField", { + /** + * @override + */ + async openRecord(record) { + var self = this; + var open = this.props.open; + if (open && self.props.readonly) { + var res_id = record.data.id; + const action = await self.env.model.orm.call( + self.props.value.resModel, + "get_formview_action", + [[res_id]] + ); + return self.env.model.actionService.doAction(action); + } + return this._super.apply(this, arguments); + }, +}); + +const X2ManyFieldExtractProps = X2ManyField.extractProps; +X2ManyField.extractProps = ({attrs}) => { + const canOpen = Boolean(attrs.options.open); + return Object.assign(X2ManyFieldExtractProps({attrs}), { + open: canOpen, + }); +}; + +X2ManyField.props = { + ...X2ManyField.props, + open: {type: Boolean, optional: true}, +}; + +/** + * FormController + **/ +patch(FormController.prototype, "web_m2x_options.FormController", { + /** + * @override + */ + setup() { + var self = this; + this._super(...arguments); + + /** Due to problem of 2 onWillStart in native web core + * (see: https://github.com/odoo/odoo/blob/16.0/addons/web/static/src/views/model.js#L142) + * do the trick to override beforeLoadResolver here to customize viewLimit + */ + this.superBeforeLoadResolver = this.beforeLoadResolver; + this.beforeLoadResolver = async () => { + await self._setSubViewLimit(); + self.superBeforeLoadResolver(); + }; + }, + /** + * @override + * add more method to add subview limit on formview + */ + async _setSubViewLimit() { + const ir_options = Component.env.session.web_m2x_options; + + const activeFields = this.archInfo.activeFields, + fields = this.props.fields, + isSmall = this.user; + + var limit = ir_options["web_m2x_options.field_limit_entries"]; + if (!_.isUndefined(limit)) { + limit = parseInt(limit, 10); + } + + for (const fieldName in activeFields) { + const field = fields[fieldName]; + if (!isX2Many(field)) { + // What follows only concerns x2many fields + continue; + } + const fieldInfo = activeFields[fieldName]; + if (fieldInfo.modifiers.invisible === true) { + // No need to fetch the sub view if the field is always invisible + continue; + } + + if (!fieldInfo.FieldComponent.useSubView) { + // The FieldComponent used to render the field doesn't need a sub view + continue; + } + + let viewType = fieldInfo.viewMode || "list,kanban"; + viewType = viewType.replace("tree", "list"); + if (viewType.includes(",")) { + viewType = isSmall ? "kanban" : "list"; + } + fieldInfo.viewMode = viewType; + if (fieldInfo.views[viewType] && limit) { + fieldInfo.views[viewType].limit = limit; + } + } + }, +}); diff --git a/addons/web_m2x_options/static/src/components/relational_utils.esm.js b/addons/web_m2x_options/static/src/components/relational_utils.esm.js new file mode 100644 index 0000000..1fbe39e --- /dev/null +++ b/addons/web_m2x_options/static/src/components/relational_utils.esm.js @@ -0,0 +1,221 @@ +/** @odoo-module **/ + +import {Many2XAutocomplete} from "@web/views/fields/relational_utils"; +import {patch} from "@web/core/utils/patch"; +import {sprintf} from "@web/core/utils/strings"; +const {Component} = owl; + +export function is_option_set(option) { + if (_.isUndefined(option)) return false; + if (typeof option === "string") return option === "true" || option === "True"; + if (typeof option === "boolean") return option; + return false; +} + +patch(Many2XAutocomplete.prototype, "web_m2x_options.Many2XAutocomplete", { + setup() { + this._super(...arguments); + this.ir_options = Component.env.session.web_m2x_options; + }, + + async loadOptionsSource(request) { + if (this.lastProm) { + this.lastProm.abort(false); + } + // Add options limit used to change number of selections record + // returned. + if (!_.isUndefined(this.ir_options["web_m2x_options.limit"])) { + this.props.searchLimit = parseInt( + this.ir_options["web_m2x_options.limit"], + 10 + ); + this.limit = this.props.searchLimit; + } + + if (typeof this.props.nodeOptions.limit === "number") { + this.props.searchLimit = this.props.nodeOptions.limit; + this.limit = this.props.searchLimit; + } + + // Add options field_color and colors to color item(s) depending on field_color value + this.field_color = this.props.nodeOptions.field_color; + this.colors = this.props.nodeOptions.colors; + + this.lastProm = this.orm.call(this.props.resModel, "name_search", [], { + name: request, + operator: "ilike", + args: this.props.getDomain(), + limit: this.props.searchLimit + 1, + context: this.props.context, + }); + const records = await this.lastProm; + + var options = records.map((result) => ({ + value: result[0], + id: result[0], + label: result[1].split("\n")[0], + })); + + // Limit results if there is a custom limit options + if (this.limit) { + options = options.slice(0, this.props.searchLimit); + } + + // Search result value colors + if (this.colors && this.field_color) { + var value_ids = options.map((result) => result.value); + const objects = await this.orm.call( + this.props.resModel, + "search_read", + [], + { + domain: [["id", "in", value_ids]], + fields: [this.field_color], + } + ); + for (var index in objects) { + for (var index_value in options) { + if (options[index_value].id === objects[index].id) { + // Find value in values by comparing ids + var option = options[index_value]; + // Find color with field value as key + var color = + this.colors[objects[index][this.field_color]] || "black"; + option.style = "color:" + color; + break; + } + } + } + } + + // Quick create + // Note: Create should be before `search_more` (reserve native order) + // One more reason: when calling `onInputBlur`, native select the first option (activeSourceOption) + // which triggers m2o_dialog if m2o_dialog=true + var create_enabled = + this.props.quickCreate && !this.props.nodeOptions.no_create; + + var raw_result = _.map(records, function (x) { + return x[1]; + }); + var quick_create = is_option_set(this.props.nodeOptions.create), + quick_create_undef = _.isUndefined(this.props.nodeOptions.create), + m2x_create_undef = _.isUndefined(this.ir_options["web_m2x_options.create"]), + m2x_create = is_option_set(this.ir_options["web_m2x_options.create"]); + var show_create = + (!this.props.nodeOptions && (m2x_create_undef || m2x_create)) || + (this.props.nodeOptions && + (quick_create || + (quick_create_undef && (m2x_create_undef || m2x_create)))); + if ( + create_enabled && + !this.props.nodeOptions.no_quick_create && + request.length > 0 && + !_.contains(raw_result, request) && + show_create + ) { + options.push({ + label: sprintf(this.env._t(`Create "%s"`), request), + classList: "o_m2o_dropdown_option o_m2o_dropdown_option_create", + action: async (params) => { + try { + await this.props.quickCreate(request, params); + } catch { + const context = this.getCreationContext(request); + return this.openMany2X({context}); + } + }, + }); + } + + // Search more... + // Resolution order: + // 1- check if "search_more" is set locally in node's options + // 2- if set locally, apply its value + // 3- if not set locally, check if it's set globally via ir.config_parameter + // 4- if set globally, apply its value + // 5- if not set globally either, check if returned values are more than node's limit + var search_more = false; + if (!_.isUndefined(this.props.nodeOptions.search_more)) { + search_more = is_option_set(this.props.nodeOptions.search_more); + } else if (!_.isUndefined(this.ir_options["web_m2x_options.search_more"])) { + search_more = is_option_set(this.ir_options["web_m2x_options.search_more"]); + } else { + search_more = + !this.props.noSearchMore && this.props.searchLimit < records.length; + } + if (search_more) { + options.push({ + label: this.env._t("Search More..."), + action: this.onSearchMore.bind(this, request), + classList: "o_m2o_dropdown_option o_m2o_dropdown_option_search_more", + }); + } + + // Create and Edit + const canCreateEdit = + "createEdit" in this.activeActions + ? this.activeActions.createEdit + : this.activeActions.create; + if ( + !request.length && + !this.props.value && + (this.props.quickCreate || canCreateEdit) + ) { + options.push({ + label: this.env._t("Start typing..."), + classList: "o_m2o_start_typing", + unselectable: true, + }); + } + + // Create and edit ... + var create_edit = + is_option_set(this.props.nodeOptions.create) || + is_option_set(this.props.nodeOptions.create_edit), + create_edit_undef = + _.isUndefined(this.props.nodeOptions.create) && + _.isUndefined(this.props.nodeOptions.create_edit), + m2x_create_edit_undef = _.isUndefined( + this.ir_options["web_m2x_options.create_edit"] + ), + m2x_create_edit = is_option_set( + this.ir_options["web_m2x_options.create_edit"] + ); + var show_create_edit = + (!this.props.nodeOptions && (m2x_create_edit_undef || m2x_create_edit)) || + (this.props.nodeOptions && + (create_edit || + (create_edit_undef && (m2x_create_edit_undef || m2x_create_edit)))); + if ( + create_enabled && + !this.props.nodeOptions.no_create_edit && + show_create_edit && + request.length && + canCreateEdit + ) { + const context = this.getCreationContext(request); + options.push({ + label: this.env._t("Create and edit..."), + classList: "o_m2o_dropdown_option o_m2o_dropdown_option_create_edit", + action: () => this.openMany2X({context}), + }); + } + + // No records + if (!records.length && !this.activeActions.create) { + options.push({ + label: this.env._t("No records"), + classList: "o_m2o_no_result", + unselectable: true, + }); + } + + return options; + }, +}); + +Many2XAutocomplete.defaultProps = { + ...Many2XAutocomplete.defaultProps, + nodeOptions: {}, +}; diff --git a/addons/web_m2x_options/tests/__init__.py b/addons/web_m2x_options/tests/__init__.py new file mode 100644 index 0000000..b472ff3 --- /dev/null +++ b/addons/web_m2x_options/tests/__init__.py @@ -0,0 +1,2 @@ +# Copyright 2020 initOS GmbH. +from . import test_ir_config_parameter diff --git a/addons/web_m2x_options/tests/test_ir_config_parameter.py b/addons/web_m2x_options/tests/test_ir_config_parameter.py new file mode 100644 index 0000000..eae00c7 --- /dev/null +++ b/addons/web_m2x_options/tests/test_ir_config_parameter.py @@ -0,0 +1,28 @@ +# Copyright 2020 initOS GmbH. +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). + +from odoo.tests import common + + +class TestIrConfigParameter(common.TransactionCase): + @classmethod + def setUpClass(cls): + super(TestIrConfigParameter, cls).setUpClass() + cls.env["ir.config_parameter"].set_param("web_m2x_options.limit", 10) + cls.env["ir.config_parameter"].set_param("web_m2x_options.create_edit", "True") + cls.env["ir.config_parameter"].set_param("web_m2x_options.create", "True") + cls.env["ir.config_parameter"].set_param("web_m2x_options.search_more", "False") + cls.env["ir.config_parameter"].set_param("web_m2x_options.m2o_dialog", "True") + + def test_web_m2x_options_key(self): + web_m2x_options = self.env["ir.config_parameter"].get_web_m2x_options() + self.assertIn("web_m2x_options.limit", web_m2x_options) + self.assertNotIn("web_m2x_options.m2o_dialog_test", web_m2x_options) + + def test_web_m2x_options_value(self): + web_m2x_options = self.env["ir.config_parameter"].get_web_m2x_options() + self.assertEqual(web_m2x_options["web_m2x_options.limit"], "10") + self.assertTrue(bool(web_m2x_options["web_m2x_options.create_edit"])) + self.assertTrue(bool(web_m2x_options["web_m2x_options.create"])) + self.assertEqual(web_m2x_options["web_m2x_options.search_more"], "False") + self.assertTrue(bool(web_m2x_options["web_m2x_options.m2o_dialog"])) From 829500ef1fad53a70d5e65d43304b5f2417fb916 Mon Sep 17 00:00:00 2001 From: belloafeez Date: Fri, 2 Aug 2024 10:35:26 +0100 Subject: [PATCH 15/54] dsgwe --- odoo/Dockerfile | 1 + 1 file changed, 1 insertion(+) diff --git a/odoo/Dockerfile b/odoo/Dockerfile index 7481bed..b7339c8 100644 --- a/odoo/Dockerfile +++ b/odoo/Dockerfile @@ -79,6 +79,7 @@ RUN curl -o odoo.deb -sSL http://nightly.odoo.com/${ODOO_VERSION}/nightly/deb/od # Copy entrypoint script and Odoo configuration file COPY ./entrypoint.sh / +RUN chmod +x ./entrypoint.sh COPY ./odoo.conf /etc/odoo/ # Set permissions and Mount /var/lib/odoo to allow restoring filestore and /mnt/extra-addons for users addons From 9b3e6364a571c3518c68ba6dc61e97dbfb9806f0 Mon Sep 17 00:00:00 2001 From: belloafeez Date: Thu, 1 Aug 2024 11:31:11 +0100 Subject: [PATCH 16/54] updated esc task deploy Signed-off-by: belloafeez --- odoo/add-ons.sh | 0 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 odoo/add-ons.sh diff --git a/odoo/add-ons.sh b/odoo/add-ons.sh deleted file mode 100644 index e69de29..0000000 From f899fe1d309fad7742b9d4a16ce71046b9031f3f Mon Sep 17 00:00:00 2001 From: belloafeez Date: Fri, 2 Aug 2024 09:46:29 +0100 Subject: [PATCH 17/54] udtaed Signed-off-by: belloafeez --- .github/workflows/openems-deployment-td.json | 4 +- docker-compose.yml | 84 ++++++++++----- iac/ecs.tf | 4 +- odoo/Dockerfile | 104 ++++++++++++++++++- odoo/Odoo.config | 16 +++ 5 files changed, 179 insertions(+), 33 deletions(-) diff --git a/.github/workflows/openems-deployment-td.json b/.github/workflows/openems-deployment-td.json index e0c5975..6e49c48 100644 --- a/.github/workflows/openems-deployment-td.json +++ b/.github/workflows/openems-deployment-td.json @@ -91,7 +91,7 @@ }, { "name": "PASSWORD", - "value": "odoo16@2022" + "value": "odoo" }, { "name": "HOST", @@ -129,7 +129,7 @@ }, { "name": "POSTGRES_PASSWORD", - "value": "odoo16@2022 " + "value": "odoo" }, { "name": "POSTGRES_DB", diff --git a/docker-compose.yml b/docker-compose.yml index 3b7ba85..c7eaeea 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -22,20 +22,7 @@ services: build: context: ./openems-edge image: openems-edge:latest - - db: - build: - context: ./odoo-database - image: odoo-db - user: root - environment: - - POSTGRES_USER=odoo - - POSTGRES_PASSWORD=odoo16@2022 - - POSTGRES_DB=postgres - restart: always # run as a service - volumes: - - ./postgresql:/var/lib/postgresql/data - + odoo16: build: context: ./odoo @@ -44,23 +31,70 @@ services: depends_on: - db ports: - - "10016:8069" - - "20016:8072" # live chat - tty: true - command: -- + - "8069:8069" + volumes: + - odoo-web-data:/var/lib/odoo + - ./config:/etc/odoo + - ./addons:/mnt/extra-addons environment: - HOST=db - USER=odoo - - PASSWORD=odoo16@2022 + - PASSWORD=odoo # Replace 'odoo-password' with your actual password + db: + build: + context: ./odoo-database + image: odoo-db + user: root + environment: + - POSTGRES_DB=postgres + - POSTGRES_PASSWORD=odoo # Replace 'odoo-password' with your actual password + - POSTGRES_USER=odoo + - PGDATA=/var/lib/postgresql/data/pgdata volumes: - #- /etc/timezone:/etc/timezone:ro - #- /etc/localtime:/etc/localtime:ro - # - ./entrypoint.sh:/entrypoint.sh # if you want to install additional Python packages, uncomment this line! - - ./addons:/mnt/extra-addons - - ./etc:/etc/odoo - restart: always + - odoo-db-data:/var/lib/postgresql/data/pgdata +volumes: + odoo-web-data: + odoo-db-data: + # db: + # build: + # context: ./odoo-database + # image: odoo-db + # user: root + # environment: + # - POSTGRES_USER=odoo + # - POSTGRES_PASSWORD=odoo16@2022 + # - POSTGRES_DB=postgres + # restart: always # run as a service + # volumes: + # - ./postgresql:/var/lib/postgresql/data + + # odoo16: + # build: + # context: ./odoo + # image: odoo + # user: root + # depends_on: + # - db + # ports: + # - "10016:8069" + # - "20016:8072" # live chat + # tty: true + # command: -- + # environment: + # - HOST=db + # - USER=odoo + # - PASSWORD=odoo16@2022 + # volumes: + # #- /etc/timezone:/etc/timezone:ro + # #- /etc/localtime:/etc/localtime:ro + # # - ./entrypoint.sh:/entrypoint.sh # if you want to install additional Python packages, uncomment this line! + # - ./addons:/mnt/extra-addons + # - ./etc:/etc/odoo + # restart: always + + # openems-database: # build: diff --git a/iac/ecs.tf b/iac/ecs.tf index acc0c94..bf8ff0e 100644 --- a/iac/ecs.tf +++ b/iac/ecs.tf @@ -138,7 +138,7 @@ resource "aws_ecs_task_definition" "ecs_task_definition" { }, { name = "PASSWORD", - value = "odoo16@2022" + value = "odoo" } ] @@ -169,7 +169,7 @@ resource "aws_ecs_task_definition" "ecs_task_definition" { }, { name = "POSTGRES_PASSWORD", - value = "odoo16@2022 " + value = "odoo" }, { name = "POSTGRES_DB", diff --git a/odoo/Dockerfile b/odoo/Dockerfile index 23bcdbd..7481bed 100644 --- a/odoo/Dockerfile +++ b/odoo/Dockerfile @@ -1,7 +1,103 @@ -# Use Odoo 16.0 as the base image -FROM odoo:16.0 +FROM debian:bullseye-slim +SHELL ["/bin/bash", "-xo", "pipefail", "-c"] -# Expose port 8069 for Odoo web interface -EXPOSE 8069 \ No newline at end of file +# Generate locale C.UTF-8 for postgres and general locale data +ENV LANG C.UTF-8 + +# Retrieve the target architecture to install the correct wkhtmltopdf package +ARG TARGETARCH + +# Install some deps, lessc and less-plugin-clean-css, and wkhtmltopdf +RUN apt-get update && \ + apt-get install -y --no-install-recommends \ + ca-certificates \ + curl \ + dirmngr \ + fonts-noto-cjk \ + gnupg \ + libssl-dev \ + node-less \ + npm \ + python3-magic \ + python3-num2words \ + python3-odf \ + python3-pdfminer \ + python3-pip \ + python3-phonenumbers \ + python3-pyldap \ + python3-qrcode \ + python3-renderpm \ + python3-setuptools \ + python3-slugify \ + python3-vobject \ + python3-watchdog \ + python3-xlrd \ + python3-xlwt \ + xz-utils && \ + if [ -z "${TARGETARCH}" ]; then \ + TARGETARCH="$(dpkg --print-architecture)"; \ + fi; \ + WKHTMLTOPDF_ARCH=${TARGETARCH} && \ + case ${TARGETARCH} in \ + "amd64") WKHTMLTOPDF_ARCH=amd64 && WKHTMLTOPDF_SHA=9df8dd7b1e99782f1cfa19aca665969bbd9cc159 ;; \ + "arm64") WKHTMLTOPDF_SHA=58c84db46b11ba0e14abb77a32324b1c257f1f22 ;; \ + "ppc64le" | "ppc64el") WKHTMLTOPDF_ARCH=ppc64el && WKHTMLTOPDF_SHA=7ed8f6dcedf5345a3dd4eeb58dc89704d862f9cd ;; \ + esac \ + && curl -o wkhtmltox.deb -sSL https://github.com/wkhtmltopdf/packaging/releases/download/0.12.6.1-3/wkhtmltox_0.12.6.1-3.bullseye_${WKHTMLTOPDF_ARCH}.deb \ + && echo ${WKHTMLTOPDF_SHA} wkhtmltox.deb | sha1sum -c - \ + && apt-get install -y --no-install-recommends ./wkhtmltox.deb \ + && rm -rf /var/lib/apt/lists/* wkhtmltox.deb + +# install latest postgresql-client +RUN echo 'deb http://apt.postgresql.org/pub/repos/apt/ bullseye-pgdg main' > /etc/apt/sources.list.d/pgdg.list \ + && GNUPGHOME="$(mktemp -d)" \ + && export GNUPGHOME \ + && repokey='B97B0AFCAA1A47F044F244A07FCC7D46ACCC4CF8' \ + && gpg --batch --keyserver keyserver.ubuntu.com --recv-keys "${repokey}" \ + && gpg --batch --armor --export "${repokey}" > /etc/apt/trusted.gpg.d/pgdg.gpg.asc \ + && gpgconf --kill all \ + && rm -rf "$GNUPGHOME" \ + && apt-get update \ + && apt-get install --no-install-recommends -y postgresql-client \ + && rm -f /etc/apt/sources.list.d/pgdg.list \ + && rm -rf /var/lib/apt/lists/* + +# Install rtlcss (on Debian buster) +RUN npm install -g rtlcss + +# Install Odoo +ENV ODOO_VERSION 16.0 +ARG ODOO_RELEASE=20240624 +ARG ODOO_SHA=a51d6f097b24096d38959f4cd97ae5fb2cd2807b +RUN curl -o odoo.deb -sSL http://nightly.odoo.com/${ODOO_VERSION}/nightly/deb/odoo_${ODOO_VERSION}.${ODOO_RELEASE}_all.deb \ + && echo "${ODOO_SHA} odoo.deb" | sha1sum -c - \ + && apt-get update \ + && apt-get -y install --no-install-recommends ./odoo.deb \ + && rm -rf /var/lib/apt/lists/* odoo.deb + +# Copy entrypoint script and Odoo configuration file +COPY ./entrypoint.sh / +COPY ./odoo.conf /etc/odoo/ + +# Set permissions and Mount /var/lib/odoo to allow restoring filestore and /mnt/extra-addons for users addons +RUN chown odoo /etc/odoo/odoo.conf \ + && mkdir -p /mnt/extra-addons \ + && chown -R odoo /mnt/extra-addons +VOLUME ["/var/lib/odoo", "/mnt/extra-addons"] + +COPY ./extra-addons /mnt/extra-addons +# Expose Odoo services +EXPOSE 8069 8071 8072 + +# Set the default config file +ENV ODOO_RC /etc/odoo/odoo.conf + +COPY wait-for-psql.py /usr/local/bin/wait-for-psql.py + +# Set default user when running the container +USER odoo + +ENTRYPOINT ["/entrypoint.sh"] +CMD ["odoo"] \ No newline at end of file diff --git a/odoo/Odoo.config b/odoo/Odoo.config index e69de29..75705c9 100644 --- a/odoo/Odoo.config +++ b/odoo/Odoo.config @@ -0,0 +1,16 @@ +# Place in openems-backend/config.d/Metadata +:org.apache.felix.configadmin.revision:=L"2" +database="postgres" +debugMode="ON" +odooHost="localhost" +odooPassword="admin" +odooPort=I"8069" +odooProtocol="HTTP" +odooUid=I"2" +pgConnectionPoolSize=I"40" +pgHost="localhost" +pgPassword="odoo" +pgPort=I"5432" +pgUser="odoo" +poolSize=I"30" +service.pid="Metadata.Odoo" \ No newline at end of file From 572aa2b4d327402e63ec017ad309e5efe77063cf Mon Sep 17 00:00:00 2001 From: belloafeez Date: Thu, 1 Aug 2024 08:35:34 +0100 Subject: [PATCH 18/54] Signed-off-by: belloafeez Added all files for odoo Signed-off-by: belloafeez --- odoo/add-ons.sh | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 odoo/add-ons.sh diff --git a/odoo/add-ons.sh b/odoo/add-ons.sh new file mode 100644 index 0000000..e69de29 From d46a6244b2a7e8b6b15be61a578a3c144af74923 Mon Sep 17 00:00:00 2001 From: belloafeez Date: Thu, 1 Aug 2024 10:24:53 +0100 Subject: [PATCH 19/54] docker compose update Signed-off-by: belloafeez --- docker-compose.yml | 84 ++++++++++++++-------------------------------- 1 file changed, 25 insertions(+), 59 deletions(-) diff --git a/docker-compose.yml b/docker-compose.yml index c7eaeea..3b7ba85 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -22,7 +22,20 @@ services: build: context: ./openems-edge image: openems-edge:latest - + + db: + build: + context: ./odoo-database + image: odoo-db + user: root + environment: + - POSTGRES_USER=odoo + - POSTGRES_PASSWORD=odoo16@2022 + - POSTGRES_DB=postgres + restart: always # run as a service + volumes: + - ./postgresql:/var/lib/postgresql/data + odoo16: build: context: ./odoo @@ -31,70 +44,23 @@ services: depends_on: - db ports: - - "8069:8069" - volumes: - - odoo-web-data:/var/lib/odoo - - ./config:/etc/odoo - - ./addons:/mnt/extra-addons + - "10016:8069" + - "20016:8072" # live chat + tty: true + command: -- environment: - HOST=db - USER=odoo - - PASSWORD=odoo # Replace 'odoo-password' with your actual password - db: - build: - context: ./odoo-database - image: odoo-db - user: root - environment: - - POSTGRES_DB=postgres - - POSTGRES_PASSWORD=odoo # Replace 'odoo-password' with your actual password - - POSTGRES_USER=odoo - - PGDATA=/var/lib/postgresql/data/pgdata + - PASSWORD=odoo16@2022 volumes: - - odoo-db-data:/var/lib/postgresql/data/pgdata -volumes: - odoo-web-data: - odoo-db-data: - - # db: - # build: - # context: ./odoo-database - # image: odoo-db - # user: root - # environment: - # - POSTGRES_USER=odoo - # - POSTGRES_PASSWORD=odoo16@2022 - # - POSTGRES_DB=postgres - # restart: always # run as a service - # volumes: - # - ./postgresql:/var/lib/postgresql/data + #- /etc/timezone:/etc/timezone:ro + #- /etc/localtime:/etc/localtime:ro + # - ./entrypoint.sh:/entrypoint.sh # if you want to install additional Python packages, uncomment this line! + - ./addons:/mnt/extra-addons + - ./etc:/etc/odoo + restart: always - # odoo16: - # build: - # context: ./odoo - # image: odoo - # user: root - # depends_on: - # - db - # ports: - # - "10016:8069" - # - "20016:8072" # live chat - # tty: true - # command: -- - # environment: - # - HOST=db - # - USER=odoo - # - PASSWORD=odoo16@2022 - # volumes: - # #- /etc/timezone:/etc/timezone:ro - # #- /etc/localtime:/etc/localtime:ro - # # - ./entrypoint.sh:/entrypoint.sh # if you want to install additional Python packages, uncomment this line! - # - ./addons:/mnt/extra-addons - # - ./etc:/etc/odoo - # restart: always - - # openems-database: # build: From 7d0c5cb9f72065ba5c415cd30c5f6922c75bb974 Mon Sep 17 00:00:00 2001 From: belloafeez Date: Thu, 1 Aug 2024 11:31:11 +0100 Subject: [PATCH 20/54] updated esc task deploy Signed-off-by: belloafeez --- odoo/add-ons.sh | 0 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 odoo/add-ons.sh diff --git a/odoo/add-ons.sh b/odoo/add-ons.sh deleted file mode 100644 index e69de29..0000000 From 78dde44016dd6902e5f4db3d75db6c9c2c75ce64 Mon Sep 17 00:00:00 2001 From: belloafeez Date: Fri, 2 Aug 2024 09:46:29 +0100 Subject: [PATCH 21/54] udtaed Signed-off-by: belloafeez --- docker-compose.yml | 84 ++++++++++++++++++++++++++++++++-------------- 1 file changed, 59 insertions(+), 25 deletions(-) diff --git a/docker-compose.yml b/docker-compose.yml index 3b7ba85..c7eaeea 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -22,20 +22,7 @@ services: build: context: ./openems-edge image: openems-edge:latest - - db: - build: - context: ./odoo-database - image: odoo-db - user: root - environment: - - POSTGRES_USER=odoo - - POSTGRES_PASSWORD=odoo16@2022 - - POSTGRES_DB=postgres - restart: always # run as a service - volumes: - - ./postgresql:/var/lib/postgresql/data - + odoo16: build: context: ./odoo @@ -44,23 +31,70 @@ services: depends_on: - db ports: - - "10016:8069" - - "20016:8072" # live chat - tty: true - command: -- + - "8069:8069" + volumes: + - odoo-web-data:/var/lib/odoo + - ./config:/etc/odoo + - ./addons:/mnt/extra-addons environment: - HOST=db - USER=odoo - - PASSWORD=odoo16@2022 + - PASSWORD=odoo # Replace 'odoo-password' with your actual password + db: + build: + context: ./odoo-database + image: odoo-db + user: root + environment: + - POSTGRES_DB=postgres + - POSTGRES_PASSWORD=odoo # Replace 'odoo-password' with your actual password + - POSTGRES_USER=odoo + - PGDATA=/var/lib/postgresql/data/pgdata volumes: - #- /etc/timezone:/etc/timezone:ro - #- /etc/localtime:/etc/localtime:ro - # - ./entrypoint.sh:/entrypoint.sh # if you want to install additional Python packages, uncomment this line! - - ./addons:/mnt/extra-addons - - ./etc:/etc/odoo - restart: always + - odoo-db-data:/var/lib/postgresql/data/pgdata +volumes: + odoo-web-data: + odoo-db-data: + # db: + # build: + # context: ./odoo-database + # image: odoo-db + # user: root + # environment: + # - POSTGRES_USER=odoo + # - POSTGRES_PASSWORD=odoo16@2022 + # - POSTGRES_DB=postgres + # restart: always # run as a service + # volumes: + # - ./postgresql:/var/lib/postgresql/data + + # odoo16: + # build: + # context: ./odoo + # image: odoo + # user: root + # depends_on: + # - db + # ports: + # - "10016:8069" + # - "20016:8072" # live chat + # tty: true + # command: -- + # environment: + # - HOST=db + # - USER=odoo + # - PASSWORD=odoo16@2022 + # volumes: + # #- /etc/timezone:/etc/timezone:ro + # #- /etc/localtime:/etc/localtime:ro + # # - ./entrypoint.sh:/entrypoint.sh # if you want to install additional Python packages, uncomment this line! + # - ./addons:/mnt/extra-addons + # - ./etc:/etc/odoo + # restart: always + + # openems-database: # build: From 50955b0363e359af1ce20202d9a26fee48c65221 Mon Sep 17 00:00:00 2001 From: belloafeez Date: Fri, 2 Aug 2024 10:12:04 +0100 Subject: [PATCH 22/54] updated Signed-off-by: belloafeez --- {addons => odoo/extra-addons}/openems/.gitignore | 0 {addons => odoo/extra-addons}/openems/__init__.py | 0 .../extra-addons}/openems/__manifest__.py | 0 .../extra-addons}/openems/controllers/__init__.py | 0 .../extra-addons}/openems/controllers/alerting.py | 0 .../extra-addons}/openems/controllers/const.py | 0 .../openems/controllers/openems_backend.py | 0 .../openems/controllers/setup_protocol.py | 0 .../extra-addons}/openems/controllers/user.py | 0 .../extra-addons}/openems/data/OpenEMS-Logo.jpg | Bin {addons => odoo/extra-addons}/openems/data/demo.xml | 0 .../openems/data/ir_config_parameter.xml | 0 .../openems/data/res_partner_category.xml | 0 {addons => odoo/extra-addons}/openems/i18n/de.po | 0 .../extra-addons}/openems/i18n/openems.pot | 0 .../openems/mail/openems/alerting_offline.xml | 0 .../openems/mail/openems/alerting_sum_state.xml | 0 .../mail/openems/setup_protocol_customer.xml | 0 .../mail/openems/setup_protocol_installer.xml | 0 .../openems/mail/openems/user_registration.xml | 0 .../openems/migrations/16.0.1.0.1/post-migrate.py | 0 .../openems/migrations/16.0.1.0.1/pre-migrate.py | 0 .../extra-addons}/openems/models/__init__.py | 0 .../extra-addons}/openems/models/device.py | 0 .../extra-addons}/openems/models/partner.py | 0 .../extra-addons}/openems/models/setup_protocol.py | 0 .../openems/models/stock_production_lot.py | 0 .../extra-addons}/openems/models/user.py | 0 .../extra-addons}/openems/report/setup_protocol.xml | 0 .../openems/security/ir.model.access.csv | 0 .../extra-addons}/openems/security/openems.xml | 0 .../setup/.setuptools-odoo-make-default-ignore | 0 {addons => odoo/extra-addons}/openems/setup/README | 0 .../openems/static/description/icon.png | Bin .../openems/static/mail/OpenEMS-Logo.jpg | Bin .../extra-addons}/openems/views/device.xml | 0 .../extra-addons}/openems/views/partner.xml | 0 .../extra-addons}/openems/views/setup_protocol.xml | 0 .../openems/views/stock_production_lot_views.xml | 0 .../extra-addons}/openems/views/user.xml | 0 .../extra-addons}/partner_firstname/README.rst | 0 .../extra-addons}/partner_firstname/__init__.py | 0 .../extra-addons}/partner_firstname/__manifest__.py | 0 .../extra-addons}/partner_firstname/exceptions.py | 0 .../extra-addons}/partner_firstname/hooks.py | 0 .../extra-addons}/partner_firstname/i18n/am.po | 0 .../extra-addons}/partner_firstname/i18n/ar.po | 0 .../extra-addons}/partner_firstname/i18n/bg.po | 0 .../extra-addons}/partner_firstname/i18n/bs.po | 0 .../extra-addons}/partner_firstname/i18n/ca.po | 0 .../extra-addons}/partner_firstname/i18n/cs.po | 0 .../extra-addons}/partner_firstname/i18n/da.po | 0 .../extra-addons}/partner_firstname/i18n/de.po | 0 .../extra-addons}/partner_firstname/i18n/el_GR.po | 0 .../extra-addons}/partner_firstname/i18n/en_GB.po | 0 .../extra-addons}/partner_firstname/i18n/es.po | 0 .../extra-addons}/partner_firstname/i18n/es_CR.po | 0 .../extra-addons}/partner_firstname/i18n/es_EC.po | 0 .../extra-addons}/partner_firstname/i18n/es_MX.po | 0 .../extra-addons}/partner_firstname/i18n/es_VE.po | 0 .../extra-addons}/partner_firstname/i18n/et.po | 0 .../extra-addons}/partner_firstname/i18n/eu.po | 0 .../extra-addons}/partner_firstname/i18n/fi.po | 0 .../extra-addons}/partner_firstname/i18n/fr.po | 0 .../extra-addons}/partner_firstname/i18n/fr_CA.po | 0 .../extra-addons}/partner_firstname/i18n/fr_CH.po | 0 .../extra-addons}/partner_firstname/i18n/gl.po | 0 .../extra-addons}/partner_firstname/i18n/hr.po | 0 .../extra-addons}/partner_firstname/i18n/hr_HR.po | 0 .../extra-addons}/partner_firstname/i18n/hu.po | 0 .../extra-addons}/partner_firstname/i18n/it.po | 0 .../extra-addons}/partner_firstname/i18n/ja.po | 0 .../extra-addons}/partner_firstname/i18n/lt.po | 0 .../extra-addons}/partner_firstname/i18n/lv.po | 0 .../extra-addons}/partner_firstname/i18n/mk.po | 0 .../extra-addons}/partner_firstname/i18n/mn.po | 0 .../extra-addons}/partner_firstname/i18n/nb.po | 0 .../extra-addons}/partner_firstname/i18n/nb_NO.po | 0 .../extra-addons}/partner_firstname/i18n/nl.po | 0 .../extra-addons}/partner_firstname/i18n/nl_BE.po | 0 .../extra-addons}/partner_firstname/i18n/nl_NL.po | 0 .../partner_firstname/i18n/partner_firstname.pot | 0 .../extra-addons}/partner_firstname/i18n/pl.po | 0 .../extra-addons}/partner_firstname/i18n/pt.po | 0 .../extra-addons}/partner_firstname/i18n/pt_BR.po | 0 .../extra-addons}/partner_firstname/i18n/pt_PT.po | 0 .../extra-addons}/partner_firstname/i18n/ro.po | 0 .../extra-addons}/partner_firstname/i18n/ru.po | 0 .../extra-addons}/partner_firstname/i18n/sk.po | 0 .../extra-addons}/partner_firstname/i18n/sl.po | 0 .../partner_firstname/i18n/sr@latin.po | 0 .../extra-addons}/partner_firstname/i18n/sv.po | 0 .../extra-addons}/partner_firstname/i18n/th.po | 0 .../extra-addons}/partner_firstname/i18n/tr.po | 0 .../extra-addons}/partner_firstname/i18n/tr_TR.po | 0 .../extra-addons}/partner_firstname/i18n/vi.po | 0 .../extra-addons}/partner_firstname/i18n/zh_CN.po | 0 .../extra-addons}/partner_firstname/i18n/zh_TW.po | 0 .../partner_firstname/models/__init__.py | 0 .../models/base_config_settings.py | 0 .../partner_firstname/models/res_partner.py | 0 .../partner_firstname/models/res_users.py | 0 .../partner_firstname/readme/CONFIGURE.rst | 0 .../partner_firstname/readme/CONTRIBUTORS.rst | 0 .../partner_firstname/readme/DESCRIPTION.rst | 0 .../partner_firstname/readme/ROADMAP.rst | 0 .../partner_firstname/readme/USAGE.rst | 0 .../partner_firstname/static/description/icon.png | Bin .../partner_firstname/static/description/index.html | 0 .../partner_firstname/tests/__init__.py | 0 .../extra-addons}/partner_firstname/tests/base.py | 0 .../partner_firstname/tests/test_config_settings.py | 0 .../partner_firstname/tests/test_copy.py | 0 .../partner_firstname/tests/test_create.py | 0 .../partner_firstname/tests/test_defaults.py | 0 .../partner_firstname/tests/test_delete.py | 0 .../partner_firstname/tests/test_empty.py | 0 .../partner_firstname/tests/test_name.py | 0 .../partner_firstname/tests/test_order.py | 0 .../partner_firstname/tests/test_partner_form.py | 0 .../partner_firstname/tests/test_user_form.py | 0 .../partner_firstname/views/base_config_view.xml | 0 .../partner_firstname/views/res_partner.xml | 0 .../partner_firstname/views/res_user.xml | 0 {addons => odoo/extra-addons}/readme.md | 0 .../extra-addons}/web_m2x_options/README.rst | 0 .../extra-addons}/web_m2x_options/__init__.py | 0 .../extra-addons}/web_m2x_options/__manifest__.py | 0 .../extra-addons}/web_m2x_options/i18n/ar.po | 0 .../extra-addons}/web_m2x_options/i18n/de.po | 0 .../extra-addons}/web_m2x_options/i18n/es.po | 0 .../extra-addons}/web_m2x_options/i18n/es_BO.po | 0 .../extra-addons}/web_m2x_options/i18n/fi.po | 0 .../extra-addons}/web_m2x_options/i18n/fr.po | 0 .../extra-addons}/web_m2x_options/i18n/hr.po | 0 .../extra-addons}/web_m2x_options/i18n/it.po | 0 .../extra-addons}/web_m2x_options/i18n/nl.po | 0 .../extra-addons}/web_m2x_options/i18n/nl_NL.po | 0 .../extra-addons}/web_m2x_options/i18n/pt_BR.po | 0 .../extra-addons}/web_m2x_options/i18n/sl.po | 0 .../extra-addons}/web_m2x_options/i18n/tr.po | 0 .../web_m2x_options/i18n/web_m2x_options.pot | 0 .../extra-addons}/web_m2x_options/i18n/zh_CN.po | 0 .../web_m2x_options/models/__init__.py | 0 .../web_m2x_options/models/ir_config_parameter.py | 0 .../extra-addons}/web_m2x_options/models/ir_http.py | 0 .../web_m2x_options/readme/CONTRIBUTORS.rst | 0 .../web_m2x_options/readme/CREDITS.rst | 0 .../web_m2x_options/readme/DESCRIPTION.rst | 0 .../web_m2x_options/readme/ROADMAP.rst | 0 .../extra-addons}/web_m2x_options/readme/USAGE.rst | 0 .../web_m2x_options/static/description/icon.png | Bin .../web_m2x_options/static/description/index.html | 0 .../web_m2x_options/static/src/components/base.xml | 0 .../static/src/components/form.esm.js | 0 .../static/src/components/relational_utils.esm.js | 0 .../extra-addons}/web_m2x_options/tests/__init__.py | 0 .../tests/test_ir_config_parameter.py | 0 158 files changed, 0 insertions(+), 0 deletions(-) rename {addons => odoo/extra-addons}/openems/.gitignore (100%) rename {addons => odoo/extra-addons}/openems/__init__.py (100%) rename {addons => odoo/extra-addons}/openems/__manifest__.py (100%) rename {addons => odoo/extra-addons}/openems/controllers/__init__.py (100%) rename {addons => odoo/extra-addons}/openems/controllers/alerting.py (100%) rename {addons => odoo/extra-addons}/openems/controllers/const.py (100%) rename {addons => odoo/extra-addons}/openems/controllers/openems_backend.py (100%) rename {addons => odoo/extra-addons}/openems/controllers/setup_protocol.py (100%) rename {addons => odoo/extra-addons}/openems/controllers/user.py (100%) rename {addons => odoo/extra-addons}/openems/data/OpenEMS-Logo.jpg (100%) rename {addons => odoo/extra-addons}/openems/data/demo.xml (100%) rename {addons => odoo/extra-addons}/openems/data/ir_config_parameter.xml (100%) rename {addons => odoo/extra-addons}/openems/data/res_partner_category.xml (100%) rename {addons => odoo/extra-addons}/openems/i18n/de.po (100%) rename {addons => odoo/extra-addons}/openems/i18n/openems.pot (100%) rename {addons => odoo/extra-addons}/openems/mail/openems/alerting_offline.xml (100%) rename {addons => odoo/extra-addons}/openems/mail/openems/alerting_sum_state.xml (100%) rename {addons => odoo/extra-addons}/openems/mail/openems/setup_protocol_customer.xml (100%) rename {addons => odoo/extra-addons}/openems/mail/openems/setup_protocol_installer.xml (100%) rename {addons => odoo/extra-addons}/openems/mail/openems/user_registration.xml (100%) rename {addons => odoo/extra-addons}/openems/migrations/16.0.1.0.1/post-migrate.py (100%) rename {addons => odoo/extra-addons}/openems/migrations/16.0.1.0.1/pre-migrate.py (100%) rename {addons => odoo/extra-addons}/openems/models/__init__.py (100%) rename {addons => odoo/extra-addons}/openems/models/device.py (100%) rename {addons => odoo/extra-addons}/openems/models/partner.py (100%) rename {addons => odoo/extra-addons}/openems/models/setup_protocol.py (100%) rename {addons => odoo/extra-addons}/openems/models/stock_production_lot.py (100%) rename {addons => odoo/extra-addons}/openems/models/user.py (100%) rename {addons => odoo/extra-addons}/openems/report/setup_protocol.xml (100%) rename {addons => odoo/extra-addons}/openems/security/ir.model.access.csv (100%) rename {addons => odoo/extra-addons}/openems/security/openems.xml (100%) rename {addons => odoo/extra-addons}/openems/setup/.setuptools-odoo-make-default-ignore (100%) rename {addons => odoo/extra-addons}/openems/setup/README (100%) rename {addons => odoo/extra-addons}/openems/static/description/icon.png (100%) rename {addons => odoo/extra-addons}/openems/static/mail/OpenEMS-Logo.jpg (100%) rename {addons => odoo/extra-addons}/openems/views/device.xml (100%) rename {addons => odoo/extra-addons}/openems/views/partner.xml (100%) rename {addons => odoo/extra-addons}/openems/views/setup_protocol.xml (100%) rename {addons => odoo/extra-addons}/openems/views/stock_production_lot_views.xml (100%) rename {addons => odoo/extra-addons}/openems/views/user.xml (100%) rename {addons => odoo/extra-addons}/partner_firstname/README.rst (100%) rename {addons => odoo/extra-addons}/partner_firstname/__init__.py (100%) rename {addons => odoo/extra-addons}/partner_firstname/__manifest__.py (100%) rename {addons => odoo/extra-addons}/partner_firstname/exceptions.py (100%) rename {addons => odoo/extra-addons}/partner_firstname/hooks.py (100%) rename {addons => odoo/extra-addons}/partner_firstname/i18n/am.po (100%) rename {addons => odoo/extra-addons}/partner_firstname/i18n/ar.po (100%) rename {addons => odoo/extra-addons}/partner_firstname/i18n/bg.po (100%) rename {addons => odoo/extra-addons}/partner_firstname/i18n/bs.po (100%) rename {addons => odoo/extra-addons}/partner_firstname/i18n/ca.po (100%) rename {addons => odoo/extra-addons}/partner_firstname/i18n/cs.po (100%) rename {addons => odoo/extra-addons}/partner_firstname/i18n/da.po (100%) rename {addons => odoo/extra-addons}/partner_firstname/i18n/de.po (100%) rename {addons => odoo/extra-addons}/partner_firstname/i18n/el_GR.po (100%) rename {addons => odoo/extra-addons}/partner_firstname/i18n/en_GB.po (100%) rename {addons => odoo/extra-addons}/partner_firstname/i18n/es.po (100%) rename {addons => odoo/extra-addons}/partner_firstname/i18n/es_CR.po (100%) rename {addons => odoo/extra-addons}/partner_firstname/i18n/es_EC.po (100%) rename {addons => odoo/extra-addons}/partner_firstname/i18n/es_MX.po (100%) rename {addons => odoo/extra-addons}/partner_firstname/i18n/es_VE.po (100%) rename {addons => odoo/extra-addons}/partner_firstname/i18n/et.po (100%) rename {addons => odoo/extra-addons}/partner_firstname/i18n/eu.po (100%) rename {addons => odoo/extra-addons}/partner_firstname/i18n/fi.po (100%) rename {addons => odoo/extra-addons}/partner_firstname/i18n/fr.po (100%) rename {addons => odoo/extra-addons}/partner_firstname/i18n/fr_CA.po (100%) rename {addons => odoo/extra-addons}/partner_firstname/i18n/fr_CH.po (100%) rename {addons => odoo/extra-addons}/partner_firstname/i18n/gl.po (100%) rename {addons => odoo/extra-addons}/partner_firstname/i18n/hr.po (100%) rename {addons => odoo/extra-addons}/partner_firstname/i18n/hr_HR.po (100%) rename {addons => odoo/extra-addons}/partner_firstname/i18n/hu.po (100%) rename {addons => odoo/extra-addons}/partner_firstname/i18n/it.po (100%) rename {addons => odoo/extra-addons}/partner_firstname/i18n/ja.po (100%) rename {addons => odoo/extra-addons}/partner_firstname/i18n/lt.po (100%) rename {addons => odoo/extra-addons}/partner_firstname/i18n/lv.po (100%) rename {addons => odoo/extra-addons}/partner_firstname/i18n/mk.po (100%) rename {addons => odoo/extra-addons}/partner_firstname/i18n/mn.po (100%) rename {addons => odoo/extra-addons}/partner_firstname/i18n/nb.po (100%) rename {addons => odoo/extra-addons}/partner_firstname/i18n/nb_NO.po (100%) rename {addons => odoo/extra-addons}/partner_firstname/i18n/nl.po (100%) rename {addons => odoo/extra-addons}/partner_firstname/i18n/nl_BE.po (100%) rename {addons => odoo/extra-addons}/partner_firstname/i18n/nl_NL.po (100%) rename {addons => odoo/extra-addons}/partner_firstname/i18n/partner_firstname.pot (100%) rename {addons => odoo/extra-addons}/partner_firstname/i18n/pl.po (100%) rename {addons => odoo/extra-addons}/partner_firstname/i18n/pt.po (100%) rename {addons => odoo/extra-addons}/partner_firstname/i18n/pt_BR.po (100%) rename {addons => odoo/extra-addons}/partner_firstname/i18n/pt_PT.po (100%) rename {addons => odoo/extra-addons}/partner_firstname/i18n/ro.po (100%) rename {addons => odoo/extra-addons}/partner_firstname/i18n/ru.po (100%) rename {addons => odoo/extra-addons}/partner_firstname/i18n/sk.po (100%) rename {addons => odoo/extra-addons}/partner_firstname/i18n/sl.po (100%) rename {addons => odoo/extra-addons}/partner_firstname/i18n/sr@latin.po (100%) rename {addons => odoo/extra-addons}/partner_firstname/i18n/sv.po (100%) rename {addons => odoo/extra-addons}/partner_firstname/i18n/th.po (100%) rename {addons => odoo/extra-addons}/partner_firstname/i18n/tr.po (100%) rename {addons => odoo/extra-addons}/partner_firstname/i18n/tr_TR.po (100%) rename {addons => odoo/extra-addons}/partner_firstname/i18n/vi.po (100%) rename {addons => odoo/extra-addons}/partner_firstname/i18n/zh_CN.po (100%) rename {addons => odoo/extra-addons}/partner_firstname/i18n/zh_TW.po (100%) rename {addons => odoo/extra-addons}/partner_firstname/models/__init__.py (100%) rename {addons => odoo/extra-addons}/partner_firstname/models/base_config_settings.py (100%) rename {addons => odoo/extra-addons}/partner_firstname/models/res_partner.py (100%) rename {addons => odoo/extra-addons}/partner_firstname/models/res_users.py (100%) rename {addons => odoo/extra-addons}/partner_firstname/readme/CONFIGURE.rst (100%) rename {addons => odoo/extra-addons}/partner_firstname/readme/CONTRIBUTORS.rst (100%) rename {addons => odoo/extra-addons}/partner_firstname/readme/DESCRIPTION.rst (100%) rename {addons => odoo/extra-addons}/partner_firstname/readme/ROADMAP.rst (100%) rename {addons => odoo/extra-addons}/partner_firstname/readme/USAGE.rst (100%) rename {addons => odoo/extra-addons}/partner_firstname/static/description/icon.png (100%) rename {addons => odoo/extra-addons}/partner_firstname/static/description/index.html (100%) rename {addons => odoo/extra-addons}/partner_firstname/tests/__init__.py (100%) rename {addons => odoo/extra-addons}/partner_firstname/tests/base.py (100%) rename {addons => odoo/extra-addons}/partner_firstname/tests/test_config_settings.py (100%) rename {addons => odoo/extra-addons}/partner_firstname/tests/test_copy.py (100%) rename {addons => odoo/extra-addons}/partner_firstname/tests/test_create.py (100%) rename {addons => odoo/extra-addons}/partner_firstname/tests/test_defaults.py (100%) rename {addons => odoo/extra-addons}/partner_firstname/tests/test_delete.py (100%) rename {addons => odoo/extra-addons}/partner_firstname/tests/test_empty.py (100%) rename {addons => odoo/extra-addons}/partner_firstname/tests/test_name.py (100%) rename {addons => odoo/extra-addons}/partner_firstname/tests/test_order.py (100%) rename {addons => odoo/extra-addons}/partner_firstname/tests/test_partner_form.py (100%) rename {addons => odoo/extra-addons}/partner_firstname/tests/test_user_form.py (100%) rename {addons => odoo/extra-addons}/partner_firstname/views/base_config_view.xml (100%) rename {addons => odoo/extra-addons}/partner_firstname/views/res_partner.xml (100%) rename {addons => odoo/extra-addons}/partner_firstname/views/res_user.xml (100%) rename {addons => odoo/extra-addons}/readme.md (100%) rename {addons => odoo/extra-addons}/web_m2x_options/README.rst (100%) rename {addons => odoo/extra-addons}/web_m2x_options/__init__.py (100%) rename {addons => odoo/extra-addons}/web_m2x_options/__manifest__.py (100%) rename {addons => odoo/extra-addons}/web_m2x_options/i18n/ar.po (100%) rename {addons => odoo/extra-addons}/web_m2x_options/i18n/de.po (100%) rename {addons => odoo/extra-addons}/web_m2x_options/i18n/es.po (100%) rename {addons => odoo/extra-addons}/web_m2x_options/i18n/es_BO.po (100%) rename {addons => odoo/extra-addons}/web_m2x_options/i18n/fi.po (100%) rename {addons => odoo/extra-addons}/web_m2x_options/i18n/fr.po (100%) rename {addons => odoo/extra-addons}/web_m2x_options/i18n/hr.po (100%) rename {addons => odoo/extra-addons}/web_m2x_options/i18n/it.po (100%) rename {addons => odoo/extra-addons}/web_m2x_options/i18n/nl.po (100%) rename {addons => odoo/extra-addons}/web_m2x_options/i18n/nl_NL.po (100%) rename {addons => odoo/extra-addons}/web_m2x_options/i18n/pt_BR.po (100%) rename {addons => odoo/extra-addons}/web_m2x_options/i18n/sl.po (100%) rename {addons => odoo/extra-addons}/web_m2x_options/i18n/tr.po (100%) rename {addons => odoo/extra-addons}/web_m2x_options/i18n/web_m2x_options.pot (100%) rename {addons => odoo/extra-addons}/web_m2x_options/i18n/zh_CN.po (100%) rename {addons => odoo/extra-addons}/web_m2x_options/models/__init__.py (100%) rename {addons => odoo/extra-addons}/web_m2x_options/models/ir_config_parameter.py (100%) rename {addons => odoo/extra-addons}/web_m2x_options/models/ir_http.py (100%) rename {addons => odoo/extra-addons}/web_m2x_options/readme/CONTRIBUTORS.rst (100%) rename {addons => odoo/extra-addons}/web_m2x_options/readme/CREDITS.rst (100%) rename {addons => odoo/extra-addons}/web_m2x_options/readme/DESCRIPTION.rst (100%) rename {addons => odoo/extra-addons}/web_m2x_options/readme/ROADMAP.rst (100%) rename {addons => odoo/extra-addons}/web_m2x_options/readme/USAGE.rst (100%) rename {addons => odoo/extra-addons}/web_m2x_options/static/description/icon.png (100%) rename {addons => odoo/extra-addons}/web_m2x_options/static/description/index.html (100%) rename {addons => odoo/extra-addons}/web_m2x_options/static/src/components/base.xml (100%) rename {addons => odoo/extra-addons}/web_m2x_options/static/src/components/form.esm.js (100%) rename {addons => odoo/extra-addons}/web_m2x_options/static/src/components/relational_utils.esm.js (100%) rename {addons => odoo/extra-addons}/web_m2x_options/tests/__init__.py (100%) rename {addons => odoo/extra-addons}/web_m2x_options/tests/test_ir_config_parameter.py (100%) diff --git a/addons/openems/.gitignore b/odoo/extra-addons/openems/.gitignore similarity index 100% rename from addons/openems/.gitignore rename to odoo/extra-addons/openems/.gitignore diff --git a/addons/openems/__init__.py b/odoo/extra-addons/openems/__init__.py similarity index 100% rename from addons/openems/__init__.py rename to odoo/extra-addons/openems/__init__.py diff --git a/addons/openems/__manifest__.py b/odoo/extra-addons/openems/__manifest__.py similarity index 100% rename from addons/openems/__manifest__.py rename to odoo/extra-addons/openems/__manifest__.py diff --git a/addons/openems/controllers/__init__.py b/odoo/extra-addons/openems/controllers/__init__.py similarity index 100% rename from addons/openems/controllers/__init__.py rename to odoo/extra-addons/openems/controllers/__init__.py diff --git a/addons/openems/controllers/alerting.py b/odoo/extra-addons/openems/controllers/alerting.py similarity index 100% rename from addons/openems/controllers/alerting.py rename to odoo/extra-addons/openems/controllers/alerting.py diff --git a/addons/openems/controllers/const.py b/odoo/extra-addons/openems/controllers/const.py similarity index 100% rename from addons/openems/controllers/const.py rename to odoo/extra-addons/openems/controllers/const.py diff --git a/addons/openems/controllers/openems_backend.py b/odoo/extra-addons/openems/controllers/openems_backend.py similarity index 100% rename from addons/openems/controllers/openems_backend.py rename to odoo/extra-addons/openems/controllers/openems_backend.py diff --git a/addons/openems/controllers/setup_protocol.py b/odoo/extra-addons/openems/controllers/setup_protocol.py similarity index 100% rename from addons/openems/controllers/setup_protocol.py rename to odoo/extra-addons/openems/controllers/setup_protocol.py diff --git a/addons/openems/controllers/user.py b/odoo/extra-addons/openems/controllers/user.py similarity index 100% rename from addons/openems/controllers/user.py rename to odoo/extra-addons/openems/controllers/user.py diff --git a/addons/openems/data/OpenEMS-Logo.jpg b/odoo/extra-addons/openems/data/OpenEMS-Logo.jpg similarity index 100% rename from addons/openems/data/OpenEMS-Logo.jpg rename to odoo/extra-addons/openems/data/OpenEMS-Logo.jpg diff --git a/addons/openems/data/demo.xml b/odoo/extra-addons/openems/data/demo.xml similarity index 100% rename from addons/openems/data/demo.xml rename to odoo/extra-addons/openems/data/demo.xml diff --git a/addons/openems/data/ir_config_parameter.xml b/odoo/extra-addons/openems/data/ir_config_parameter.xml similarity index 100% rename from addons/openems/data/ir_config_parameter.xml rename to odoo/extra-addons/openems/data/ir_config_parameter.xml diff --git a/addons/openems/data/res_partner_category.xml b/odoo/extra-addons/openems/data/res_partner_category.xml similarity index 100% rename from addons/openems/data/res_partner_category.xml rename to odoo/extra-addons/openems/data/res_partner_category.xml diff --git a/addons/openems/i18n/de.po b/odoo/extra-addons/openems/i18n/de.po similarity index 100% rename from addons/openems/i18n/de.po rename to odoo/extra-addons/openems/i18n/de.po diff --git a/addons/openems/i18n/openems.pot b/odoo/extra-addons/openems/i18n/openems.pot similarity index 100% rename from addons/openems/i18n/openems.pot rename to odoo/extra-addons/openems/i18n/openems.pot diff --git a/addons/openems/mail/openems/alerting_offline.xml b/odoo/extra-addons/openems/mail/openems/alerting_offline.xml similarity index 100% rename from addons/openems/mail/openems/alerting_offline.xml rename to odoo/extra-addons/openems/mail/openems/alerting_offline.xml diff --git a/addons/openems/mail/openems/alerting_sum_state.xml b/odoo/extra-addons/openems/mail/openems/alerting_sum_state.xml similarity index 100% rename from addons/openems/mail/openems/alerting_sum_state.xml rename to odoo/extra-addons/openems/mail/openems/alerting_sum_state.xml diff --git a/addons/openems/mail/openems/setup_protocol_customer.xml b/odoo/extra-addons/openems/mail/openems/setup_protocol_customer.xml similarity index 100% rename from addons/openems/mail/openems/setup_protocol_customer.xml rename to odoo/extra-addons/openems/mail/openems/setup_protocol_customer.xml diff --git a/addons/openems/mail/openems/setup_protocol_installer.xml b/odoo/extra-addons/openems/mail/openems/setup_protocol_installer.xml similarity index 100% rename from addons/openems/mail/openems/setup_protocol_installer.xml rename to odoo/extra-addons/openems/mail/openems/setup_protocol_installer.xml diff --git a/addons/openems/mail/openems/user_registration.xml b/odoo/extra-addons/openems/mail/openems/user_registration.xml similarity index 100% rename from addons/openems/mail/openems/user_registration.xml rename to odoo/extra-addons/openems/mail/openems/user_registration.xml diff --git a/addons/openems/migrations/16.0.1.0.1/post-migrate.py b/odoo/extra-addons/openems/migrations/16.0.1.0.1/post-migrate.py similarity index 100% rename from addons/openems/migrations/16.0.1.0.1/post-migrate.py rename to odoo/extra-addons/openems/migrations/16.0.1.0.1/post-migrate.py diff --git a/addons/openems/migrations/16.0.1.0.1/pre-migrate.py b/odoo/extra-addons/openems/migrations/16.0.1.0.1/pre-migrate.py similarity index 100% rename from addons/openems/migrations/16.0.1.0.1/pre-migrate.py rename to odoo/extra-addons/openems/migrations/16.0.1.0.1/pre-migrate.py diff --git a/addons/openems/models/__init__.py b/odoo/extra-addons/openems/models/__init__.py similarity index 100% rename from addons/openems/models/__init__.py rename to odoo/extra-addons/openems/models/__init__.py diff --git a/addons/openems/models/device.py b/odoo/extra-addons/openems/models/device.py similarity index 100% rename from addons/openems/models/device.py rename to odoo/extra-addons/openems/models/device.py diff --git a/addons/openems/models/partner.py b/odoo/extra-addons/openems/models/partner.py similarity index 100% rename from addons/openems/models/partner.py rename to odoo/extra-addons/openems/models/partner.py diff --git a/addons/openems/models/setup_protocol.py b/odoo/extra-addons/openems/models/setup_protocol.py similarity index 100% rename from addons/openems/models/setup_protocol.py rename to odoo/extra-addons/openems/models/setup_protocol.py diff --git a/addons/openems/models/stock_production_lot.py b/odoo/extra-addons/openems/models/stock_production_lot.py similarity index 100% rename from addons/openems/models/stock_production_lot.py rename to odoo/extra-addons/openems/models/stock_production_lot.py diff --git a/addons/openems/models/user.py b/odoo/extra-addons/openems/models/user.py similarity index 100% rename from addons/openems/models/user.py rename to odoo/extra-addons/openems/models/user.py diff --git a/addons/openems/report/setup_protocol.xml b/odoo/extra-addons/openems/report/setup_protocol.xml similarity index 100% rename from addons/openems/report/setup_protocol.xml rename to odoo/extra-addons/openems/report/setup_protocol.xml diff --git a/addons/openems/security/ir.model.access.csv b/odoo/extra-addons/openems/security/ir.model.access.csv similarity index 100% rename from addons/openems/security/ir.model.access.csv rename to odoo/extra-addons/openems/security/ir.model.access.csv diff --git a/addons/openems/security/openems.xml b/odoo/extra-addons/openems/security/openems.xml similarity index 100% rename from addons/openems/security/openems.xml rename to odoo/extra-addons/openems/security/openems.xml diff --git a/addons/openems/setup/.setuptools-odoo-make-default-ignore b/odoo/extra-addons/openems/setup/.setuptools-odoo-make-default-ignore similarity index 100% rename from addons/openems/setup/.setuptools-odoo-make-default-ignore rename to odoo/extra-addons/openems/setup/.setuptools-odoo-make-default-ignore diff --git a/addons/openems/setup/README b/odoo/extra-addons/openems/setup/README similarity index 100% rename from addons/openems/setup/README rename to odoo/extra-addons/openems/setup/README diff --git a/addons/openems/static/description/icon.png b/odoo/extra-addons/openems/static/description/icon.png similarity index 100% rename from addons/openems/static/description/icon.png rename to odoo/extra-addons/openems/static/description/icon.png diff --git a/addons/openems/static/mail/OpenEMS-Logo.jpg b/odoo/extra-addons/openems/static/mail/OpenEMS-Logo.jpg similarity index 100% rename from addons/openems/static/mail/OpenEMS-Logo.jpg rename to odoo/extra-addons/openems/static/mail/OpenEMS-Logo.jpg diff --git a/addons/openems/views/device.xml b/odoo/extra-addons/openems/views/device.xml similarity index 100% rename from addons/openems/views/device.xml rename to odoo/extra-addons/openems/views/device.xml diff --git a/addons/openems/views/partner.xml b/odoo/extra-addons/openems/views/partner.xml similarity index 100% rename from addons/openems/views/partner.xml rename to odoo/extra-addons/openems/views/partner.xml diff --git a/addons/openems/views/setup_protocol.xml b/odoo/extra-addons/openems/views/setup_protocol.xml similarity index 100% rename from addons/openems/views/setup_protocol.xml rename to odoo/extra-addons/openems/views/setup_protocol.xml diff --git a/addons/openems/views/stock_production_lot_views.xml b/odoo/extra-addons/openems/views/stock_production_lot_views.xml similarity index 100% rename from addons/openems/views/stock_production_lot_views.xml rename to odoo/extra-addons/openems/views/stock_production_lot_views.xml diff --git a/addons/openems/views/user.xml b/odoo/extra-addons/openems/views/user.xml similarity index 100% rename from addons/openems/views/user.xml rename to odoo/extra-addons/openems/views/user.xml diff --git a/addons/partner_firstname/README.rst b/odoo/extra-addons/partner_firstname/README.rst similarity index 100% rename from addons/partner_firstname/README.rst rename to odoo/extra-addons/partner_firstname/README.rst diff --git a/addons/partner_firstname/__init__.py b/odoo/extra-addons/partner_firstname/__init__.py similarity index 100% rename from addons/partner_firstname/__init__.py rename to odoo/extra-addons/partner_firstname/__init__.py diff --git a/addons/partner_firstname/__manifest__.py b/odoo/extra-addons/partner_firstname/__manifest__.py similarity index 100% rename from addons/partner_firstname/__manifest__.py rename to odoo/extra-addons/partner_firstname/__manifest__.py diff --git a/addons/partner_firstname/exceptions.py b/odoo/extra-addons/partner_firstname/exceptions.py similarity index 100% rename from addons/partner_firstname/exceptions.py rename to odoo/extra-addons/partner_firstname/exceptions.py diff --git a/addons/partner_firstname/hooks.py b/odoo/extra-addons/partner_firstname/hooks.py similarity index 100% rename from addons/partner_firstname/hooks.py rename to odoo/extra-addons/partner_firstname/hooks.py diff --git a/addons/partner_firstname/i18n/am.po b/odoo/extra-addons/partner_firstname/i18n/am.po similarity index 100% rename from addons/partner_firstname/i18n/am.po rename to odoo/extra-addons/partner_firstname/i18n/am.po diff --git a/addons/partner_firstname/i18n/ar.po b/odoo/extra-addons/partner_firstname/i18n/ar.po similarity index 100% rename from addons/partner_firstname/i18n/ar.po rename to odoo/extra-addons/partner_firstname/i18n/ar.po diff --git a/addons/partner_firstname/i18n/bg.po b/odoo/extra-addons/partner_firstname/i18n/bg.po similarity index 100% rename from addons/partner_firstname/i18n/bg.po rename to odoo/extra-addons/partner_firstname/i18n/bg.po diff --git a/addons/partner_firstname/i18n/bs.po b/odoo/extra-addons/partner_firstname/i18n/bs.po similarity index 100% rename from addons/partner_firstname/i18n/bs.po rename to odoo/extra-addons/partner_firstname/i18n/bs.po diff --git a/addons/partner_firstname/i18n/ca.po b/odoo/extra-addons/partner_firstname/i18n/ca.po similarity index 100% rename from addons/partner_firstname/i18n/ca.po rename to odoo/extra-addons/partner_firstname/i18n/ca.po diff --git a/addons/partner_firstname/i18n/cs.po b/odoo/extra-addons/partner_firstname/i18n/cs.po similarity index 100% rename from addons/partner_firstname/i18n/cs.po rename to odoo/extra-addons/partner_firstname/i18n/cs.po diff --git a/addons/partner_firstname/i18n/da.po b/odoo/extra-addons/partner_firstname/i18n/da.po similarity index 100% rename from addons/partner_firstname/i18n/da.po rename to odoo/extra-addons/partner_firstname/i18n/da.po diff --git a/addons/partner_firstname/i18n/de.po b/odoo/extra-addons/partner_firstname/i18n/de.po similarity index 100% rename from addons/partner_firstname/i18n/de.po rename to odoo/extra-addons/partner_firstname/i18n/de.po diff --git a/addons/partner_firstname/i18n/el_GR.po b/odoo/extra-addons/partner_firstname/i18n/el_GR.po similarity index 100% rename from addons/partner_firstname/i18n/el_GR.po rename to odoo/extra-addons/partner_firstname/i18n/el_GR.po diff --git a/addons/partner_firstname/i18n/en_GB.po b/odoo/extra-addons/partner_firstname/i18n/en_GB.po similarity index 100% rename from addons/partner_firstname/i18n/en_GB.po rename to odoo/extra-addons/partner_firstname/i18n/en_GB.po diff --git a/addons/partner_firstname/i18n/es.po b/odoo/extra-addons/partner_firstname/i18n/es.po similarity index 100% rename from addons/partner_firstname/i18n/es.po rename to odoo/extra-addons/partner_firstname/i18n/es.po diff --git a/addons/partner_firstname/i18n/es_CR.po b/odoo/extra-addons/partner_firstname/i18n/es_CR.po similarity index 100% rename from addons/partner_firstname/i18n/es_CR.po rename to odoo/extra-addons/partner_firstname/i18n/es_CR.po diff --git a/addons/partner_firstname/i18n/es_EC.po b/odoo/extra-addons/partner_firstname/i18n/es_EC.po similarity index 100% rename from addons/partner_firstname/i18n/es_EC.po rename to odoo/extra-addons/partner_firstname/i18n/es_EC.po diff --git a/addons/partner_firstname/i18n/es_MX.po b/odoo/extra-addons/partner_firstname/i18n/es_MX.po similarity index 100% rename from addons/partner_firstname/i18n/es_MX.po rename to odoo/extra-addons/partner_firstname/i18n/es_MX.po diff --git a/addons/partner_firstname/i18n/es_VE.po b/odoo/extra-addons/partner_firstname/i18n/es_VE.po similarity index 100% rename from addons/partner_firstname/i18n/es_VE.po rename to odoo/extra-addons/partner_firstname/i18n/es_VE.po diff --git a/addons/partner_firstname/i18n/et.po b/odoo/extra-addons/partner_firstname/i18n/et.po similarity index 100% rename from addons/partner_firstname/i18n/et.po rename to odoo/extra-addons/partner_firstname/i18n/et.po diff --git a/addons/partner_firstname/i18n/eu.po b/odoo/extra-addons/partner_firstname/i18n/eu.po similarity index 100% rename from addons/partner_firstname/i18n/eu.po rename to odoo/extra-addons/partner_firstname/i18n/eu.po diff --git a/addons/partner_firstname/i18n/fi.po b/odoo/extra-addons/partner_firstname/i18n/fi.po similarity index 100% rename from addons/partner_firstname/i18n/fi.po rename to odoo/extra-addons/partner_firstname/i18n/fi.po diff --git a/addons/partner_firstname/i18n/fr.po b/odoo/extra-addons/partner_firstname/i18n/fr.po similarity index 100% rename from addons/partner_firstname/i18n/fr.po rename to odoo/extra-addons/partner_firstname/i18n/fr.po diff --git a/addons/partner_firstname/i18n/fr_CA.po b/odoo/extra-addons/partner_firstname/i18n/fr_CA.po similarity index 100% rename from addons/partner_firstname/i18n/fr_CA.po rename to odoo/extra-addons/partner_firstname/i18n/fr_CA.po diff --git a/addons/partner_firstname/i18n/fr_CH.po b/odoo/extra-addons/partner_firstname/i18n/fr_CH.po similarity index 100% rename from addons/partner_firstname/i18n/fr_CH.po rename to odoo/extra-addons/partner_firstname/i18n/fr_CH.po diff --git a/addons/partner_firstname/i18n/gl.po b/odoo/extra-addons/partner_firstname/i18n/gl.po similarity index 100% rename from addons/partner_firstname/i18n/gl.po rename to odoo/extra-addons/partner_firstname/i18n/gl.po diff --git a/addons/partner_firstname/i18n/hr.po b/odoo/extra-addons/partner_firstname/i18n/hr.po similarity index 100% rename from addons/partner_firstname/i18n/hr.po rename to odoo/extra-addons/partner_firstname/i18n/hr.po diff --git a/addons/partner_firstname/i18n/hr_HR.po b/odoo/extra-addons/partner_firstname/i18n/hr_HR.po similarity index 100% rename from addons/partner_firstname/i18n/hr_HR.po rename to odoo/extra-addons/partner_firstname/i18n/hr_HR.po diff --git a/addons/partner_firstname/i18n/hu.po b/odoo/extra-addons/partner_firstname/i18n/hu.po similarity index 100% rename from addons/partner_firstname/i18n/hu.po rename to odoo/extra-addons/partner_firstname/i18n/hu.po diff --git a/addons/partner_firstname/i18n/it.po b/odoo/extra-addons/partner_firstname/i18n/it.po similarity index 100% rename from addons/partner_firstname/i18n/it.po rename to odoo/extra-addons/partner_firstname/i18n/it.po diff --git a/addons/partner_firstname/i18n/ja.po b/odoo/extra-addons/partner_firstname/i18n/ja.po similarity index 100% rename from addons/partner_firstname/i18n/ja.po rename to odoo/extra-addons/partner_firstname/i18n/ja.po diff --git a/addons/partner_firstname/i18n/lt.po b/odoo/extra-addons/partner_firstname/i18n/lt.po similarity index 100% rename from addons/partner_firstname/i18n/lt.po rename to odoo/extra-addons/partner_firstname/i18n/lt.po diff --git a/addons/partner_firstname/i18n/lv.po b/odoo/extra-addons/partner_firstname/i18n/lv.po similarity index 100% rename from addons/partner_firstname/i18n/lv.po rename to odoo/extra-addons/partner_firstname/i18n/lv.po diff --git a/addons/partner_firstname/i18n/mk.po b/odoo/extra-addons/partner_firstname/i18n/mk.po similarity index 100% rename from addons/partner_firstname/i18n/mk.po rename to odoo/extra-addons/partner_firstname/i18n/mk.po diff --git a/addons/partner_firstname/i18n/mn.po b/odoo/extra-addons/partner_firstname/i18n/mn.po similarity index 100% rename from addons/partner_firstname/i18n/mn.po rename to odoo/extra-addons/partner_firstname/i18n/mn.po diff --git a/addons/partner_firstname/i18n/nb.po b/odoo/extra-addons/partner_firstname/i18n/nb.po similarity index 100% rename from addons/partner_firstname/i18n/nb.po rename to odoo/extra-addons/partner_firstname/i18n/nb.po diff --git a/addons/partner_firstname/i18n/nb_NO.po b/odoo/extra-addons/partner_firstname/i18n/nb_NO.po similarity index 100% rename from addons/partner_firstname/i18n/nb_NO.po rename to odoo/extra-addons/partner_firstname/i18n/nb_NO.po diff --git a/addons/partner_firstname/i18n/nl.po b/odoo/extra-addons/partner_firstname/i18n/nl.po similarity index 100% rename from addons/partner_firstname/i18n/nl.po rename to odoo/extra-addons/partner_firstname/i18n/nl.po diff --git a/addons/partner_firstname/i18n/nl_BE.po b/odoo/extra-addons/partner_firstname/i18n/nl_BE.po similarity index 100% rename from addons/partner_firstname/i18n/nl_BE.po rename to odoo/extra-addons/partner_firstname/i18n/nl_BE.po diff --git a/addons/partner_firstname/i18n/nl_NL.po b/odoo/extra-addons/partner_firstname/i18n/nl_NL.po similarity index 100% rename from addons/partner_firstname/i18n/nl_NL.po rename to odoo/extra-addons/partner_firstname/i18n/nl_NL.po diff --git a/addons/partner_firstname/i18n/partner_firstname.pot b/odoo/extra-addons/partner_firstname/i18n/partner_firstname.pot similarity index 100% rename from addons/partner_firstname/i18n/partner_firstname.pot rename to odoo/extra-addons/partner_firstname/i18n/partner_firstname.pot diff --git a/addons/partner_firstname/i18n/pl.po b/odoo/extra-addons/partner_firstname/i18n/pl.po similarity index 100% rename from addons/partner_firstname/i18n/pl.po rename to odoo/extra-addons/partner_firstname/i18n/pl.po diff --git a/addons/partner_firstname/i18n/pt.po b/odoo/extra-addons/partner_firstname/i18n/pt.po similarity index 100% rename from addons/partner_firstname/i18n/pt.po rename to odoo/extra-addons/partner_firstname/i18n/pt.po diff --git a/addons/partner_firstname/i18n/pt_BR.po b/odoo/extra-addons/partner_firstname/i18n/pt_BR.po similarity index 100% rename from addons/partner_firstname/i18n/pt_BR.po rename to odoo/extra-addons/partner_firstname/i18n/pt_BR.po diff --git a/addons/partner_firstname/i18n/pt_PT.po b/odoo/extra-addons/partner_firstname/i18n/pt_PT.po similarity index 100% rename from addons/partner_firstname/i18n/pt_PT.po rename to odoo/extra-addons/partner_firstname/i18n/pt_PT.po diff --git a/addons/partner_firstname/i18n/ro.po b/odoo/extra-addons/partner_firstname/i18n/ro.po similarity index 100% rename from addons/partner_firstname/i18n/ro.po rename to odoo/extra-addons/partner_firstname/i18n/ro.po diff --git a/addons/partner_firstname/i18n/ru.po b/odoo/extra-addons/partner_firstname/i18n/ru.po similarity index 100% rename from addons/partner_firstname/i18n/ru.po rename to odoo/extra-addons/partner_firstname/i18n/ru.po diff --git a/addons/partner_firstname/i18n/sk.po b/odoo/extra-addons/partner_firstname/i18n/sk.po similarity index 100% rename from addons/partner_firstname/i18n/sk.po rename to odoo/extra-addons/partner_firstname/i18n/sk.po diff --git a/addons/partner_firstname/i18n/sl.po b/odoo/extra-addons/partner_firstname/i18n/sl.po similarity index 100% rename from addons/partner_firstname/i18n/sl.po rename to odoo/extra-addons/partner_firstname/i18n/sl.po diff --git a/addons/partner_firstname/i18n/sr@latin.po b/odoo/extra-addons/partner_firstname/i18n/sr@latin.po similarity index 100% rename from addons/partner_firstname/i18n/sr@latin.po rename to odoo/extra-addons/partner_firstname/i18n/sr@latin.po diff --git a/addons/partner_firstname/i18n/sv.po b/odoo/extra-addons/partner_firstname/i18n/sv.po similarity index 100% rename from addons/partner_firstname/i18n/sv.po rename to odoo/extra-addons/partner_firstname/i18n/sv.po diff --git a/addons/partner_firstname/i18n/th.po b/odoo/extra-addons/partner_firstname/i18n/th.po similarity index 100% rename from addons/partner_firstname/i18n/th.po rename to odoo/extra-addons/partner_firstname/i18n/th.po diff --git a/addons/partner_firstname/i18n/tr.po b/odoo/extra-addons/partner_firstname/i18n/tr.po similarity index 100% rename from addons/partner_firstname/i18n/tr.po rename to odoo/extra-addons/partner_firstname/i18n/tr.po diff --git a/addons/partner_firstname/i18n/tr_TR.po b/odoo/extra-addons/partner_firstname/i18n/tr_TR.po similarity index 100% rename from addons/partner_firstname/i18n/tr_TR.po rename to odoo/extra-addons/partner_firstname/i18n/tr_TR.po diff --git a/addons/partner_firstname/i18n/vi.po b/odoo/extra-addons/partner_firstname/i18n/vi.po similarity index 100% rename from addons/partner_firstname/i18n/vi.po rename to odoo/extra-addons/partner_firstname/i18n/vi.po diff --git a/addons/partner_firstname/i18n/zh_CN.po b/odoo/extra-addons/partner_firstname/i18n/zh_CN.po similarity index 100% rename from addons/partner_firstname/i18n/zh_CN.po rename to odoo/extra-addons/partner_firstname/i18n/zh_CN.po diff --git a/addons/partner_firstname/i18n/zh_TW.po b/odoo/extra-addons/partner_firstname/i18n/zh_TW.po similarity index 100% rename from addons/partner_firstname/i18n/zh_TW.po rename to odoo/extra-addons/partner_firstname/i18n/zh_TW.po diff --git a/addons/partner_firstname/models/__init__.py b/odoo/extra-addons/partner_firstname/models/__init__.py similarity index 100% rename from addons/partner_firstname/models/__init__.py rename to odoo/extra-addons/partner_firstname/models/__init__.py diff --git a/addons/partner_firstname/models/base_config_settings.py b/odoo/extra-addons/partner_firstname/models/base_config_settings.py similarity index 100% rename from addons/partner_firstname/models/base_config_settings.py rename to odoo/extra-addons/partner_firstname/models/base_config_settings.py diff --git a/addons/partner_firstname/models/res_partner.py b/odoo/extra-addons/partner_firstname/models/res_partner.py similarity index 100% rename from addons/partner_firstname/models/res_partner.py rename to odoo/extra-addons/partner_firstname/models/res_partner.py diff --git a/addons/partner_firstname/models/res_users.py b/odoo/extra-addons/partner_firstname/models/res_users.py similarity index 100% rename from addons/partner_firstname/models/res_users.py rename to odoo/extra-addons/partner_firstname/models/res_users.py diff --git a/addons/partner_firstname/readme/CONFIGURE.rst b/odoo/extra-addons/partner_firstname/readme/CONFIGURE.rst similarity index 100% rename from addons/partner_firstname/readme/CONFIGURE.rst rename to odoo/extra-addons/partner_firstname/readme/CONFIGURE.rst diff --git a/addons/partner_firstname/readme/CONTRIBUTORS.rst b/odoo/extra-addons/partner_firstname/readme/CONTRIBUTORS.rst similarity index 100% rename from addons/partner_firstname/readme/CONTRIBUTORS.rst rename to odoo/extra-addons/partner_firstname/readme/CONTRIBUTORS.rst diff --git a/addons/partner_firstname/readme/DESCRIPTION.rst b/odoo/extra-addons/partner_firstname/readme/DESCRIPTION.rst similarity index 100% rename from addons/partner_firstname/readme/DESCRIPTION.rst rename to odoo/extra-addons/partner_firstname/readme/DESCRIPTION.rst diff --git a/addons/partner_firstname/readme/ROADMAP.rst b/odoo/extra-addons/partner_firstname/readme/ROADMAP.rst similarity index 100% rename from addons/partner_firstname/readme/ROADMAP.rst rename to odoo/extra-addons/partner_firstname/readme/ROADMAP.rst diff --git a/addons/partner_firstname/readme/USAGE.rst b/odoo/extra-addons/partner_firstname/readme/USAGE.rst similarity index 100% rename from addons/partner_firstname/readme/USAGE.rst rename to odoo/extra-addons/partner_firstname/readme/USAGE.rst diff --git a/addons/partner_firstname/static/description/icon.png b/odoo/extra-addons/partner_firstname/static/description/icon.png similarity index 100% rename from addons/partner_firstname/static/description/icon.png rename to odoo/extra-addons/partner_firstname/static/description/icon.png diff --git a/addons/partner_firstname/static/description/index.html b/odoo/extra-addons/partner_firstname/static/description/index.html similarity index 100% rename from addons/partner_firstname/static/description/index.html rename to odoo/extra-addons/partner_firstname/static/description/index.html diff --git a/addons/partner_firstname/tests/__init__.py b/odoo/extra-addons/partner_firstname/tests/__init__.py similarity index 100% rename from addons/partner_firstname/tests/__init__.py rename to odoo/extra-addons/partner_firstname/tests/__init__.py diff --git a/addons/partner_firstname/tests/base.py b/odoo/extra-addons/partner_firstname/tests/base.py similarity index 100% rename from addons/partner_firstname/tests/base.py rename to odoo/extra-addons/partner_firstname/tests/base.py diff --git a/addons/partner_firstname/tests/test_config_settings.py b/odoo/extra-addons/partner_firstname/tests/test_config_settings.py similarity index 100% rename from addons/partner_firstname/tests/test_config_settings.py rename to odoo/extra-addons/partner_firstname/tests/test_config_settings.py diff --git a/addons/partner_firstname/tests/test_copy.py b/odoo/extra-addons/partner_firstname/tests/test_copy.py similarity index 100% rename from addons/partner_firstname/tests/test_copy.py rename to odoo/extra-addons/partner_firstname/tests/test_copy.py diff --git a/addons/partner_firstname/tests/test_create.py b/odoo/extra-addons/partner_firstname/tests/test_create.py similarity index 100% rename from addons/partner_firstname/tests/test_create.py rename to odoo/extra-addons/partner_firstname/tests/test_create.py diff --git a/addons/partner_firstname/tests/test_defaults.py b/odoo/extra-addons/partner_firstname/tests/test_defaults.py similarity index 100% rename from addons/partner_firstname/tests/test_defaults.py rename to odoo/extra-addons/partner_firstname/tests/test_defaults.py diff --git a/addons/partner_firstname/tests/test_delete.py b/odoo/extra-addons/partner_firstname/tests/test_delete.py similarity index 100% rename from addons/partner_firstname/tests/test_delete.py rename to odoo/extra-addons/partner_firstname/tests/test_delete.py diff --git a/addons/partner_firstname/tests/test_empty.py b/odoo/extra-addons/partner_firstname/tests/test_empty.py similarity index 100% rename from addons/partner_firstname/tests/test_empty.py rename to odoo/extra-addons/partner_firstname/tests/test_empty.py diff --git a/addons/partner_firstname/tests/test_name.py b/odoo/extra-addons/partner_firstname/tests/test_name.py similarity index 100% rename from addons/partner_firstname/tests/test_name.py rename to odoo/extra-addons/partner_firstname/tests/test_name.py diff --git a/addons/partner_firstname/tests/test_order.py b/odoo/extra-addons/partner_firstname/tests/test_order.py similarity index 100% rename from addons/partner_firstname/tests/test_order.py rename to odoo/extra-addons/partner_firstname/tests/test_order.py diff --git a/addons/partner_firstname/tests/test_partner_form.py b/odoo/extra-addons/partner_firstname/tests/test_partner_form.py similarity index 100% rename from addons/partner_firstname/tests/test_partner_form.py rename to odoo/extra-addons/partner_firstname/tests/test_partner_form.py diff --git a/addons/partner_firstname/tests/test_user_form.py b/odoo/extra-addons/partner_firstname/tests/test_user_form.py similarity index 100% rename from addons/partner_firstname/tests/test_user_form.py rename to odoo/extra-addons/partner_firstname/tests/test_user_form.py diff --git a/addons/partner_firstname/views/base_config_view.xml b/odoo/extra-addons/partner_firstname/views/base_config_view.xml similarity index 100% rename from addons/partner_firstname/views/base_config_view.xml rename to odoo/extra-addons/partner_firstname/views/base_config_view.xml diff --git a/addons/partner_firstname/views/res_partner.xml b/odoo/extra-addons/partner_firstname/views/res_partner.xml similarity index 100% rename from addons/partner_firstname/views/res_partner.xml rename to odoo/extra-addons/partner_firstname/views/res_partner.xml diff --git a/addons/partner_firstname/views/res_user.xml b/odoo/extra-addons/partner_firstname/views/res_user.xml similarity index 100% rename from addons/partner_firstname/views/res_user.xml rename to odoo/extra-addons/partner_firstname/views/res_user.xml diff --git a/addons/readme.md b/odoo/extra-addons/readme.md similarity index 100% rename from addons/readme.md rename to odoo/extra-addons/readme.md diff --git a/addons/web_m2x_options/README.rst b/odoo/extra-addons/web_m2x_options/README.rst similarity index 100% rename from addons/web_m2x_options/README.rst rename to odoo/extra-addons/web_m2x_options/README.rst diff --git a/addons/web_m2x_options/__init__.py b/odoo/extra-addons/web_m2x_options/__init__.py similarity index 100% rename from addons/web_m2x_options/__init__.py rename to odoo/extra-addons/web_m2x_options/__init__.py diff --git a/addons/web_m2x_options/__manifest__.py b/odoo/extra-addons/web_m2x_options/__manifest__.py similarity index 100% rename from addons/web_m2x_options/__manifest__.py rename to odoo/extra-addons/web_m2x_options/__manifest__.py diff --git a/addons/web_m2x_options/i18n/ar.po b/odoo/extra-addons/web_m2x_options/i18n/ar.po similarity index 100% rename from addons/web_m2x_options/i18n/ar.po rename to odoo/extra-addons/web_m2x_options/i18n/ar.po diff --git a/addons/web_m2x_options/i18n/de.po b/odoo/extra-addons/web_m2x_options/i18n/de.po similarity index 100% rename from addons/web_m2x_options/i18n/de.po rename to odoo/extra-addons/web_m2x_options/i18n/de.po diff --git a/addons/web_m2x_options/i18n/es.po b/odoo/extra-addons/web_m2x_options/i18n/es.po similarity index 100% rename from addons/web_m2x_options/i18n/es.po rename to odoo/extra-addons/web_m2x_options/i18n/es.po diff --git a/addons/web_m2x_options/i18n/es_BO.po b/odoo/extra-addons/web_m2x_options/i18n/es_BO.po similarity index 100% rename from addons/web_m2x_options/i18n/es_BO.po rename to odoo/extra-addons/web_m2x_options/i18n/es_BO.po diff --git a/addons/web_m2x_options/i18n/fi.po b/odoo/extra-addons/web_m2x_options/i18n/fi.po similarity index 100% rename from addons/web_m2x_options/i18n/fi.po rename to odoo/extra-addons/web_m2x_options/i18n/fi.po diff --git a/addons/web_m2x_options/i18n/fr.po b/odoo/extra-addons/web_m2x_options/i18n/fr.po similarity index 100% rename from addons/web_m2x_options/i18n/fr.po rename to odoo/extra-addons/web_m2x_options/i18n/fr.po diff --git a/addons/web_m2x_options/i18n/hr.po b/odoo/extra-addons/web_m2x_options/i18n/hr.po similarity index 100% rename from addons/web_m2x_options/i18n/hr.po rename to odoo/extra-addons/web_m2x_options/i18n/hr.po diff --git a/addons/web_m2x_options/i18n/it.po b/odoo/extra-addons/web_m2x_options/i18n/it.po similarity index 100% rename from addons/web_m2x_options/i18n/it.po rename to odoo/extra-addons/web_m2x_options/i18n/it.po diff --git a/addons/web_m2x_options/i18n/nl.po b/odoo/extra-addons/web_m2x_options/i18n/nl.po similarity index 100% rename from addons/web_m2x_options/i18n/nl.po rename to odoo/extra-addons/web_m2x_options/i18n/nl.po diff --git a/addons/web_m2x_options/i18n/nl_NL.po b/odoo/extra-addons/web_m2x_options/i18n/nl_NL.po similarity index 100% rename from addons/web_m2x_options/i18n/nl_NL.po rename to odoo/extra-addons/web_m2x_options/i18n/nl_NL.po diff --git a/addons/web_m2x_options/i18n/pt_BR.po b/odoo/extra-addons/web_m2x_options/i18n/pt_BR.po similarity index 100% rename from addons/web_m2x_options/i18n/pt_BR.po rename to odoo/extra-addons/web_m2x_options/i18n/pt_BR.po diff --git a/addons/web_m2x_options/i18n/sl.po b/odoo/extra-addons/web_m2x_options/i18n/sl.po similarity index 100% rename from addons/web_m2x_options/i18n/sl.po rename to odoo/extra-addons/web_m2x_options/i18n/sl.po diff --git a/addons/web_m2x_options/i18n/tr.po b/odoo/extra-addons/web_m2x_options/i18n/tr.po similarity index 100% rename from addons/web_m2x_options/i18n/tr.po rename to odoo/extra-addons/web_m2x_options/i18n/tr.po diff --git a/addons/web_m2x_options/i18n/web_m2x_options.pot b/odoo/extra-addons/web_m2x_options/i18n/web_m2x_options.pot similarity index 100% rename from addons/web_m2x_options/i18n/web_m2x_options.pot rename to odoo/extra-addons/web_m2x_options/i18n/web_m2x_options.pot diff --git a/addons/web_m2x_options/i18n/zh_CN.po b/odoo/extra-addons/web_m2x_options/i18n/zh_CN.po similarity index 100% rename from addons/web_m2x_options/i18n/zh_CN.po rename to odoo/extra-addons/web_m2x_options/i18n/zh_CN.po diff --git a/addons/web_m2x_options/models/__init__.py b/odoo/extra-addons/web_m2x_options/models/__init__.py similarity index 100% rename from addons/web_m2x_options/models/__init__.py rename to odoo/extra-addons/web_m2x_options/models/__init__.py diff --git a/addons/web_m2x_options/models/ir_config_parameter.py b/odoo/extra-addons/web_m2x_options/models/ir_config_parameter.py similarity index 100% rename from addons/web_m2x_options/models/ir_config_parameter.py rename to odoo/extra-addons/web_m2x_options/models/ir_config_parameter.py diff --git a/addons/web_m2x_options/models/ir_http.py b/odoo/extra-addons/web_m2x_options/models/ir_http.py similarity index 100% rename from addons/web_m2x_options/models/ir_http.py rename to odoo/extra-addons/web_m2x_options/models/ir_http.py diff --git a/addons/web_m2x_options/readme/CONTRIBUTORS.rst b/odoo/extra-addons/web_m2x_options/readme/CONTRIBUTORS.rst similarity index 100% rename from addons/web_m2x_options/readme/CONTRIBUTORS.rst rename to odoo/extra-addons/web_m2x_options/readme/CONTRIBUTORS.rst diff --git a/addons/web_m2x_options/readme/CREDITS.rst b/odoo/extra-addons/web_m2x_options/readme/CREDITS.rst similarity index 100% rename from addons/web_m2x_options/readme/CREDITS.rst rename to odoo/extra-addons/web_m2x_options/readme/CREDITS.rst diff --git a/addons/web_m2x_options/readme/DESCRIPTION.rst b/odoo/extra-addons/web_m2x_options/readme/DESCRIPTION.rst similarity index 100% rename from addons/web_m2x_options/readme/DESCRIPTION.rst rename to odoo/extra-addons/web_m2x_options/readme/DESCRIPTION.rst diff --git a/addons/web_m2x_options/readme/ROADMAP.rst b/odoo/extra-addons/web_m2x_options/readme/ROADMAP.rst similarity index 100% rename from addons/web_m2x_options/readme/ROADMAP.rst rename to odoo/extra-addons/web_m2x_options/readme/ROADMAP.rst diff --git a/addons/web_m2x_options/readme/USAGE.rst b/odoo/extra-addons/web_m2x_options/readme/USAGE.rst similarity index 100% rename from addons/web_m2x_options/readme/USAGE.rst rename to odoo/extra-addons/web_m2x_options/readme/USAGE.rst diff --git a/addons/web_m2x_options/static/description/icon.png b/odoo/extra-addons/web_m2x_options/static/description/icon.png similarity index 100% rename from addons/web_m2x_options/static/description/icon.png rename to odoo/extra-addons/web_m2x_options/static/description/icon.png diff --git a/addons/web_m2x_options/static/description/index.html b/odoo/extra-addons/web_m2x_options/static/description/index.html similarity index 100% rename from addons/web_m2x_options/static/description/index.html rename to odoo/extra-addons/web_m2x_options/static/description/index.html diff --git a/addons/web_m2x_options/static/src/components/base.xml b/odoo/extra-addons/web_m2x_options/static/src/components/base.xml similarity index 100% rename from addons/web_m2x_options/static/src/components/base.xml rename to odoo/extra-addons/web_m2x_options/static/src/components/base.xml diff --git a/addons/web_m2x_options/static/src/components/form.esm.js b/odoo/extra-addons/web_m2x_options/static/src/components/form.esm.js similarity index 100% rename from addons/web_m2x_options/static/src/components/form.esm.js rename to odoo/extra-addons/web_m2x_options/static/src/components/form.esm.js diff --git a/addons/web_m2x_options/static/src/components/relational_utils.esm.js b/odoo/extra-addons/web_m2x_options/static/src/components/relational_utils.esm.js similarity index 100% rename from addons/web_m2x_options/static/src/components/relational_utils.esm.js rename to odoo/extra-addons/web_m2x_options/static/src/components/relational_utils.esm.js diff --git a/addons/web_m2x_options/tests/__init__.py b/odoo/extra-addons/web_m2x_options/tests/__init__.py similarity index 100% rename from addons/web_m2x_options/tests/__init__.py rename to odoo/extra-addons/web_m2x_options/tests/__init__.py diff --git a/addons/web_m2x_options/tests/test_ir_config_parameter.py b/odoo/extra-addons/web_m2x_options/tests/test_ir_config_parameter.py similarity index 100% rename from addons/web_m2x_options/tests/test_ir_config_parameter.py rename to odoo/extra-addons/web_m2x_options/tests/test_ir_config_parameter.py From a913e81696b0e3033e258ea819d4d14d408c1475 Mon Sep 17 00:00:00 2001 From: belloafeez Date: Fri, 2 Aug 2024 10:14:21 +0100 Subject: [PATCH 23/54] updated Signed-off-by: belloafeez --- addons/openems/.gitignore | 3 + addons/openems/__init__.py | 1 + addons/openems/__manifest__.py | 40 + addons/openems/controllers/__init__.py | 1 + addons/openems/controllers/alerting.py | 86 + addons/openems/controllers/const.py | 5 + addons/openems/controllers/openems_backend.py | 276 +++ addons/openems/controllers/setup_protocol.py | 142 ++ addons/openems/controllers/user.py | 32 + addons/openems/data/OpenEMS-Logo.jpg | Bin 0 -> 152320 bytes addons/openems/data/demo.xml | 12 + addons/openems/data/ir_config_parameter.xml | 9 + addons/openems/data/res_partner_category.xml | 11 + addons/openems/i18n/de.po | 1666 +++++++++++++++++ addons/openems/i18n/openems.pot | 1666 +++++++++++++++++ .../openems/mail/openems/alerting_offline.xml | 275 +++ .../mail/openems/alerting_sum_state.xml | 268 +++ .../mail/openems/setup_protocol_customer.xml | 170 ++ .../mail/openems/setup_protocol_installer.xml | 173 ++ .../mail/openems/user_registration.xml | 197 ++ .../migrations/16.0.1.0.1/post-migrate.py | 9 + .../migrations/16.0.1.0.1/pre-migrate.py | 7 + addons/openems/models/__init__.py | 1 + addons/openems/models/device.py | 321 ++++ addons/openems/models/partner.py | 12 + addons/openems/models/setup_protocol.py | 49 + addons/openems/models/stock_production_lot.py | 23 + addons/openems/models/user.py | 37 + addons/openems/report/setup_protocol.xml | 311 +++ addons/openems/security/ir.model.access.csv | 31 + addons/openems/security/openems.xml | 54 + .../.setuptools-odoo-make-default-ignore | 2 + addons/openems/setup/README | 2 + addons/openems/static/description/icon.png | Bin 0 -> 53271 bytes addons/openems/static/mail/OpenEMS-Logo.jpg | Bin 0 -> 152320 bytes addons/openems/views/device.xml | 320 ++++ addons/openems/views/partner.xml | 28 + addons/openems/views/setup_protocol.xml | 82 + .../views/stock_production_lot_views.xml | 13 + addons/openems/views/user.xml | 25 + addons/partner_firstname/README.rst | 146 ++ addons/partner_firstname/__init__.py | 2 + addons/partner_firstname/__manifest__.py | 30 + addons/partner_firstname/exceptions.py | 12 + addons/partner_firstname/hooks.py | 9 + addons/partner_firstname/i18n/am.po | 130 ++ addons/partner_firstname/i18n/ar.po | 131 ++ addons/partner_firstname/i18n/bg.po | 130 ++ addons/partner_firstname/i18n/bs.po | 131 ++ addons/partner_firstname/i18n/ca.po | 139 ++ addons/partner_firstname/i18n/cs.po | 130 ++ addons/partner_firstname/i18n/da.po | 135 ++ addons/partner_firstname/i18n/de.po | 136 ++ addons/partner_firstname/i18n/el_GR.po | 131 ++ addons/partner_firstname/i18n/en_GB.po | 131 ++ addons/partner_firstname/i18n/es.po | 136 ++ addons/partner_firstname/i18n/es_CR.po | 131 ++ addons/partner_firstname/i18n/es_EC.po | 131 ++ addons/partner_firstname/i18n/es_MX.po | 131 ++ addons/partner_firstname/i18n/es_VE.po | 131 ++ addons/partner_firstname/i18n/et.po | 130 ++ addons/partner_firstname/i18n/eu.po | 130 ++ addons/partner_firstname/i18n/fi.po | 130 ++ addons/partner_firstname/i18n/fr.po | 138 ++ addons/partner_firstname/i18n/fr_CA.po | 131 ++ addons/partner_firstname/i18n/fr_CH.po | 131 ++ addons/partner_firstname/i18n/gl.po | 130 ++ addons/partner_firstname/i18n/hr.po | 132 ++ addons/partner_firstname/i18n/hr_HR.po | 132 ++ addons/partner_firstname/i18n/hu.po | 138 ++ addons/partner_firstname/i18n/it.po | 136 ++ addons/partner_firstname/i18n/ja.po | 130 ++ addons/partner_firstname/i18n/lt.po | 131 ++ addons/partner_firstname/i18n/lv.po | 131 ++ addons/partner_firstname/i18n/mk.po | 130 ++ addons/partner_firstname/i18n/mn.po | 130 ++ addons/partner_firstname/i18n/nb.po | 131 ++ addons/partner_firstname/i18n/nb_NO.po | 131 ++ addons/partner_firstname/i18n/nl.po | 130 ++ addons/partner_firstname/i18n/nl_BE.po | 131 ++ addons/partner_firstname/i18n/nl_NL.po | 138 ++ .../i18n/partner_firstname.pot | 124 ++ addons/partner_firstname/i18n/pl.po | 132 ++ addons/partner_firstname/i18n/pt.po | 130 ++ addons/partner_firstname/i18n/pt_BR.po | 138 ++ addons/partner_firstname/i18n/pt_PT.po | 131 ++ addons/partner_firstname/i18n/ro.po | 131 ++ addons/partner_firstname/i18n/ru.po | 132 ++ addons/partner_firstname/i18n/sk.po | 130 ++ addons/partner_firstname/i18n/sl.po | 131 ++ addons/partner_firstname/i18n/sr@latin.po | 132 ++ addons/partner_firstname/i18n/sv.po | 130 ++ addons/partner_firstname/i18n/th.po | 130 ++ addons/partner_firstname/i18n/tr.po | 130 ++ addons/partner_firstname/i18n/tr_TR.po | 131 ++ addons/partner_firstname/i18n/vi.po | 130 ++ addons/partner_firstname/i18n/zh_CN.po | 131 ++ addons/partner_firstname/i18n/zh_TW.po | 131 ++ addons/partner_firstname/models/__init__.py | 3 + .../models/base_config_settings.py | 71 + .../partner_firstname/models/res_partner.py | 270 +++ addons/partner_firstname/models/res_users.py | 49 + addons/partner_firstname/readme/CONFIGURE.rst | 14 + .../partner_firstname/readme/CONTRIBUTORS.rst | 23 + .../partner_firstname/readme/DESCRIPTION.rst | 2 + addons/partner_firstname/readme/ROADMAP.rst | 3 + addons/partner_firstname/readme/USAGE.rst | 13 + .../static/description/icon.png | Bin 0 -> 9455 bytes .../static/description/index.html | 488 +++++ addons/partner_firstname/tests/__init__.py | 12 + addons/partner_firstname/tests/base.py | 65 + .../tests/test_config_settings.py | 35 + addons/partner_firstname/tests/test_copy.py | 95 + addons/partner_firstname/tests/test_create.py | 79 + .../partner_firstname/tests/test_defaults.py | 64 + addons/partner_firstname/tests/test_delete.py | 38 + addons/partner_firstname/tests/test_empty.py | 73 + addons/partner_firstname/tests/test_name.py | 119 ++ addons/partner_firstname/tests/test_order.py | 38 + .../tests/test_partner_form.py | 106 ++ .../partner_firstname/tests/test_user_form.py | 51 + .../views/base_config_view.xml | 28 + .../partner_firstname/views/res_partner.xml | 105 ++ addons/partner_firstname/views/res_user.xml | 25 + addons/readme.md | 1 + addons/web_m2x_options/README.rst | 217 +++ addons/web_m2x_options/__init__.py | 1 + addons/web_m2x_options/__manifest__.py | 21 + addons/web_m2x_options/i18n/ar.po | 133 ++ addons/web_m2x_options/i18n/de.po | 159 ++ addons/web_m2x_options/i18n/es.po | 145 ++ addons/web_m2x_options/i18n/es_BO.po | 116 ++ addons/web_m2x_options/i18n/fi.po | 132 ++ addons/web_m2x_options/i18n/fr.po | 158 ++ addons/web_m2x_options/i18n/hr.po | 150 ++ addons/web_m2x_options/i18n/it.po | 133 ++ addons/web_m2x_options/i18n/nl.po | 162 ++ addons/web_m2x_options/i18n/nl_NL.po | 125 ++ addons/web_m2x_options/i18n/pt_BR.po | 156 ++ addons/web_m2x_options/i18n/sl.po | 133 ++ addons/web_m2x_options/i18n/tr.po | 132 ++ .../web_m2x_options/i18n/web_m2x_options.pot | 115 ++ addons/web_m2x_options/i18n/zh_CN.po | 153 ++ addons/web_m2x_options/models/__init__.py | 2 + .../models/ir_config_parameter.py | 18 + addons/web_m2x_options/models/ir_http.py | 11 + .../web_m2x_options/readme/CONTRIBUTORS.rst | 16 + addons/web_m2x_options/readme/CREDITS.rst | 1 + addons/web_m2x_options/readme/DESCRIPTION.rst | 10 + addons/web_m2x_options/readme/ROADMAP.rst | 6 + addons/web_m2x_options/readme/USAGE.rst | 95 + .../static/description/icon.png | Bin 0 -> 9455 bytes .../static/description/index.html | 412 ++++ .../static/src/components/base.xml | 46 + .../static/src/components/form.esm.js | 404 ++++ .../src/components/relational_utils.esm.js | 221 +++ addons/web_m2x_options/tests/__init__.py | 2 + .../tests/test_ir_config_parameter.py | 28 + 158 files changed, 19021 insertions(+) create mode 100644 addons/openems/.gitignore create mode 100644 addons/openems/__init__.py create mode 100644 addons/openems/__manifest__.py create mode 100644 addons/openems/controllers/__init__.py create mode 100644 addons/openems/controllers/alerting.py create mode 100644 addons/openems/controllers/const.py create mode 100644 addons/openems/controllers/openems_backend.py create mode 100644 addons/openems/controllers/setup_protocol.py create mode 100644 addons/openems/controllers/user.py create mode 100644 addons/openems/data/OpenEMS-Logo.jpg create mode 100644 addons/openems/data/demo.xml create mode 100644 addons/openems/data/ir_config_parameter.xml create mode 100644 addons/openems/data/res_partner_category.xml create mode 100644 addons/openems/i18n/de.po create mode 100644 addons/openems/i18n/openems.pot create mode 100644 addons/openems/mail/openems/alerting_offline.xml create mode 100644 addons/openems/mail/openems/alerting_sum_state.xml create mode 100644 addons/openems/mail/openems/setup_protocol_customer.xml create mode 100644 addons/openems/mail/openems/setup_protocol_installer.xml create mode 100644 addons/openems/mail/openems/user_registration.xml create mode 100644 addons/openems/migrations/16.0.1.0.1/post-migrate.py create mode 100644 addons/openems/migrations/16.0.1.0.1/pre-migrate.py create mode 100644 addons/openems/models/__init__.py create mode 100644 addons/openems/models/device.py create mode 100644 addons/openems/models/partner.py create mode 100644 addons/openems/models/setup_protocol.py create mode 100644 addons/openems/models/stock_production_lot.py create mode 100644 addons/openems/models/user.py create mode 100644 addons/openems/report/setup_protocol.xml create mode 100644 addons/openems/security/ir.model.access.csv create mode 100644 addons/openems/security/openems.xml create mode 100644 addons/openems/setup/.setuptools-odoo-make-default-ignore create mode 100644 addons/openems/setup/README create mode 100644 addons/openems/static/description/icon.png create mode 100644 addons/openems/static/mail/OpenEMS-Logo.jpg create mode 100644 addons/openems/views/device.xml create mode 100644 addons/openems/views/partner.xml create mode 100644 addons/openems/views/setup_protocol.xml create mode 100644 addons/openems/views/stock_production_lot_views.xml create mode 100644 addons/openems/views/user.xml create mode 100644 addons/partner_firstname/README.rst create mode 100644 addons/partner_firstname/__init__.py create mode 100644 addons/partner_firstname/__manifest__.py create mode 100644 addons/partner_firstname/exceptions.py create mode 100644 addons/partner_firstname/hooks.py create mode 100644 addons/partner_firstname/i18n/am.po create mode 100644 addons/partner_firstname/i18n/ar.po create mode 100644 addons/partner_firstname/i18n/bg.po create mode 100644 addons/partner_firstname/i18n/bs.po create mode 100644 addons/partner_firstname/i18n/ca.po create mode 100644 addons/partner_firstname/i18n/cs.po create mode 100644 addons/partner_firstname/i18n/da.po create mode 100644 addons/partner_firstname/i18n/de.po create mode 100644 addons/partner_firstname/i18n/el_GR.po create mode 100644 addons/partner_firstname/i18n/en_GB.po create mode 100644 addons/partner_firstname/i18n/es.po create mode 100644 addons/partner_firstname/i18n/es_CR.po create mode 100644 addons/partner_firstname/i18n/es_EC.po create mode 100644 addons/partner_firstname/i18n/es_MX.po create mode 100644 addons/partner_firstname/i18n/es_VE.po create mode 100644 addons/partner_firstname/i18n/et.po create mode 100644 addons/partner_firstname/i18n/eu.po create mode 100644 addons/partner_firstname/i18n/fi.po create mode 100644 addons/partner_firstname/i18n/fr.po create mode 100644 addons/partner_firstname/i18n/fr_CA.po create mode 100644 addons/partner_firstname/i18n/fr_CH.po create mode 100644 addons/partner_firstname/i18n/gl.po create mode 100644 addons/partner_firstname/i18n/hr.po create mode 100644 addons/partner_firstname/i18n/hr_HR.po create mode 100644 addons/partner_firstname/i18n/hu.po create mode 100644 addons/partner_firstname/i18n/it.po create mode 100644 addons/partner_firstname/i18n/ja.po create mode 100644 addons/partner_firstname/i18n/lt.po create mode 100644 addons/partner_firstname/i18n/lv.po create mode 100644 addons/partner_firstname/i18n/mk.po create mode 100644 addons/partner_firstname/i18n/mn.po create mode 100644 addons/partner_firstname/i18n/nb.po create mode 100644 addons/partner_firstname/i18n/nb_NO.po create mode 100644 addons/partner_firstname/i18n/nl.po create mode 100644 addons/partner_firstname/i18n/nl_BE.po create mode 100644 addons/partner_firstname/i18n/nl_NL.po create mode 100644 addons/partner_firstname/i18n/partner_firstname.pot create mode 100644 addons/partner_firstname/i18n/pl.po create mode 100644 addons/partner_firstname/i18n/pt.po create mode 100644 addons/partner_firstname/i18n/pt_BR.po create mode 100644 addons/partner_firstname/i18n/pt_PT.po create mode 100644 addons/partner_firstname/i18n/ro.po create mode 100644 addons/partner_firstname/i18n/ru.po create mode 100644 addons/partner_firstname/i18n/sk.po create mode 100644 addons/partner_firstname/i18n/sl.po create mode 100644 addons/partner_firstname/i18n/sr@latin.po create mode 100644 addons/partner_firstname/i18n/sv.po create mode 100644 addons/partner_firstname/i18n/th.po create mode 100644 addons/partner_firstname/i18n/tr.po create mode 100644 addons/partner_firstname/i18n/tr_TR.po create mode 100644 addons/partner_firstname/i18n/vi.po create mode 100644 addons/partner_firstname/i18n/zh_CN.po create mode 100644 addons/partner_firstname/i18n/zh_TW.po create mode 100644 addons/partner_firstname/models/__init__.py create mode 100644 addons/partner_firstname/models/base_config_settings.py create mode 100644 addons/partner_firstname/models/res_partner.py create mode 100644 addons/partner_firstname/models/res_users.py create mode 100644 addons/partner_firstname/readme/CONFIGURE.rst create mode 100644 addons/partner_firstname/readme/CONTRIBUTORS.rst create mode 100644 addons/partner_firstname/readme/DESCRIPTION.rst create mode 100644 addons/partner_firstname/readme/ROADMAP.rst create mode 100644 addons/partner_firstname/readme/USAGE.rst create mode 100644 addons/partner_firstname/static/description/icon.png create mode 100644 addons/partner_firstname/static/description/index.html create mode 100644 addons/partner_firstname/tests/__init__.py create mode 100644 addons/partner_firstname/tests/base.py create mode 100644 addons/partner_firstname/tests/test_config_settings.py create mode 100644 addons/partner_firstname/tests/test_copy.py create mode 100644 addons/partner_firstname/tests/test_create.py create mode 100644 addons/partner_firstname/tests/test_defaults.py create mode 100644 addons/partner_firstname/tests/test_delete.py create mode 100644 addons/partner_firstname/tests/test_empty.py create mode 100644 addons/partner_firstname/tests/test_name.py create mode 100644 addons/partner_firstname/tests/test_order.py create mode 100644 addons/partner_firstname/tests/test_partner_form.py create mode 100644 addons/partner_firstname/tests/test_user_form.py create mode 100644 addons/partner_firstname/views/base_config_view.xml create mode 100644 addons/partner_firstname/views/res_partner.xml create mode 100644 addons/partner_firstname/views/res_user.xml create mode 100644 addons/readme.md create mode 100644 addons/web_m2x_options/README.rst create mode 100644 addons/web_m2x_options/__init__.py create mode 100644 addons/web_m2x_options/__manifest__.py create mode 100644 addons/web_m2x_options/i18n/ar.po create mode 100644 addons/web_m2x_options/i18n/de.po create mode 100644 addons/web_m2x_options/i18n/es.po create mode 100644 addons/web_m2x_options/i18n/es_BO.po create mode 100644 addons/web_m2x_options/i18n/fi.po create mode 100644 addons/web_m2x_options/i18n/fr.po create mode 100644 addons/web_m2x_options/i18n/hr.po create mode 100644 addons/web_m2x_options/i18n/it.po create mode 100644 addons/web_m2x_options/i18n/nl.po create mode 100644 addons/web_m2x_options/i18n/nl_NL.po create mode 100644 addons/web_m2x_options/i18n/pt_BR.po create mode 100644 addons/web_m2x_options/i18n/sl.po create mode 100644 addons/web_m2x_options/i18n/tr.po create mode 100644 addons/web_m2x_options/i18n/web_m2x_options.pot create mode 100644 addons/web_m2x_options/i18n/zh_CN.po create mode 100644 addons/web_m2x_options/models/__init__.py create mode 100644 addons/web_m2x_options/models/ir_config_parameter.py create mode 100644 addons/web_m2x_options/models/ir_http.py create mode 100644 addons/web_m2x_options/readme/CONTRIBUTORS.rst create mode 100644 addons/web_m2x_options/readme/CREDITS.rst create mode 100644 addons/web_m2x_options/readme/DESCRIPTION.rst create mode 100644 addons/web_m2x_options/readme/ROADMAP.rst create mode 100644 addons/web_m2x_options/readme/USAGE.rst create mode 100644 addons/web_m2x_options/static/description/icon.png create mode 100644 addons/web_m2x_options/static/description/index.html create mode 100644 addons/web_m2x_options/static/src/components/base.xml create mode 100644 addons/web_m2x_options/static/src/components/form.esm.js create mode 100644 addons/web_m2x_options/static/src/components/relational_utils.esm.js create mode 100644 addons/web_m2x_options/tests/__init__.py create mode 100644 addons/web_m2x_options/tests/test_ir_config_parameter.py diff --git a/addons/openems/.gitignore b/addons/openems/.gitignore new file mode 100644 index 0000000..e41d5e2 --- /dev/null +++ b/addons/openems/.gitignore @@ -0,0 +1,3 @@ +.swp +.swo +**/__pycache__ diff --git a/addons/openems/__init__.py b/addons/openems/__init__.py new file mode 100644 index 0000000..72d3ea6 --- /dev/null +++ b/addons/openems/__init__.py @@ -0,0 +1 @@ +from . import controllers, models diff --git a/addons/openems/__manifest__.py b/addons/openems/__manifest__.py new file mode 100644 index 0000000..232ebf1 --- /dev/null +++ b/addons/openems/__manifest__.py @@ -0,0 +1,40 @@ +{ + "name": "OpenEMS", + "summary": "Everything related to OpenEMS (Open Energy Management System)", + "version": "16.0.1.0.1", + "author": "OpenEMS Association e.V.", + "maintainer": "OpenEMS Association e.V.", + "contributors": [ + "Stefan Feilmeier " + "Maximilian Lang " + ], + "website": "https://openems.io", + "license": "AGPL-3", + "category": "Specific Industry Applications", + "depends": ["base", "web", "mail", "crm", "resource", "stock", "web_m2x_options", "partner_firstname"], + "data": [ + "data/ir_config_parameter.xml", + "data/res_partner_category.xml", + "security/openems.xml", + "security/ir.model.access.csv", + "report/setup_protocol.xml", + "views/device.xml", + "views/partner.xml", + "views/setup_protocol.xml", + "views/user.xml", + "views/stock_production_lot_views.xml", + "mail/openems/alerting_offline.xml", + "mail/openems/alerting_sum_state.xml", + "mail/openems/setup_protocol_customer.xml", + "mail/openems/setup_protocol_installer.xml", + "mail/openems/user_registration.xml", + ], + "demo": ["data/demo.xml"], + "js": [], + "css": [], + "qweb": [], + "images": [], + "test": [], + "installable": True, + "application": True, +} diff --git a/addons/openems/controllers/__init__.py b/addons/openems/controllers/__init__.py new file mode 100644 index 0000000..3e863cd --- /dev/null +++ b/addons/openems/controllers/__init__.py @@ -0,0 +1 @@ +from . import openems_backend, setup_protocol, user, alerting diff --git a/addons/openems/controllers/alerting.py b/addons/openems/controllers/alerting.py new file mode 100644 index 0000000..7a848f2 --- /dev/null +++ b/addons/openems/controllers/alerting.py @@ -0,0 +1,86 @@ +import logging +from datetime import datetime +from enum import Enum + +from odoo import http +from odoo.http import request + +class SumState(Enum): + FAULT = 0 + WARNING = 1 + +class Message: + sentAt: datetime + edgeId: str + userIds: list[int] + + def __init__(self, sentAt: datetime, edgeId: str, userIds: list[int]) -> None: + self.sentAt = sentAt + self.edgeId = edgeId + self.userIds = userIds + +class SumStateMessage(Message): + state: SumState + + def __init__(self, sentAt: datetime, edgeId: str, userIds: list[int], state: SumState) -> None: + super().__init__(sentAt, edgeId, userIds) + self.state = state + +class Alerting(http.Controller): + __logger = logging.getLogger("Alerting") + + @http.route("/openems_backend/mail/alerting_sum_state", type="json", auth="user") + def sum_state_alerting(self, sentAt: str, params: list[dict]): + msgs = self.__get_sum_state_params(sentAt, params) + update_func = lambda role, at: { role.write({"sum_state_last_notification": at})} + + if len(msgs) == 0: + self.__logger.error("Scheduled SumState-Alerting-Mail without any recipients!!!") + + template = request.env.ref('openems.alerting_sum_state') + for msg in msgs: + self.__send_mails(template, msg, update_func) + + return {} + + @http.route("/openems_backend/mail/alerting_offline", type="json", auth="user") + def offline_alerting(self, sentAt: str, params: list[dict]): + msgs = self.__get_offline_params(sentAt, params) + update_func = lambda role, at: { role.write({"offline_last_notification": at})} + + template = request.env.ref("openems.alerting_offline") + for msg in msgs: + self.__send_mails(template, msg, update_func) + + return {} + + def __get_offline_params(self, sentAt, params) -> list[Message]: + msgs = list() + sent = datetime.strptime(sentAt, "%Y-%m-%d %H:%M:%S") + for param in params: + edgeId = param["edgeId"] + recipients = param["recipients"] + msgs.append(Message(sent, edgeId, recipients)); + return msgs + + def __get_sum_state_params(self, sentAt, params) -> list[SumStateMessage]: + msgs = list() + sent = datetime.strptime(sentAt, "%Y-%m-%d %H:%M:%S") + for param in params: + edgeId = param["edgeId"] + recipients = param["recipients"] + state = param["state"] + msgs.append(SumStateMessage(sent, edgeId, recipients, state)); + return msgs + + def __send_mails(self, template, msg: Message, update_func): + roles = http.request.env['openems.alerting'].search( + [('user_id','in',msg.userIds),('device_id','=',msg.edgeId)] + ) + + for role in roles: + try: + template.send_mail(res_id=role.id, force_send=True) + update_func(role, msg.sentAt) + except Exception as err: + self.__logger.error("[" + str(err) + "] Unable to send template[" + str(template.name) +"] to edgeUser[user=" + str(role.id) + ", edge=" + str(msg.edgeId)+ "]") \ No newline at end of file diff --git a/addons/openems/controllers/const.py b/addons/openems/controllers/const.py new file mode 100644 index 0000000..c6fbc01 --- /dev/null +++ b/addons/openems/controllers/const.py @@ -0,0 +1,5 @@ +from odoo.modules.module import get_module_resource + +import base64 + +OPENEMS_LOGO_BASE64 = base64.b64encode(open(get_module_resource('openems', 'data', 'OpenEMS-Logo.jpg') , "rb").read()) \ No newline at end of file diff --git a/addons/openems/controllers/openems_backend.py b/addons/openems/controllers/openems_backend.py new file mode 100644 index 0000000..d0dcb80 --- /dev/null +++ b/addons/openems/controllers/openems_backend.py @@ -0,0 +1,276 @@ +from odoo import http + + +class OpenemsBackend(http.Controller): + @http.route("/openems_backend/info", auth="user", type="json") + def index(self): + # Get user + user_id = http.request.env.context.get("uid") + res_users = http.request.env["res.users"].sudo() + user_rec = res_users.search_read( + [("id", "=", user_id)], + ["login", "name", "groups_id", "global_role", "openems_language"], + )[0] + res_users.browse([user_id]) + + # Get res group model + res_groups_model = http.request.env["res.groups"].sudo() + + # Get Manager and Reader group + manager_group = res_groups_model.env.ref("openems.group_openems_manager") + reader_group = res_groups_model.env.ref("openems.group_openems_reader") + + manager_group_id = manager_group["id"] + reader_group_id = reader_group["id"] + + # Get user attributes + global_role = user_rec["global_role"] + if manager_group_id in user_rec["groups_id"]: + # Manager group + global_role = "admin" + + # return empty device (use pagination) list if user is manager or reader + if manager_group_id in user_rec["groups_id"] or reader_group_id in user_rec["groups_id"]: + return { + "user": { + "id": user_rec["id"], + "login": user_rec["login"], + "name": user_rec["name"], + "global_role": global_role, + "language": user_rec["openems_language"], + "has_multiple_edges": True + }, + "devices": [], + } + + # Get specific Device roles + device_user_role_model = http.request.env["openems.device_user_role"] + user_role_ids = device_user_role_model.search_read( + [("user_id", "=", user_id)], ["id", "role"] + ) + + # Get Devices + device_model = http.request.env["openems.device"] + devices = device_model.search_read( + [], ["id", "name", "user_role_ids", "comment", "producttype", + "lastmessage", "first_setup_protocol_date", "openems_sum_state_level"] + ) + + devs = [] + for device_rec in devices: + # Set user role per group + role = "guest" + if manager_group_id in user_rec["groups_id"]: + # Manager group + role = "admin" + elif reader_group_id in user_rec["groups_id"]: + # Reader group + role = "guest" + + # Set specific user role + for device_role_id in device_rec["user_role_ids"]: + for user_role_id in user_role_ids: + if device_role_id == user_role_id["id"]: + role = user_role_id["role"] + + # Prepare result + dev = { + "id": device_rec["id"], + "name": device_rec["name"], + "comment": device_rec["comment"], + "producttype": device_rec["producttype"], + "role": role, + "lastmessage": device_rec["lastmessage"], + "openems_sum_state_level": device_rec["openems_sum_state_level"] + } + + if device_rec["first_setup_protocol_date"]: + dev["first_setup_protocol_date"] = device_rec[ + "first_setup_protocol_date" + ] + + devs.append(dev) + + return { + "user": { + "id": user_rec["id"], + "login": user_rec["login"], + "name": user_rec["name"], + "global_role": global_role, + "language": user_rec["openems_language"], + "has_multiple_edges": len(devs) > 1 + }, + "devices": devs, + } + + @http.route("/openems_backend/get_edge_with_role", auth="user", type="json") + def get_edge_with_role(self, edge_id: str): + user_id = http.request.env.context.get("uid") + res_users = http.request.env["res.users"].sudo() + user_rec = res_users.search_read( + [("id", "=", user_id)], + ["login", "name", "groups_id"], + )[0] + + # Get res group model + res_groups_model = http.request.env["res.groups"].sudo() + + # Get Manager and Reader group + manager_group = res_groups_model.env.ref("openems.group_openems_manager") + reader_group = res_groups_model.env.ref("openems.group_openems_reader") + + manager_group_id = manager_group["id"] + reader_group_id = reader_group["id"] + + # get devices for which the user has permissions + device_model = http.request.env["openems.device"] + devices = device_model.search_read( + [("name", "=", edge_id)], + ["id", "name", "comment", "producttype", "lastmessage", "first_setup_protocol_date", "openems_sum_state_level"]) + + if len(devices) != 1: + return {} + + device = devices[0] + + # Get specific Device roles + device_user_role_model = http.request.env["openems.device_user_role"] + device_user_roles = device_user_role_model.search_read( + [("user_id", "=", user_id), + ("device_id", "=", device["id"])], ["id", "role"] + ) + + # Set user role per group + role = "guest" + if manager_group_id in user_rec["groups_id"]: + # Manager group + role = "admin" + elif reader_group_id in user_rec["groups_id"]: + # Reader group + role = "guest" + + # Set specific user role + if len(device_user_roles) > 0: + role = device_user_roles[0]["role"] + + dev = { + "id": device["id"], + "name": device["name"], + "comment": device["comment"], + "producttype": device["producttype"], + "role": role, + "lastmessage": device["lastmessage"], + "openems_sum_state_level": device["openems_sum_state_level"] + } + if device["first_setup_protocol_date"]: + dev["first_setup_protocol_date"] = device["first_setup_protocol_date"] + + return dev + + @http.route("/openems_backend/get_edges", auth="user", type="json") + def get_edges(self, limit, page, query=None, searchParams=None): + # Get user + user_id = http.request.env.context.get("uid") + res_users = http.request.env["res.users"].sudo() + user_rec = res_users.search_read( + [("id", "=", user_id)], + ["login", "name", "groups_id", "global_role"], + )[0] + + # Get res group model + res_groups_model = http.request.env["res.groups"].sudo() + + # Get Manager and Reader group + manager_group = res_groups_model.env.ref("openems.group_openems_manager") + reader_group = res_groups_model.env.ref("openems.group_openems_reader") + + manager_group_id = manager_group["id"] + reader_group_id = reader_group["id"] + + # Get specific Device roles + device_user_role_model = http.request.env["openems.device_user_role"] + user_role_ids = device_user_role_model.search_read( + [("user_id", "=", user_id)], ["id", "role"] + ) + + domains = [] + logical_operators = [] + additional_domains = [] + if query: + logical_operators.extend(['|', '|']) + domains = [ + ("name", "ilike", query), + ("comment", "ilike", query), + ("producttype", "ilike", query)] + + if searchParams: + if searchParams.get("producttype"): + additional_domains.append( + ("producttype", "in", searchParams.get("producttype"))) + + if searchParams.get("sumState"): + sum_states = list(map(lambda s: s.lower(), searchParams.get("sumState"))) + additional_domains.append( + ("openems_sum_state_level", "in", sum_states)) + + if "isOnline" in searchParams: + additional_domains.append( + ("openems_is_connected", "=", searchParams.get("isOnline"))) + + if len(additional_domains) > 1: + for _ in range(len(additional_domains) - 1): + logical_operators.insert(0, '&') + + # insert 'and' if both are not 'None' + if query and searchParams: + logical_operators.insert(0, '&') + + domains.extend(additional_domains) + logical_operators.extend(domains) + + # Get Devices + device_model = http.request.env["openems.device"] + devices = device_model.search_read( + logical_operators, + ["id", "name", "user_role_ids", "comment", "producttype", + "lastmessage", "first_setup_protocol_date", "openems_sum_state_level"], + limit=limit, offset=(page * limit) + ) + devs = [] + for device_rec in devices: + # Set user role per group + role = "guest" + if manager_group_id in user_rec["groups_id"]: + # Manager group + role = "admin" + elif reader_group_id in user_rec["groups_id"]: + # Reader group + role = "guest" + + # Set specific user role + for device_role_id in device_rec["user_role_ids"]: + for user_role_id in user_role_ids: + if device_role_id == user_role_id["id"]: + role = user_role_id["role"] + + # Prepare result + dev = { + "id": device_rec["id"], + "name": device_rec["name"], + "comment": device_rec["comment"], + "producttype": device_rec["producttype"], + "role": role, + "lastmessage": device_rec["lastmessage"], + "openems_sum_state_level": device_rec["openems_sum_state_level"] + } + + if device_rec["first_setup_protocol_date"]: + dev["first_setup_protocol_date"] = device_rec[ + "first_setup_protocol_date" + ] + + devs.append(dev) + + return { + "devices": devs, + } diff --git a/addons/openems/controllers/setup_protocol.py b/addons/openems/controllers/setup_protocol.py new file mode 100644 index 0000000..d64b18e --- /dev/null +++ b/addons/openems/controllers/setup_protocol.py @@ -0,0 +1,142 @@ +import base64 + +from odoo import http +from odoo.http import request + + +class SetupProtocol(http.Controller): + @http.route("/openems_backend/sendSetupProtocolEmail", type="json", auth="user") + def index(self, setupProtocolId, edgeId): + setup_protocol_model = request.env["openems.setup_protocol"] + setup_protocol_record = setup_protocol_model.search_read( + [("id", "=", setupProtocolId)] + ) + if len(setup_protocol_record) != 1: + raise ValueError("Setup protocol not found for id [" + edgeId + "]") + + device_model = request.env["openems.device"] + device_rec = device_model.search_read([("name", "=", edgeId)]) + if len(device_rec) != 1: + raise ValueError("Device not found for id [" + edgeId + "]") + + name = ( + "IBN-" + + edgeId + + "-" + + setup_protocol_record[0]["create_date"].strftime("%d.%m.%Y") + + ".pdf" + ) + + data = request.env.ref( + "openems.action_openems_setup_protocol_report" + )._render_qweb_pdf([setupProtocolId]) + ibnPdf = request.env["ir.attachment"].create( + { + "res_model": "openems.device", + "res_id": device_rec[0]["id"], + "name": name, + "store_fname": name, + "datas": base64.b64encode(data[0]), + } + ) + + templates = self.getTemplates(device_rec[0]['oem'], ibnPdf) + + templates['installer'].send_mail(setupProtocolId, force_send=True) + templates['customer'].send_mail(setupProtocolId, force_send=True) + + return {} + + def getTemplates(self, oem: str, protocol): + templates = {'customer': None, 'installer': None} + + templates['customer'] = request.env.ref( + "openems.setup_protocol_email_customer") + templates['installer'] = request.env.ref( + "openems.setup_protocol_email_installer") + + logo = request.env.ref("openems.attachment_logo_openems") + + templates['customer'].attachment_ids = [ + (6, 0, [protocol.id, logo.id])] + templates['installer'].attachment_ids = [ + (6, 0, [protocol.id, logo.id])] + + return templates + + @http.route('/openems_backend/get_latest_setup_protocol', type='json', auth='user') + def get_latest_setup_protocol(self, edge_name): + # search for device + device_model = request.env['openems.device'] + device = device_model.search([('name', '=', edge_name)]) + + response = dict() + if not len(device.setup_protocol_ids) > 0: + return response + + latest_protocol = device.setup_protocol_ids[0] + + # build customer object + customer = latest_protocol.customer_id + customer_values = dict({ + "firstname": customer['firstname'], + "lastname": customer['lastname'], + "email": customer['email'], + "phone": customer['phone'], + "address": { + "street": customer['street'], + "city": customer['city'], + "zip": customer['zip'], + "country": customer['country_id']['name'] + } + }) + + # check company for customer + customer_company = customer['commercial_company_name'] + if customer_company: + customer_values.update({ + "company": { + "name": customer['commercial_company_name'] + } + }) + response.update({"customer": customer_values}) + + # check different location is available + location = latest_protocol['different_location_id'] + if location: + location_values = dict({ + "firstname": location['firstname'], + "lastname": location['lastname'], + "email": location['email'], + "phone": location['phone'], + "address": { + "street": location['street'], + "city": location['city'], + "zip": location['zip'], + "country": location['country_id']['name'] + } + }) + + # check company for different location + different_location_company = location['commercial_company_name'] + if different_location_company: + location_values.update({ + "company": { + "name": location['commercial_company_name'] + } + }) + response.update({"location": location_values}) + + # build items object + items = list() + for item in latest_protocol.item_ids: + items.append({ + "view": item['view'], + "field": item['field'], + "category": item['category'], + "name": item['name'], + "value": item['value'] + }) + response.update({"items": items}) + + return response diff --git a/addons/openems/controllers/user.py b/addons/openems/controllers/user.py new file mode 100644 index 0000000..75ec137 --- /dev/null +++ b/addons/openems/controllers/user.py @@ -0,0 +1,32 @@ +from odoo import http +from odoo.http import request + +class User(http.Controller): + @http.route("/openems_backend/sendRegistrationEmail", type="json", auth="user") + def index(self, userId, password=None, oem: str = ''): + user_model = request.env["res.users"] + user_record = user_model.search_read([("id", "=", userId)], ["partner_id"]) + if len(user_record) != 1: + raise ValueError("User not found for id [" + userId + "]") + + partner = user_record[0] + partner_id = partner.get("partner_id") + if partner_id is None: + raise ValueError("User has no partner") + + if password is None: + password = "*****" + # load template + template = self.getTemplate(oem) + # set mail values + email_values = { + 'password': password + } + # send mail + template.with_context(email_values).send_mail( + res_id=partner_id[0], force_send=True) + return {} + + def getTemplate(self, oem: str): + template = request.env.ref("openems.registration_email") + return template diff --git a/addons/openems/data/OpenEMS-Logo.jpg b/addons/openems/data/OpenEMS-Logo.jpg new file mode 100644 index 0000000000000000000000000000000000000000..13ae0fba6120a7472998decceef335398be01035 GIT binary patch literal 152320 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

`b%zWJVoybJJC+al7(vmUoDSw-d(zU?;>j| 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 + + + + + edge0 + OpenEMS Edge #0 + DEMO_API_KEY + + + + diff --git a/addons/openems/data/ir_config_parameter.xml b/addons/openems/data/ir_config_parameter.xml new file mode 100644 index 0000000..b1da5cf --- /dev/null +++ b/addons/openems/data/ir_config_parameter.xml @@ -0,0 +1,9 @@ + + + + + edge_monitoring_url + http://localhost:8082/device/ + + + diff --git a/addons/openems/data/res_partner_category.xml b/addons/openems/data/res_partner_category.xml new file mode 100644 index 0000000..f56c0e0 --- /dev/null +++ b/addons/openems/data/res_partner_category.xml @@ -0,0 +1,11 @@ + + + + + Created via IBN + + + Customer + + + diff --git a/addons/openems/i18n/de.po b/addons/openems/i18n/de.po new file mode 100644 index 0000000..cc4c660 --- /dev/null +++ b/addons/openems/i18n/de.po @@ -0,0 +1,1666 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * openems +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 16.0-20240218\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2024-02-18 11:57+0000\n" +"PO-Revision-Date: 2024-02-18 11:57+0000\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: openems +#: model:mail.template,body_html:openems.setup_protocol_email_installer +msgid "" +"\n" +"\n" +"\n" +"\n" +"\n" +" OpenEMS setup protocol \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +"\n" +"\n" +"\n" +"

\n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +"
\n" +" \n" +"
\n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +"
\n" +" \n" +"
\n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +"
\n" +"

\n" +"

\n" +" \n" +"
\n" +"
Dear \n" +" ,\n" +"
\n" +"
\n" +"
please find the setup protocol for your customer attached.\n" +"
\n" +"
\n" +"
Best Regards
\n" +"
\n" +"
OpenEMS Association e.V.
\n" +"
\n" +"
\n" +" \n" +"
\n" +"
\n" +" \n" +"
\n" +"
\n" +"\n" +"\n" +"\n" +" \n" +" " +msgstr "" + +#. module: openems +#: model:mail.template,body_html:openems.registration_email +msgid "" +"\n" +"\n" +"\n" +"\n" +"\n" +" Registrierung erfolgreich \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +"\n" +"\n" +"\n" +"
\n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +"
\n" +" \n" +"
\n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +"
\n" +" \n" +"
\n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +"
\n" +"

\n" +"

\n" +" \n" +"
\n" +"
Guten Tag \n" +" ,\n" +"
\n" +"
\n" +"
Ihr Zugang zu OpenEMS UI wurde erstellt.
\n" +"
\n" +"
Sie können sich auf OpenEMS UI einloggen, um auf das Online-Monitoring zuzugreifen.
\n" +"
\n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +"
Ihre Zugangsdaten:
E-Mail\n" +" \n" +"
Passwort\n" +" \n" +"
\n" +"
\n" +"
Best Regards
\n" +"
\n" +"
OpenEMS Association e.V.
\n" +"
\n" +"
\n" +" \n" +"
\n" +"
\n" +" \n" +"
\n" +"
\n" +"\n" +"\n" +"\n" +" \n" +" " +msgstr "" + +#. module: openems +#: model:mail.template,body_html:openems.setup_protocol_email_customer +msgid "" +"\n" +"\n" +"\n" +"\n" +"\n" +" Your OpenEMS Edge setup protocol \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +"\n" +"\n" +"\n" +"
\n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +"
\n" +" \n" +"
\n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +"
\n" +" \n" +"
\n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +"
\n" +"

\n" +"

\n" +" \n" +"
\n" +"
Welcome to OpenEMS,
\n" +"
\n" +"
please find your setup protocol for OpenEMS Edge attached.
\n" +"
\n" +"
Best Regards
\n" +"
\n" +"
OpenEMS Association e.V.
\n" +"
\n" +"
\n" +" \n" +"
\n" +"
\n" +" \n" +"
\n" +"
\n" +"\n" +"\n" +"\n" +" \n" +" " +msgstr "" + +#. module: openems +#: model:mail.template,body_html:openems.alerting_email_generic +msgid "" +"\n" +"\n" +"\n" +"\n" +"\n" +" OpenEMS Alert - Edge is offline\n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +"\n" +"\n" +"\n" +"
\n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +"
\n" +" \n" +"
\n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +"
\n" +" \n" +"
\n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +"
\n" +"

\n" +"

\n" +" \n" +"
\n" +"
Dear \n" +" ,\n" +"
\n" +"
\n" +"
Your OpenEMS Edge with number is offline since:
\n" +"
\n" +"
\n" +" \n" +" \n" +" \n" +" \n" +" \n" +" (UTC)\n" +" \n" +"
\n" +"
\n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +"
Info
\n" +" Edge-Version\n" +" \n" +" \n" +"
\n" +" Type\n" +" \n" +" \n" +" \n" +"
\n" +"
\n" +"
Best Regards
\n" +"
\n" +"
OpenEMS Association e.V.
\n" +"
\n" +"
\n" +" \n" +"
\n" +"
\n" +" \n" +"
\n" +" \n" +"
\n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +"
\n" +" \n" +"
\n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +"
\n" +"
Wenn Sie keine E-Mail Benachrichtigung mehr wünschen, können Sie die Funktion hier deaktivieren.
\n" +"
\n" +"
Dies ist eine automatisch generierte Nachricht. Bitte antworten Sie nicht auf diese Nachricht!
\n" +"
\n" +"
\n" +" \n" +"
\n" +"
\n" +" \n" +"
\n" +"\n" +"\n" +"\n" +" \n" +" " +msgstr "" + +#. module: openems +#: model:ir.actions.report,print_report_name:openems.action_openems_setup_protocol_report +msgid "" +"('IBN-' + object.openems_device_id.name + '-' + " +"object.create_date.strftime('%d.%m.%Y'))" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__apikey +msgid "API-Key" +msgstr "" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.openems_device_form +msgid "Access Role in Online-Monitoring" +msgstr "Zugriffsrollen im Online-Monitoring" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__message_needaction +msgid "Action Needed" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__active +msgid "Active" +msgstr "" + +#. module: openems +#: model:ir.model.fields.selection,name:openems.selection__openems_device_user_role__role__admin +#: model:ir.model.fields.selection,name:openems.selection__res_users__global_role__admin +msgid "Admin" +msgstr "" + +#. module: openems +#: model:ir.ui.menu,name:openems.menu_openems_admin +msgid "Administration" +msgstr "" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.device_search_view +msgid "Archived" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__message_attachment_count +msgid "Attachment Count" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_res_users__branding_partner_id +msgid "Branding Partner" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol_item__category +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol_production_lot__category +msgid "Category" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__comment +msgid "Comment" +msgstr "" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.openems_device_form +msgid "Configuration" +msgstr "Konfiguration" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.openems_device_form +msgid "Configuration Updates" +msgstr "Konfigurationsänderungen" + +#. module: openems +#: model:ir.model,name:openems.model_res_partner +msgid "Contact" +msgstr "Kontakt" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__create_uid +#: model:ir.model.fields,field_description:openems.field_openems_device_tag__create_uid +#: model:ir.model.fields,field_description:openems.field_openems_device_user_role__create_uid +#: model:ir.model.fields,field_description:openems.field_openems_openemsconfigupdate__create_uid +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol__create_uid +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol_item__create_uid +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol_production_lot__create_uid +#: model:ir.model.fields,field_description:openems.field_openems_systemmessage__create_uid +msgid "Created by" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__create_date +#: model:ir.model.fields,field_description:openems.field_openems_device_tag__create_date +#: model:ir.model.fields,field_description:openems.field_openems_device_user_role__create_date +#: model:ir.model.fields,field_description:openems.field_openems_openemsconfigupdate__create_date +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol__create_date +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol_item__create_date +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol_production_lot__create_date +#: model:ir.model.fields,field_description:openems.field_openems_systemmessage__create_date +msgid "Created on" +msgstr "" + +#. module: openems +#: model:res.partner.category,name:openems.res_partner_category_created_via_ibn +msgid "Created via IBN" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_systemmessage__timestamp +msgid "Creation date" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol__customer_id +#: model:res.partner.category,name:openems.res_partner_category_customer +msgid "Customer" +msgstr "" + +#. module: openems +#: model:ir.model.fields.selection,name:openems.selection__res_users__openems_language__cz +msgid "Czech" +msgstr "" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.report_openems_setup_protocol_template +msgid "Datum:" +msgstr "" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.device_search_view +#: model_terms:ir.ui.view,arch_db:openems.openems_device_tree +msgid "Description" +msgstr "Bezeichnung" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.openems_openemsconfigupdate_tree +msgid "Details" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_stock_lot__device_id +#: model:ir.model.fields,field_description:openems.field_stock_lot__device_ids +msgid "Device" +msgstr "" + +#. module: openems +#: model:ir.actions.act_window,name:openems.action_openems_openemsconfigupdate +#: model:ir.ui.menu,name:openems.menu_openems_admin_openemsconfigupdate +msgid "Device Configuration Updates" +msgstr "" + +#. module: openems +#: model:ir.actions.act_window,name:openems.action_openems_device +#: model:ir.ui.menu,name:openems.menu_openems_content_devices +msgid "Devices" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol__different_location_id +msgid "Different Location" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__display_name +#: model:ir.model.fields,field_description:openems.field_openems_device_tag__display_name +#: model:ir.model.fields,field_description:openems.field_openems_device_user_role__display_name +#: model:ir.model.fields,field_description:openems.field_openems_openemsconfigupdate__display_name +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol__display_name +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol_item__display_name +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol_production_lot__display_name +#: model:ir.model.fields,field_description:openems.field_openems_systemmessage__display_name +msgid "Display Name" +msgstr "" + +#. module: openems +#: model:ir.model.fields.selection,name:openems.selection__res_users__openems_language__nl +msgid "Dutch" +msgstr "" + +#. module: openems +#: model:mail.template,name:openems.alerting_email_generic +msgid "E-Mail Alerting" +msgstr "" + +#. module: openems +#: model:mail.template,name:openems.registration_email +msgid "E-Mail Kunden Registrierung" +msgstr "" + +#. module: openems +#: model:mail.template,name:openems.setup_protocol_email_customer +msgid "E-Mail setup protocol for customer" +msgstr "" + +#. module: openems +#: model:mail.template,name:openems.setup_protocol_email_installer +msgid "E-Mail setup protocol for installer" +msgstr "" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.report_openems_setup_protocol_template +msgid "E-Mail-Adresse" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__emshardware +msgid "EMS Hardware" +msgstr "" + +#. module: openems +#: model:ir.model.fields.selection,name:openems.selection__res_users__openems_language__en +msgid "English" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol__item_ids +msgid "Entry Items" +msgstr "" + +#. module: openems +#: model:ir.model.fields.selection,name:openems.selection__openems_device__openems_sum_state_level__fault +msgid "Fault" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol_item__field +msgid "Field Identifier" +msgstr "" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.report_openems_setup_protocol_template +msgid "Firmenname" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__first_setup_protocol_date +msgid "First Setup Protocol Date" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__message_follower_ids +msgid "Followers" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__message_partner_ids +msgid "Followers (Partners)" +msgstr "" + +#. module: openems +#: model:ir.model.fields.selection,name:openems.selection__res_users__openems_language__fr +msgid "French" +msgstr "" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.openems_device_form +msgid "General" +msgstr "" + +#. module: openems +#: model:ir.model.fields.selection,name:openems.selection__res_users__openems_language__de +msgid "German" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_res_users__global_role +msgid "Global Role" +msgstr "" + +#. module: openems +#: model:ir.model.fields.selection,name:openems.selection__openems_device_user_role__role__guest +#: model:ir.model.fields.selection,name:openems.selection__res_users__global_role__guest +msgid "Guest" +msgstr "" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.openems_device_form +msgid "Hardware" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__has_message +msgid "Has Message" +msgstr "" + +#. module: openems +#: model:ir.model.fields.selection,name:openems.selection__res_users__openems_language__hu +msgid "Hungarian" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__id +#: model:ir.model.fields,field_description:openems.field_openems_device_tag__id +#: model:ir.model.fields,field_description:openems.field_openems_device_user_role__id +#: model:ir.model.fields,field_description:openems.field_openems_openemsconfigupdate__id +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol__id +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol_item__id +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol_production_lot__id +#: model:ir.model.fields,field_description:openems.field_openems_systemmessage__id +msgid "ID" +msgstr "" + +#. module: openems +#: model:ir.model.fields,help:openems.field_openems_device__message_needaction +msgid "If checked, new messages require your attention." +msgstr "" + +#. module: openems +#: model:ir.model.fields,help:openems.field_openems_device__message_has_error +#: model:ir.model.fields,help:openems.field_openems_device__message_has_sms_error +msgid "If checked, some messages have a delivery error." +msgstr "" + +#. module: openems +#: model:ir.model.fields.selection,name:openems.selection__openems_device__openems_sum_state_level__info +msgid "Info" +msgstr "" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.report_openems_setup_protocol_template +msgid "Installateur" +msgstr "" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.openems_device_form +msgid "Installation" +msgstr "Inbetriebnahme" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.openems_device_form +msgid "Installation Log" +msgstr "Inbetriebnahme Protokolle" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__setup_password +msgid "Installation key" +msgstr "Installateursschlüssel" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_res_partner__installer_setup_protocols_ids +#: model:ir.model.fields,field_description:openems.field_res_users__installer_setup_protocols_ids +msgid "Installed OpenEMS Edge" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol__installer_id +#: model:ir.model.fields.selection,name:openems.selection__openems_device_user_role__role__installer +#: model:ir.model.fields.selection,name:openems.selection__res_users__global_role__installer +msgid "Installer" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__internalnote +msgid "Internal note" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__message_is_follower +msgid "Is Follower" +msgstr "" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.openems_device_form +msgid "Is connected" +msgstr "" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.report_openems_setup_protocol_template +msgid "Kontaktdaten Endkunde" +msgstr "" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.report_openems_setup_protocol_template +msgid "Land" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device____last_update +#: model:ir.model.fields,field_description:openems.field_openems_device_tag____last_update +#: model:ir.model.fields,field_description:openems.field_openems_device_user_role____last_update +#: model:ir.model.fields,field_description:openems.field_openems_openemsconfigupdate____last_update +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol____last_update +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol_item____last_update +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol_production_lot____last_update +#: model:ir.model.fields,field_description:openems.field_openems_systemmessage____last_update +msgid "Last Modified on" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__write_uid +#: model:ir.model.fields,field_description:openems.field_openems_device_tag__write_uid +#: model:ir.model.fields,field_description:openems.field_openems_device_user_role__write_uid +#: model:ir.model.fields,field_description:openems.field_openems_openemsconfigupdate__write_uid +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol__write_uid +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol_item__write_uid +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol_production_lot__write_uid +#: model:ir.model.fields,field_description:openems.field_openems_systemmessage__write_uid +msgid "Last Updated by" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__write_date +#: model:ir.model.fields,field_description:openems.field_openems_device_tag__write_date +#: model:ir.model.fields,field_description:openems.field_openems_device_user_role__write_date +#: model:ir.model.fields,field_description:openems.field_openems_openemsconfigupdate__write_date +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol__write_date +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol_item__write_date +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol_production_lot__write_date +#: model:ir.model.fields,field_description:openems.field_openems_systemmessage__write_date +msgid "Last Updated on" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__lastupdate +msgid "Last data update" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__lastmessage +msgid "Last message" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device_user_role__last_notification +msgid "Last notification sent" +msgstr "" + +#. module: openems +#: model:ir.model,name:openems.model_stock_lot +msgid "Lot/Serial" +msgstr "Los/Serie" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__message_main_attachment_id +msgid "Main Attachment" +msgstr "" + +#. module: openems +#: model:res.groups,name:openems.group_openems_manager +msgid "Manager" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__manual_setup_date +msgid "Manual Setup Date" +msgstr "" + +#. module: openems +#: model:res.groups,comment:openems.group_openems_manager +msgid "Members of this group can manage all devices" +msgstr "" + +#. module: openems +#: model:res.groups,comment:openems.group_openems_reader +msgid "Members of this group have reading access to all devices" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_systemmessage__text +msgid "Message" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__message_has_error +msgid "Message Delivery error" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__message_ids +msgid "Messages" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__name +#: model:ir.model.fields,field_description:openems.field_openems_device_tag__name +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol_item__name +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol_production_lot__name +msgid "Name" +msgstr "" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.report_openems_setup_protocol_template +msgid "Name Installateur" +msgstr "" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.report_openems_setup_protocol_template +msgid "Name Kontaktperson" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__name_number +msgid "Name Number" +msgstr "" + +#. module: openems +#: model:ir.model.constraint,message:openems.constraint_openems_device_unique_name +msgid "Name needs to be unique" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device_user_role__time_to_wait +msgid "Notification" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__message_needaction_counter +msgid "Number of Actions" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__message_has_error_counter +msgid "Number of errors" +msgstr "" + +#. module: openems +#: model:ir.model.fields,help:openems.field_openems_device__message_needaction_counter +msgid "Number of messages requiring action" +msgstr "" + +#. module: openems +#: model:ir.model.fields,help:openems.field_openems_device__message_has_error_counter +msgid "Number of messages with delivery error" +msgstr "" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.openems_device_tree +msgid "OE Connected" +msgstr "" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.openems_device_tree +msgid "OE State" +msgstr "" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.openems_device_tree +msgid "OE Version" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__oem +msgid "OEM Branding" +msgstr "" + +#. module: openems +#: model:ir.model.fields.selection,name:openems.selection__openems_device__openems_sum_state_level__ok +msgid "Ok" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__monitoring_url +msgid "Online-Monitoring" +msgstr "" + +#. module: openems +#: model:ir.model.fields.selection,name:openems.selection__openems_device__oem__openems +#: model:ir.module.category,name:openems.module_category_openems +#: model:ir.ui.menu,name:openems.menu_openems +#: model_terms:ir.ui.view,arch_db:openems.openems_users_form +msgid "OpenEMS" +msgstr "" + +#. module: openems +#: model:mail.template,subject:openems.alerting_email_generic +msgid "OpenEMS Alert - Edge is offline" +msgstr "" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.report_openems_setup_protocol_template +msgid "OpenEMS Association e.V." +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__openems_config_components +msgid "OpenEMS Config" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__openems_config +msgid "OpenEMS Config Full" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__openems_config_update_ids +msgid "OpenEMS Config Updates" +msgstr "" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.openems_openemsconfigupdate_tree +msgid "OpenEMS Configuration Updates" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device_user_role__device_id +#: model:ir.model.fields,field_description:openems.field_openems_openemsconfigupdate__device_id +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol__device_id +#: model:ir.model.fields,field_description:openems.field_openems_systemmessage__device_id +#: model:ir.model.fields.selection,name:openems.selection__openems_device__producttype__openems-edge +#: model:ir.ui.menu,name:openems.menu_openems_content +msgid "OpenEMS Edge" +msgstr "" + +#. module: openems +#: model:ir.model,name:openems.model_openems_device +msgid "OpenEMS Edge Device" +msgstr "" + +#. module: openems +#: model:ir.model,name:openems.model_openems_openemsconfigupdate +msgid "OpenEMS Edge Device Configuration Update" +msgstr "" + +#. module: openems +#: model:ir.model,name:openems.model_openems_device_tag +msgid "OpenEMS Edge Device Tag" +msgstr "" + +#. module: openems +#: model:ir.model,name:openems.model_openems_device_user_role +msgid "OpenEMS Edge Device User Role" +msgstr "" + +#. module: openems +#: model:ir.model,name:openems.model_openems_setup_protocol_item +msgid "OpenEMS Edge Setup Protocol Entry Item" +msgstr "" + +#. module: openems +#: model:ir.model,name:openems.model_openems_setup_protocol_production_lot +msgid "OpenEMS Edge Setup Protocol Serial Number" +msgstr "" + +#. module: openems +#: model:ir.model,name:openems.model_openems_setup_protocol +msgid "OpenEMS Edge Setup Protocols (IBN)" +msgstr "" + +#. module: openems +#: model:ir.model,name:openems.model_openems_systemmessage +msgid "OpenEMS Edge Systemmessage" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__openems_is_connected +msgid "OpenEMS Is connected" +msgstr "" + +#. module: openems +#: model:ir.actions.report,name:openems.action_openems_setup_protocol_report +msgid "OpenEMS Setup Protocol" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__openems_sum_state_level +msgid "OpenEMS State" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__openems_version +#: model_terms:ir.ui.view,arch_db:openems.device_search_view +msgid "OpenEMS Version" +msgstr "" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.device_search_view +#: model_terms:ir.ui.view,arch_db:openems.openems_device_tree +msgid "OpenEMS-Number" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_res_users__openems_language +msgid "Openems Language" +msgstr "" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.report_openems_setup_protocol_template +msgid "Ort" +msgstr "" + +#. module: openems +#: model:ir.model.fields.selection,name:openems.selection__openems_device_user_role__role__owner +#: model:ir.model.fields.selection,name:openems.selection__res_users__global_role__owner +msgid "Owner" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_res_partner__customer_setup_protocols_ids +#: model:ir.model.fields,field_description:openems.field_res_users__customer_setup_protocols_ids +msgid "Owner of OpenEMS Edge" +msgstr "" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.report_openems_setup_protocol_template +msgid "PLZ" +msgstr "" + +#. module: openems +#: model:ir.model.fields,help:openems.field_openems_device__setup_password +msgid "Password for commissioning by the installer" +msgstr "Passwort für die Inbetriebnahme durch den Installateur" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.openems_setup_protocol_form +msgid "Print" +msgstr "" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.openems_device_form +msgid "Product" +msgstr "Produkt" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__producttype +msgid "Product type" +msgstr "" + +#. module: openems +#: model:res.groups,name:openems.group_openems_reader +msgid "Read access" +msgstr "" + +#. module: openems +#: model:mail.template,subject:openems.registration_email +msgid "Registrierung erfolgreich" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device_user_role__role +msgid "Role" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__user_role_ids +#: model:ir.model.fields,field_description:openems.field_res_users__device_role_ids +msgid "Roles" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__message_has_sms_error +msgid "SMS Delivery error" +msgstr "" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.openems_device_form +msgid "Security" +msgstr "Sicherheit" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol_production_lot__lot_id +msgid "Serial Number" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol__productionlot_ids +msgid "Serial Numbers" +msgstr "" + +#. module: openems +#: model:ir.model.constraint,message:openems.constraint_openems_device_unique_stock_production_lot_id +msgid "Serial number needs to be unique" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol_item__setup_protocol_id +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol_production_lot__setup_protocol_id +#: model_terms:ir.ui.view,arch_db:openems.report_openems_setup_protocol_template +msgid "Setup Protocol" +msgstr "" + +#. module: openems +#: model:ir.actions.act_window,name:openems.action_openems_admin_setup_protocol +#: model:ir.model.fields,field_description:openems.field_openems_device__setup_protocol_ids +#: model:ir.ui.menu,name:openems.menu_openems_admin_setup_protocol +#: model_terms:ir.ui.view,arch_db:openems.res_partner_form +msgid "Setup Protocols" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol_item__sequence +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol_production_lot__sequence +msgid "Sort" +msgstr "" + +#. module: openems +#: model:ir.model.fields.selection,name:openems.selection__res_users__openems_language__es +msgid "Spanish" +msgstr "" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.report_openems_setup_protocol_template +msgid "Speicherstandort" +msgstr "" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.openems_device_form +msgid "Status" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__stock_production_lot_id +msgid "Stock Production Lot" +msgstr "" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.report_openems_setup_protocol_template +msgid "Straße / Hausnummer" +msgstr "" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.openems_device_form +msgid "System Messages" +msgstr "" + +#. module: openems +#: model:ir.actions.act_window,name:openems.action_openems_systemmessage +#: model:ir.model.fields,field_description:openems.field_openems_device__systemmessage_ids +#: model:ir.ui.menu,name:openems.menu_openems_admin_systemmessages +msgid "Systemmessages" +msgstr "" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.openems_device_form +msgid "Systemstatus" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__tag_ids +msgid "Tags" +msgstr "" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.report_openems_setup_protocol_template +msgid "Telefonnummer" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_systemmessage__text_teaser +msgid "Text Teaser" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_openemsconfigupdate__details +msgid "Update Details" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_openemsconfigupdate__teaser +msgid "Update Details Teaser" +msgstr "" + +#. module: openems +#: model:ir.model,name:openems.model_res_users +#: model:ir.model.fields,field_description:openems.field_openems_device_user_role__user_id +msgid "User" +msgstr "Benutzer" + +#. module: openems +#: model:ir.model.constraint,message:openems.constraint_openems_device_user_role_device_user_uniq +msgid "User already exists for this device." +msgstr "" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.openems_systemmessage_tree +msgid "Users" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol_item__value +msgid "Value" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol_item__view +msgid "View Identifier" +msgstr "" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.report_openems_setup_protocol_template +msgid "Vor- Nachname" +msgstr "" + +#. module: openems +#: model:ir.model.fields.selection,name:openems.selection__openems_device__openems_sum_state_level__warning +msgid "Warning" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__website_message_ids +msgid "Website Messages" +msgstr "" + +#. module: openems +#: model:ir.model.fields,help:openems.field_openems_device__website_message_ids +msgid "Website communication history" +msgstr "" + +#. module: openems +#: model:mail.template,subject:openems.setup_protocol_email_customer +#: model:mail.template,subject:openems.setup_protocol_email_installer +msgid "Your OpenEMS setup protocol for {{object.openems_device_id.name}}" +msgstr "" diff --git a/addons/openems/i18n/openems.pot b/addons/openems/i18n/openems.pot new file mode 100644 index 0000000..c02fb93 --- /dev/null +++ b/addons/openems/i18n/openems.pot @@ -0,0 +1,1666 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * openems +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 16.0-20240218\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2024-02-18 11:56+0000\n" +"PO-Revision-Date: 2024-02-18 11:56+0000\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: openems +#: model:mail.template,body_html:openems.setup_protocol_email_installer +msgid "" +"\n" +"\n" +"\n" +"\n" +"\n" +" OpenEMS setup protocol \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +"\n" +"\n" +"\n" +"
\n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +"
\n" +" \n" +"
\n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +"
\n" +" \n" +"
\n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +"
\n" +"

\n" +"

\n" +" \n" +"
\n" +"
Dear \n" +" ,\n" +"
\n" +"
\n" +"
please find the setup protocol for your customer attached.\n" +"
\n" +"
\n" +"
Best Regards
\n" +"
\n" +"
OpenEMS Association e.V.
\n" +"
\n" +"
\n" +" \n" +"
\n" +"
\n" +" \n" +"
\n" +"
\n" +"\n" +"\n" +"\n" +" \n" +" " +msgstr "" + +#. module: openems +#: model:mail.template,body_html:openems.registration_email +msgid "" +"\n" +"\n" +"\n" +"\n" +"\n" +" Registrierung erfolgreich \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +"\n" +"\n" +"\n" +"
\n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +"
\n" +" \n" +"
\n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +"
\n" +" \n" +"
\n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +"
\n" +"

\n" +"

\n" +" \n" +"
\n" +"
Guten Tag \n" +" ,\n" +"
\n" +"
\n" +"
Ihr Zugang zu OpenEMS UI wurde erstellt.
\n" +"
\n" +"
Sie können sich auf OpenEMS UI einloggen, um auf das Online-Monitoring zuzugreifen.
\n" +"
\n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +"
Ihre Zugangsdaten:
E-Mail\n" +" \n" +"
Passwort\n" +" \n" +"
\n" +"
\n" +"
Best Regards
\n" +"
\n" +"
OpenEMS Association e.V.
\n" +"
\n" +"
\n" +" \n" +"
\n" +"
\n" +" \n" +"
\n" +"
\n" +"\n" +"\n" +"\n" +" \n" +" " +msgstr "" + +#. module: openems +#: model:mail.template,body_html:openems.setup_protocol_email_customer +msgid "" +"\n" +"\n" +"\n" +"\n" +"\n" +" Your OpenEMS Edge setup protocol \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +"\n" +"\n" +"\n" +"
\n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +"
\n" +" \n" +"
\n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +"
\n" +" \n" +"
\n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +"
\n" +"

\n" +"

\n" +" \n" +"
\n" +"
Welcome to OpenEMS,
\n" +"
\n" +"
please find your setup protocol for OpenEMS Edge attached.
\n" +"
\n" +"
Best Regards
\n" +"
\n" +"
OpenEMS Association e.V.
\n" +"
\n" +"
\n" +" \n" +"
\n" +"
\n" +" \n" +"
\n" +"
\n" +"\n" +"\n" +"\n" +" \n" +" " +msgstr "" + +#. module: openems +#: model:mail.template,body_html:openems.alerting_email_generic +msgid "" +"\n" +"\n" +"\n" +"\n" +"\n" +" OpenEMS Alert - Edge is offline\n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +"\n" +"\n" +"\n" +"
\n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +"
\n" +" \n" +"
\n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +"
\n" +" \n" +"
\n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +"
\n" +"

\n" +"

\n" +" \n" +"
\n" +"
Dear \n" +" ,\n" +"
\n" +"
\n" +"
Your OpenEMS Edge with number is offline since:
\n" +"
\n" +"
\n" +" \n" +" \n" +" \n" +" \n" +" \n" +" (UTC)\n" +" \n" +"
\n" +"
\n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +"
Info
\n" +" Edge-Version\n" +" \n" +" \n" +"
\n" +" Type\n" +" \n" +" \n" +" \n" +"
\n" +"
\n" +"
Best Regards
\n" +"
\n" +"
OpenEMS Association e.V.
\n" +"
\n" +"
\n" +" \n" +"
\n" +"
\n" +" \n" +"
\n" +" \n" +"
\n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +"
\n" +" \n" +"
\n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +"
\n" +"
Wenn Sie keine E-Mail Benachrichtigung mehr wünschen, können Sie die Funktion hier deaktivieren.
\n" +"
\n" +"
Dies ist eine automatisch generierte Nachricht. Bitte antworten Sie nicht auf diese Nachricht!
\n" +"
\n" +"
\n" +" \n" +"
\n" +"
\n" +" \n" +"
\n" +"\n" +"\n" +"\n" +" \n" +" " +msgstr "" + +#. module: openems +#: model:ir.actions.report,print_report_name:openems.action_openems_setup_protocol_report +msgid "" +"('IBN-' + object.openems_device_id.name + '-' + " +"object.create_date.strftime('%d.%m.%Y'))" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__apikey +msgid "API-Key" +msgstr "" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.openems_device_form +msgid "Access Role in Online-Monitoring" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__message_needaction +msgid "Action Needed" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__active +msgid "Active" +msgstr "" + +#. module: openems +#: model:ir.model.fields.selection,name:openems.selection__openems_device_user_role__role__admin +#: model:ir.model.fields.selection,name:openems.selection__res_users__global_role__admin +msgid "Admin" +msgstr "" + +#. module: openems +#: model:ir.ui.menu,name:openems.menu_openems_admin +msgid "Administration" +msgstr "" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.device_search_view +msgid "Archived" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__message_attachment_count +msgid "Attachment Count" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_res_users__branding_partner_id +msgid "Branding Partner" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol_item__category +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol_production_lot__category +msgid "Category" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__comment +msgid "Comment" +msgstr "" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.openems_device_form +msgid "Configuration" +msgstr "" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.openems_device_form +msgid "Configuration Updates" +msgstr "" + +#. module: openems +#: model:ir.model,name:openems.model_res_partner +msgid "Contact" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__create_uid +#: model:ir.model.fields,field_description:openems.field_openems_device_tag__create_uid +#: model:ir.model.fields,field_description:openems.field_openems_device_user_role__create_uid +#: model:ir.model.fields,field_description:openems.field_openems_openemsconfigupdate__create_uid +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol__create_uid +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol_item__create_uid +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol_production_lot__create_uid +#: model:ir.model.fields,field_description:openems.field_openems_systemmessage__create_uid +msgid "Created by" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__create_date +#: model:ir.model.fields,field_description:openems.field_openems_device_tag__create_date +#: model:ir.model.fields,field_description:openems.field_openems_device_user_role__create_date +#: model:ir.model.fields,field_description:openems.field_openems_openemsconfigupdate__create_date +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol__create_date +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol_item__create_date +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol_production_lot__create_date +#: model:ir.model.fields,field_description:openems.field_openems_systemmessage__create_date +msgid "Created on" +msgstr "" + +#. module: openems +#: model:res.partner.category,name:openems.res_partner_category_created_via_ibn +msgid "Created via IBN" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_systemmessage__timestamp +msgid "Creation date" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol__customer_id +#: model:res.partner.category,name:openems.res_partner_category_customer +msgid "Customer" +msgstr "" + +#. module: openems +#: model:ir.model.fields.selection,name:openems.selection__res_users__openems_language__cz +msgid "Czech" +msgstr "" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.report_openems_setup_protocol_template +msgid "Datum:" +msgstr "" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.device_search_view +#: model_terms:ir.ui.view,arch_db:openems.openems_device_tree +msgid "Description" +msgstr "" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.openems_openemsconfigupdate_tree +msgid "Details" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_stock_lot__device_id +#: model:ir.model.fields,field_description:openems.field_stock_lot__device_ids +msgid "Device" +msgstr "" + +#. module: openems +#: model:ir.actions.act_window,name:openems.action_openems_openemsconfigupdate +#: model:ir.ui.menu,name:openems.menu_openems_admin_openemsconfigupdate +msgid "Device Configuration Updates" +msgstr "" + +#. module: openems +#: model:ir.actions.act_window,name:openems.action_openems_device +#: model:ir.ui.menu,name:openems.menu_openems_content_devices +msgid "Devices" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol__different_location_id +msgid "Different Location" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__display_name +#: model:ir.model.fields,field_description:openems.field_openems_device_tag__display_name +#: model:ir.model.fields,field_description:openems.field_openems_device_user_role__display_name +#: model:ir.model.fields,field_description:openems.field_openems_openemsconfigupdate__display_name +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol__display_name +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol_item__display_name +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol_production_lot__display_name +#: model:ir.model.fields,field_description:openems.field_openems_systemmessage__display_name +msgid "Display Name" +msgstr "" + +#. module: openems +#: model:ir.model.fields.selection,name:openems.selection__res_users__openems_language__nl +msgid "Dutch" +msgstr "" + +#. module: openems +#: model:mail.template,name:openems.alerting_email_generic +msgid "E-Mail Alerting" +msgstr "" + +#. module: openems +#: model:mail.template,name:openems.registration_email +msgid "E-Mail Kunden Registrierung" +msgstr "" + +#. module: openems +#: model:mail.template,name:openems.setup_protocol_email_customer +msgid "E-Mail setup protocol for customer" +msgstr "" + +#. module: openems +#: model:mail.template,name:openems.setup_protocol_email_installer +msgid "E-Mail setup protocol for installer" +msgstr "" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.report_openems_setup_protocol_template +msgid "E-Mail-Adresse" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__emshardware +msgid "EMS Hardware" +msgstr "" + +#. module: openems +#: model:ir.model.fields.selection,name:openems.selection__res_users__openems_language__en +msgid "English" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol__item_ids +msgid "Entry Items" +msgstr "" + +#. module: openems +#: model:ir.model.fields.selection,name:openems.selection__openems_device__openems_sum_state_level__fault +msgid "Fault" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol_item__field +msgid "Field Identifier" +msgstr "" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.report_openems_setup_protocol_template +msgid "Firmenname" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__first_setup_protocol_date +msgid "First Setup Protocol Date" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__message_follower_ids +msgid "Followers" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__message_partner_ids +msgid "Followers (Partners)" +msgstr "" + +#. module: openems +#: model:ir.model.fields.selection,name:openems.selection__res_users__openems_language__fr +msgid "French" +msgstr "" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.openems_device_form +msgid "General" +msgstr "" + +#. module: openems +#: model:ir.model.fields.selection,name:openems.selection__res_users__openems_language__de +msgid "German" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_res_users__global_role +msgid "Global Role" +msgstr "" + +#. module: openems +#: model:ir.model.fields.selection,name:openems.selection__openems_device_user_role__role__guest +#: model:ir.model.fields.selection,name:openems.selection__res_users__global_role__guest +msgid "Guest" +msgstr "" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.openems_device_form +msgid "Hardware" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__has_message +msgid "Has Message" +msgstr "" + +#. module: openems +#: model:ir.model.fields.selection,name:openems.selection__res_users__openems_language__hu +msgid "Hungarian" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__id +#: model:ir.model.fields,field_description:openems.field_openems_device_tag__id +#: model:ir.model.fields,field_description:openems.field_openems_device_user_role__id +#: model:ir.model.fields,field_description:openems.field_openems_openemsconfigupdate__id +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol__id +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol_item__id +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol_production_lot__id +#: model:ir.model.fields,field_description:openems.field_openems_systemmessage__id +msgid "ID" +msgstr "" + +#. module: openems +#: model:ir.model.fields,help:openems.field_openems_device__message_needaction +msgid "If checked, new messages require your attention." +msgstr "" + +#. module: openems +#: model:ir.model.fields,help:openems.field_openems_device__message_has_error +#: model:ir.model.fields,help:openems.field_openems_device__message_has_sms_error +msgid "If checked, some messages have a delivery error." +msgstr "" + +#. module: openems +#: model:ir.model.fields.selection,name:openems.selection__openems_device__openems_sum_state_level__info +msgid "Info" +msgstr "" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.report_openems_setup_protocol_template +msgid "Installateur" +msgstr "" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.openems_device_form +msgid "Installation" +msgstr "" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.openems_device_form +msgid "Installation Log" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__setup_password +msgid "Installation key" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_res_partner__installer_setup_protocols_ids +#: model:ir.model.fields,field_description:openems.field_res_users__installer_setup_protocols_ids +msgid "Installed OpenEMS Edge" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol__installer_id +#: model:ir.model.fields.selection,name:openems.selection__openems_device_user_role__role__installer +#: model:ir.model.fields.selection,name:openems.selection__res_users__global_role__installer +msgid "Installer" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__internalnote +msgid "Internal note" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__message_is_follower +msgid "Is Follower" +msgstr "" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.openems_device_form +msgid "Is connected" +msgstr "" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.report_openems_setup_protocol_template +msgid "Kontaktdaten Endkunde" +msgstr "" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.report_openems_setup_protocol_template +msgid "Land" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device____last_update +#: model:ir.model.fields,field_description:openems.field_openems_device_tag____last_update +#: model:ir.model.fields,field_description:openems.field_openems_device_user_role____last_update +#: model:ir.model.fields,field_description:openems.field_openems_openemsconfigupdate____last_update +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol____last_update +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol_item____last_update +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol_production_lot____last_update +#: model:ir.model.fields,field_description:openems.field_openems_systemmessage____last_update +msgid "Last Modified on" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__write_uid +#: model:ir.model.fields,field_description:openems.field_openems_device_tag__write_uid +#: model:ir.model.fields,field_description:openems.field_openems_device_user_role__write_uid +#: model:ir.model.fields,field_description:openems.field_openems_openemsconfigupdate__write_uid +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol__write_uid +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol_item__write_uid +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol_production_lot__write_uid +#: model:ir.model.fields,field_description:openems.field_openems_systemmessage__write_uid +msgid "Last Updated by" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__write_date +#: model:ir.model.fields,field_description:openems.field_openems_device_tag__write_date +#: model:ir.model.fields,field_description:openems.field_openems_device_user_role__write_date +#: model:ir.model.fields,field_description:openems.field_openems_openemsconfigupdate__write_date +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol__write_date +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol_item__write_date +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol_production_lot__write_date +#: model:ir.model.fields,field_description:openems.field_openems_systemmessage__write_date +msgid "Last Updated on" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__lastupdate +msgid "Last data update" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__lastmessage +msgid "Last message" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device_user_role__last_notification +msgid "Last notification sent" +msgstr "" + +#. module: openems +#: model:ir.model,name:openems.model_stock_lot +msgid "Lot/Serial" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__message_main_attachment_id +msgid "Main Attachment" +msgstr "" + +#. module: openems +#: model:res.groups,name:openems.group_openems_manager +msgid "Manager" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__manual_setup_date +msgid "Manual Setup Date" +msgstr "" + +#. module: openems +#: model:res.groups,comment:openems.group_openems_manager +msgid "Members of this group can manage all devices" +msgstr "" + +#. module: openems +#: model:res.groups,comment:openems.group_openems_reader +msgid "Members of this group have reading access to all devices" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_systemmessage__text +msgid "Message" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__message_has_error +msgid "Message Delivery error" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__message_ids +msgid "Messages" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__name +#: model:ir.model.fields,field_description:openems.field_openems_device_tag__name +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol_item__name +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol_production_lot__name +msgid "Name" +msgstr "" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.report_openems_setup_protocol_template +msgid "Name Installateur" +msgstr "" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.report_openems_setup_protocol_template +msgid "Name Kontaktperson" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__name_number +msgid "Name Number" +msgstr "" + +#. module: openems +#: model:ir.model.constraint,message:openems.constraint_openems_device_unique_name +msgid "Name needs to be unique" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device_user_role__time_to_wait +msgid "Notification" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__message_needaction_counter +msgid "Number of Actions" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__message_has_error_counter +msgid "Number of errors" +msgstr "" + +#. module: openems +#: model:ir.model.fields,help:openems.field_openems_device__message_needaction_counter +msgid "Number of messages requiring action" +msgstr "" + +#. module: openems +#: model:ir.model.fields,help:openems.field_openems_device__message_has_error_counter +msgid "Number of messages with delivery error" +msgstr "" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.openems_device_tree +msgid "OE Connected" +msgstr "" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.openems_device_tree +msgid "OE State" +msgstr "" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.openems_device_tree +msgid "OE Version" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__oem +msgid "OEM Branding" +msgstr "" + +#. module: openems +#: model:ir.model.fields.selection,name:openems.selection__openems_device__openems_sum_state_level__ok +msgid "Ok" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__monitoring_url +msgid "Online-Monitoring" +msgstr "" + +#. module: openems +#: model:ir.model.fields.selection,name:openems.selection__openems_device__oem__openems +#: model:ir.module.category,name:openems.module_category_openems +#: model:ir.ui.menu,name:openems.menu_openems +#: model_terms:ir.ui.view,arch_db:openems.openems_users_form +msgid "OpenEMS" +msgstr "" + +#. module: openems +#: model:mail.template,subject:openems.alerting_email_generic +msgid "OpenEMS Alert - Edge is offline" +msgstr "" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.report_openems_setup_protocol_template +msgid "OpenEMS Association e.V." +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__openems_config_components +msgid "OpenEMS Config" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__openems_config +msgid "OpenEMS Config Full" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__openems_config_update_ids +msgid "OpenEMS Config Updates" +msgstr "" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.openems_openemsconfigupdate_tree +msgid "OpenEMS Configuration Updates" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device_user_role__device_id +#: model:ir.model.fields,field_description:openems.field_openems_openemsconfigupdate__device_id +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol__device_id +#: model:ir.model.fields,field_description:openems.field_openems_systemmessage__device_id +#: model:ir.model.fields.selection,name:openems.selection__openems_device__producttype__openems-edge +#: model:ir.ui.menu,name:openems.menu_openems_content +msgid "OpenEMS Edge" +msgstr "" + +#. module: openems +#: model:ir.model,name:openems.model_openems_device +msgid "OpenEMS Edge Device" +msgstr "" + +#. module: openems +#: model:ir.model,name:openems.model_openems_openemsconfigupdate +msgid "OpenEMS Edge Device Configuration Update" +msgstr "" + +#. module: openems +#: model:ir.model,name:openems.model_openems_device_tag +msgid "OpenEMS Edge Device Tag" +msgstr "" + +#. module: openems +#: model:ir.model,name:openems.model_openems_device_user_role +msgid "OpenEMS Edge Device User Role" +msgstr "" + +#. module: openems +#: model:ir.model,name:openems.model_openems_setup_protocol_item +msgid "OpenEMS Edge Setup Protocol Entry Item" +msgstr "" + +#. module: openems +#: model:ir.model,name:openems.model_openems_setup_protocol_production_lot +msgid "OpenEMS Edge Setup Protocol Serial Number" +msgstr "" + +#. module: openems +#: model:ir.model,name:openems.model_openems_setup_protocol +msgid "OpenEMS Edge Setup Protocols (IBN)" +msgstr "" + +#. module: openems +#: model:ir.model,name:openems.model_openems_systemmessage +msgid "OpenEMS Edge Systemmessage" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__openems_is_connected +msgid "OpenEMS Is connected" +msgstr "" + +#. module: openems +#: model:ir.actions.report,name:openems.action_openems_setup_protocol_report +msgid "OpenEMS Setup Protocol" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__openems_sum_state_level +msgid "OpenEMS State" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__openems_version +#: model_terms:ir.ui.view,arch_db:openems.device_search_view +msgid "OpenEMS Version" +msgstr "" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.device_search_view +#: model_terms:ir.ui.view,arch_db:openems.openems_device_tree +msgid "OpenEMS-Number" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_res_users__openems_language +msgid "Openems Language" +msgstr "" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.report_openems_setup_protocol_template +msgid "Ort" +msgstr "" + +#. module: openems +#: model:ir.model.fields.selection,name:openems.selection__openems_device_user_role__role__owner +#: model:ir.model.fields.selection,name:openems.selection__res_users__global_role__owner +msgid "Owner" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_res_partner__customer_setup_protocols_ids +#: model:ir.model.fields,field_description:openems.field_res_users__customer_setup_protocols_ids +msgid "Owner of OpenEMS Edge" +msgstr "" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.report_openems_setup_protocol_template +msgid "PLZ" +msgstr "" + +#. module: openems +#: model:ir.model.fields,help:openems.field_openems_device__setup_password +msgid "Password for commissioning by the installer" +msgstr "" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.openems_setup_protocol_form +msgid "Print" +msgstr "" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.openems_device_form +msgid "Product" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__producttype +msgid "Product type" +msgstr "" + +#. module: openems +#: model:res.groups,name:openems.group_openems_reader +msgid "Read access" +msgstr "" + +#. module: openems +#: model:mail.template,subject:openems.registration_email +msgid "Registrierung erfolgreich" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device_user_role__role +msgid "Role" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__user_role_ids +#: model:ir.model.fields,field_description:openems.field_res_users__device_role_ids +msgid "Roles" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__message_has_sms_error +msgid "SMS Delivery error" +msgstr "" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.openems_device_form +msgid "Security" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol_production_lot__lot_id +msgid "Serial Number" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol__productionlot_ids +msgid "Serial Numbers" +msgstr "" + +#. module: openems +#: model:ir.model.constraint,message:openems.constraint_openems_device_unique_stock_production_lot_id +msgid "Serial number needs to be unique" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol_item__setup_protocol_id +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol_production_lot__setup_protocol_id +#: model_terms:ir.ui.view,arch_db:openems.report_openems_setup_protocol_template +msgid "Setup Protocol" +msgstr "" + +#. module: openems +#: model:ir.actions.act_window,name:openems.action_openems_admin_setup_protocol +#: model:ir.model.fields,field_description:openems.field_openems_device__setup_protocol_ids +#: model:ir.ui.menu,name:openems.menu_openems_admin_setup_protocol +#: model_terms:ir.ui.view,arch_db:openems.res_partner_form +msgid "Setup Protocols" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol_item__sequence +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol_production_lot__sequence +msgid "Sort" +msgstr "" + +#. module: openems +#: model:ir.model.fields.selection,name:openems.selection__res_users__openems_language__es +msgid "Spanish" +msgstr "" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.report_openems_setup_protocol_template +msgid "Speicherstandort" +msgstr "" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.openems_device_form +msgid "Status" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__stock_production_lot_id +msgid "Stock Production Lot" +msgstr "" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.report_openems_setup_protocol_template +msgid "Straße / Hausnummer" +msgstr "" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.openems_device_form +msgid "System Messages" +msgstr "" + +#. module: openems +#: model:ir.actions.act_window,name:openems.action_openems_systemmessage +#: model:ir.model.fields,field_description:openems.field_openems_device__systemmessage_ids +#: model:ir.ui.menu,name:openems.menu_openems_admin_systemmessages +msgid "Systemmessages" +msgstr "" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.openems_device_form +msgid "Systemstatus" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__tag_ids +msgid "Tags" +msgstr "" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.report_openems_setup_protocol_template +msgid "Telefonnummer" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_systemmessage__text_teaser +msgid "Text Teaser" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_openemsconfigupdate__details +msgid "Update Details" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_openemsconfigupdate__teaser +msgid "Update Details Teaser" +msgstr "" + +#. module: openems +#: model:ir.model,name:openems.model_res_users +#: model:ir.model.fields,field_description:openems.field_openems_device_user_role__user_id +msgid "User" +msgstr "" + +#. module: openems +#: model:ir.model.constraint,message:openems.constraint_openems_device_user_role_device_user_uniq +msgid "User already exists for this device." +msgstr "" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.openems_systemmessage_tree +msgid "Users" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol_item__value +msgid "Value" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol_item__view +msgid "View Identifier" +msgstr "" + +#. module: openems +#: model_terms:ir.ui.view,arch_db:openems.report_openems_setup_protocol_template +msgid "Vor- Nachname" +msgstr "" + +#. module: openems +#: model:ir.model.fields.selection,name:openems.selection__openems_device__openems_sum_state_level__warning +msgid "Warning" +msgstr "" + +#. module: openems +#: model:ir.model.fields,field_description:openems.field_openems_device__website_message_ids +msgid "Website Messages" +msgstr "" + +#. module: openems +#: model:ir.model.fields,help:openems.field_openems_device__website_message_ids +msgid "Website communication history" +msgstr "" + +#. module: openems +#: model:mail.template,subject:openems.setup_protocol_email_customer +#: model:mail.template,subject:openems.setup_protocol_email_installer +msgid "Your OpenEMS setup protocol for {{object.openems_device_id.name}}" +msgstr "" diff --git a/addons/openems/mail/openems/alerting_offline.xml b/addons/openems/mail/openems/alerting_offline.xml new file mode 100644 index 0000000..2d2a38d --- /dev/null +++ b/addons/openems/mail/openems/alerting_offline.xml @@ -0,0 +1,275 @@ + + + + + E-Mail Offline-Alerting + + ]]> + {{object.user_id.partner_id.id}} + OpenEMS Alert - Edge is offline + + + + + OpenEMS Alert - Edge is offline + + + + + + + + + + + + + + + +
+ + + + + + +
+ +
+ + + + + + +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+

+

+ +
+
+ + + , + + Ms/Mr , + Customer, +
+
+
Your OpenEMS Edge with number is offline since: +
+
+
+ + + + + + + (UTC) + + +
+
+ + + + + + + + + + + + +
Info
+ OpenEMS-Version + + + + + UNKNOWN +
+ Type + + + + + + + +
+
+
Best Regards
+
+
OpenEMS Association e.V.
+
+
+ +
+
+ +
+ +
+ + + + + + +
+ +
+ + + + + + + + + + + + + + + +
+
If you do no longer wish to receive email notifications, you can disable the feature here .
+
+
This is an automatically generated message. Please do not reply to this message!
+
+ + + + + + +
+ OpenEMS Logo +
+
+

+

+ +
+
+ +
+
+ +
+ + + + ]]> +
+
+
+
diff --git a/addons/openems/mail/openems/alerting_sum_state.xml b/addons/openems/mail/openems/alerting_sum_state.xml new file mode 100644 index 0000000..5ac49f6 --- /dev/null +++ b/addons/openems/mail/openems/alerting_sum_state.xml @@ -0,0 +1,268 @@ + + + + + E-Mail SumState Alerting + + ]]> + {{object.user_id.partner_id.id}} + OpenEMS Alert - Edge is in {{object.device_id.openems_sum_state_level}} State + + + + + OpenEMS Alert - Edge is in fault + + + + + + + + + + + + + + + +
+ + + + + + +
+ +
+ + + + + + +
+ +
+ + + + + + + + + + + + + + + + + + + + + +
+

+

+ +
+
+ + + , + + Ms/Mr , + Customer, +
+
+
Your OpenEMS Edge with number is in a continuous + + + + + + + UNKNOWN + state! +
+
+ + + + + + + + + + + + +
Info
+ OpenEMS-Version + + + + + UNKNOWN +
+ Type + + + + + + + +
+
+
Best Regards
+
+
OpenEMS Association e.V.
+
+
+ +
+
+ +
+ +
+ + + + + + +
+ +
+ + + + + + + + + + + + + + + +
+
If you do no longer wish to receive email notifications, you can disable the feature here .
+
+
This is an automatically generated message. Please do not reply to this message!
+
+ + + + + + +
+ OpenEMS Logo +
+
+

+

+ +
+
+ +
+
+ +
+ + + + ]]> +
+
+
+
diff --git a/addons/openems/mail/openems/setup_protocol_customer.xml b/addons/openems/mail/openems/setup_protocol_customer.xml new file mode 100644 index 0000000..3b1e781 --- /dev/null +++ b/addons/openems/mail/openems/setup_protocol_customer.xml @@ -0,0 +1,170 @@ + + + + + E-Mail setup protocol for customer + + ]]> + {{object.customer_id.id}} + Your OpenEMS setup protocol for {{object.openems_device_id.name}} + false + + + + + Your OpenEMS Edge setup protocol + + + + + + + + + + + + + + + +
+ + + + + + +
+ +
+ + + + + + +
+ +
+ + + + + + + + + + + + + + + + + + +
+

+

+ +
+
Welcome to OpenEMS,
+
+
please find your setup protocol for OpenEMS Edge attached.
+
+
Best Regards
+
+
OpenEMS Association e.V.
+
+
+ +
+
+ +
+
+ + + + ]]> +
+
+
+
diff --git a/addons/openems/mail/openems/setup_protocol_installer.xml b/addons/openems/mail/openems/setup_protocol_installer.xml new file mode 100644 index 0000000..13afd9d --- /dev/null +++ b/addons/openems/mail/openems/setup_protocol_installer.xml @@ -0,0 +1,173 @@ + + + + + E-Mail setup protocol for installer + + ]]> + {{object.installer_id.id}} + Your OpenEMS setup protocol for {{object.openems_device_id.name}} + false + + + + + OpenEMS setup protocol + + + + + + + + + + + + + + + +
+ + + + + + +
+ +
+ + + + + + +
+ +
+ + + + + + + + + + + + + + + + + + +
+

+

+ +
+
Dear + , +
+
+
please find the setup protocol for your customer attached. +
+
+
Best Regards
+
+
OpenEMS Association e.V.
+
+
+ +
+
+ +
+
+ + + + ]]> +
+
+
+
diff --git a/addons/openems/mail/openems/user_registration.xml b/addons/openems/mail/openems/user_registration.xml new file mode 100644 index 0000000..cfd4183 --- /dev/null +++ b/addons/openems/mail/openems/user_registration.xml @@ -0,0 +1,197 @@ + + + + + E-Mail Kunden Registrierung + + ]]> + {{object.id}} + Registrierung erfolgreich + false + + + + + Registrierung erfolgreich + + + + + + + + + + + + + + + +
+ + + + + + +
+ +
+ + + + + + +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+

+

+ +
+
Guten Tag + , +
+
+
Ihr Zugang zu OpenEMS UI wurde erstellt.
+
+
Sie können sich auf OpenEMS UI einloggen, um auf das Online-Monitoring zuzugreifen.
+
+ + + + + + + + + + + + +
Ihre Zugangsdaten:
E-Mail + +
Passwort + +
+
+
Best Regards
+
+
OpenEMS Association e.V.
+
+
+ +
+
+ +
+
+ + + + ]]> +
+
+
+
diff --git a/addons/openems/migrations/16.0.1.0.1/post-migrate.py b/addons/openems/migrations/16.0.1.0.1/post-migrate.py new file mode 100644 index 0000000..1eab6fe --- /dev/null +++ b/addons/openems/migrations/16.0.1.0.1/post-migrate.py @@ -0,0 +1,9 @@ +def migrate(cr, version): + cr.execute(""" + INSERT INTO openems_alerting (device_id, device_name, user_id, user_login, offline_delay, warning_delay, fault_delay, offline_last_notification) + SELECT device_id, dev.name, user_id, usr.login, time_to_wait, 0, 0, last_notification + FROM openems_alerting_migrate AS migrate + LEFT JOIN openems_device AS dev ON dev.id = migrate.device_id + LEFT JOIN res_users AS usr ON usr.id = migrate.user_id + """) + cr.execute('DROP TABLE openems_alerting_migrate') diff --git a/addons/openems/migrations/16.0.1.0.1/pre-migrate.py b/addons/openems/migrations/16.0.1.0.1/pre-migrate.py new file mode 100644 index 0000000..341e4a5 --- /dev/null +++ b/addons/openems/migrations/16.0.1.0.1/pre-migrate.py @@ -0,0 +1,7 @@ +def migrate(cr, version): + cr.execute(""" + SELECT device_id, user_id, time_to_wait, last_notification + INTO openems_alerting_migrate + FROM openems_device_user_role + WHERE time_to_wait > 0; + """) diff --git a/addons/openems/models/__init__.py b/addons/openems/models/__init__.py new file mode 100644 index 0000000..c4a7e59 --- /dev/null +++ b/addons/openems/models/__init__.py @@ -0,0 +1 @@ +from . import device, partner, setup_protocol, user, stock_production_lot diff --git a/addons/openems/models/device.py b/addons/openems/models/device.py new file mode 100644 index 0000000..bdbda80 --- /dev/null +++ b/addons/openems/models/device.py @@ -0,0 +1,321 @@ +from odoo import api, fields, models, exceptions, _ +from datetime import datetime +from odoo.exceptions import ValidationError +import random +import re +import string + +class Device(models.Model): + _name = "openems.device" + _description = "OpenEMS Edge Device" + _inherit = "mail.thread" + _order = "name_number asc" + _sql_constraints = [ + ("unique_name", "unique(name)", "Name needs to be unique"), + ("unique_stock_production_lot_id", "unique(stock_production_lot_id)", + "Serial number needs to be unique") + ] + + name = fields.Char(required=True) + active = fields.Boolean("Active", default=True, tracking=True) + comment = fields.Char(tracking=True) + internalnote = fields.Text("Internal note", tracking=True) + tag_ids = fields.Many2many("openems.device_tag", string="Tags", tracking=True) + monitoring_url = fields.Char( + "Online-Monitoring", compute="_compute_monitoring_url", store=False + ) + stock_production_lot_id = fields.Many2one("stock.lot") + first_setup_protocol_date = fields.Datetime( + "First Setup Protocol Date", compute="_compute_first_setup_protocol" + ) + manual_setup_date = fields.Datetime("Manual Setup Date") + + @api.depends("setup_protocol_ids", "manual_setup_date") + def _compute_first_setup_protocol(self): + for rec in self: + if rec.manual_setup_date: + rec.first_setup_protocol_date = rec.manual_setup_date + elif len(rec.setup_protocol_ids) > 0: + rec.first_setup_protocol_date = rec.setup_protocol_ids[ + (len(rec.setup_protocol_ids) - 1) + ]["create_date"] + else: + rec.first_setup_protocol_date = None + + @api.depends("name") + def _compute_monitoring_url(self): + # Corrected the parameter key to 'edge_monitoring_url' + base_url = self.env["ir.config_parameter"].sudo().get_param("edge_monitoring_url", default='#') + for rec in self: + if isinstance(rec.name, str) and rec.name: + # Ensuring there is a '/' between base_url and rec.name if it's not already present + separator = '' if base_url.endswith('/') else '/' + rec.monitoring_url = base_url + separator + rec.name + "/live" + else: + rec.monitoring_url = base_url + + producttype = fields.Selection( + [ + ("openems-edge", "OpenEMS Edge"), + ], + "Product type", + tracking=True, + ) + emshardware = fields.Selection([], "EMS Hardware", tracking=True) + oem = fields.Selection( + [ + ("openems", "OpenEMS"), + ], + "OEM Branding", + default="openems", + ) + + # Settings + openems_config = fields.Text("OpenEMS Config Full") + openems_config_components = fields.Text("OpenEMS Config") + openems_version = fields.Char("OpenEMS Version", tracking=True) + + # Security + setup_password = fields.Char( + "Installation Key", + help="Password for commissioning by the installer", + ) + apikey = fields.Char("API-Key", required=True, tracking=True) + + # 'openems_sum_state_level' is updated by OpenEMS Backend + openems_sum_state_level = fields.Selection( + [("ok", "Ok"), ("info", "Info"), ("warning", "Warning"), ("fault", "Fault")], + "OpenEMS State", + ) + # 'openems_is_connected' is updated by OpenEMS Backend + openems_is_connected = fields.Boolean("OpenEMS Is connected") + + # System Status + lastmessage = fields.Datetime("Last message") + lastupdate = fields.Datetime("Last data update") + + # Verknüpfungen + systemmessage_ids = fields.One2many( + "openems.systemmessage", "device_id", string="System Messages" + ) + user_role_ids = fields.One2many( + "openems.device_user_role", "device_id", string="Roles", tracking=True + ) + alerting_settings = fields.One2many( + "openems.alerting", "device_id", string="Alerting", tracking=True + ) + openems_config_update_ids = fields.One2many( + "openems.openemsconfigupdate", "device_id", string="OpenEMS Config Updates" + ) + setup_protocol_ids = fields.One2many( + "openems.setup_protocol", "device_id", "Setup Protocols" + ) + + # Helper fields + name_number = fields.Integer(compute="_compute_name_number", store="True") + + @api.depends("name") + def _compute_name_number(self): + for rec in self: + rec.name_number = int(rec.name[4:]) if rec.name.startswith("edge") else -1 + + def _get_openems_state_number(self, string): + state = 0 + if string == "info": + state = 1 + elif string == "warning": + state = 2 + elif string == "fault": + state = 3 + return state + + def write(self, vals): + """Prohibit to change name field after creation.""" + if 'name' in vals: + for record in self: + if record.id and record.name != vals['name']: + self.env.cr.execute(""" + SELECT EXISTS ( + SELECT 1 FROM openems_device + WHERE name = %s AND id != %s + ) + """, (vals['name'], record.id)) + exists = self.env.cr.fetchone()[0] + if exists: + # This means there's already a device with the intended new name + raise exceptions.UserError( + "The name '{}' is already in use or does not follow the required pattern.".format( + vals['name'])) + + # If you simply want to prevent name changes, the following UserError suffices + raise exceptions.UserError("The name of the device cannot be changed after creation.") + return super(Device, self).write(vals) + + @api.model + def create(self, vals): + + # Generate setup password if not provided + if 'setup_password' not in vals or not vals['setup_password']: + vals['setup_password'] = self._generate_unique_setup_password() + + # Generate API key if not provided + if 'apikey' not in vals or not vals['apikey']: + vals['apikey'] = self._generate_api_key() + + return super(Device, self).create(vals) + + def _generate_unique_setup_password(self): + is_unique = False + setup_password = '' + while not is_unique: + # Generate a random setup password + raw_password = ''.join(random.choices(string.ascii_uppercase + string.digits, k=16)) + setup_password = '-'.join([raw_password[i:i + 4] for i in range(0, len(raw_password), 4)]) + # Check if the generated setup password already exists + existing = self.search_count([('setup_password', '=', setup_password)]) + # If the password does not exist, it is unique, and we can exit the loop + if existing == 0: + is_unique = True + return setup_password + + def _generate_api_key(self): + # Initialize a flag to indicate whether the generated key is unique + is_unique = False + api_key = '' + while not is_unique: + # Generate a random API key + api_key = ''.join(random.choices(string.ascii_letters + string.digits, k=20)) + # Check if the generated API key already exists + existing = self.search_count([('apikey', '=', api_key)]) + # If the key does not exist, it is unique, and we can exit the loop + if existing == 0: + is_unique = True + return api_key + + @api.onchange('setup_password') + def _check_setup_password_format(self): + for record in self: + if not record.setup_password: + continue + if not re.match(r"^[A-Z0-9]{4}-[A-Z0-9]{4}-[A-Z0-9]{4}-[A-Z0-9]{4}$", record.setup_password): + raise ValidationError("The device ID must be formatted as XXXX-XXXX-XXXX-XXXX") + + @api.onchange('apikey') + def _check_api_key_uniqueness(self): + for record in self: + if record.apikey: + # Prepare the domain for searching duplicates + domain = [('apikey', '=', record.apikey)] + # If the record is already saved (has a valid database ID), exclude it from the search + if record.id and isinstance(record.id, (int,)): + domain.append(('id', '!=', record.id)) + # Check if any other records with the same API key exist + existing = self.search_count(domain) + # If there are duplicates, raise a ValidationError + if existing: + raise ValidationError( + _("The API key already exists and must be unique. Please choose a different API key.")) + + +class DeviceTag(models.Model): + _name = "openems.device_tag" + _description = "OpenEMS Edge Device Tag" + name = fields.Char(required=True) + + +class DeviceUserRole(models.Model): + _name = "openems.device_user_role" + _description = "OpenEMS Edge Device User Role" + _sql_constraints = [ + ( + "device_user_uniq", + "unique(device_id, user_id)", + "User already exists for this device.", + ), + ] + device_id = fields.Many2one("openems.device", string="OpenEMS Edge") + user_id = fields.Many2one("res.users", string="User") + role = fields.Selection( + [ + ("admin", "Admin"), + ("installer", "Installer"), + ("owner", "Owner"), + ("guest", "Guest"), + ], + default="guest", + required=True, + ) + + +class OpenemsConfigUpdate(models.Model): + _name = "openems.openemsconfigupdate" + _description = "OpenEMS Edge Device Configuration Update" + _order = "create_date desc" + + device_id = fields.Many2one("openems.device", string="OpenEMS Edge") + teaser = fields.Text("Update Details Teaser") + details = fields.Html("Update Details") + + +class Systemmessage(models.Model): + _name = "openems.systemmessage" + _description = "OpenEMS Edge Systemmessage" + _order = "create_date desc" + + timestamp = fields.Datetime("Creation date") + device_id = fields.Many2one("openems.device", string="OpenEMS Edge") + text = fields.Text("Message") + text_teaser = fields.Char(compute="_compute_text_teaser") + + @api.depends("text") + def _compute_text_teaser(self): + for rec in self: + # get up to 100 characters from first line + rec.text_teaser = rec.text.splitlines()[0][0:100] if rec.text else False + +class Alerting(models.Model): + _name = "openems.alerting" + _description = "OpenEMS Edge AlertingSettings" + _sql_constraints = [ + ( + "device_user_uniq", + "unique(device_id, user_id)", + "User already has Alerting Settings.", + ), + ] + + device_id = fields.Many2one("openems.device", string="OpenEMS Edge") + user_id = fields.Many2one("res.users", string="User") + + offline_delay = fields.Integer(string="Offline Notification", default=1440) + warning_delay = fields.Integer(string="Warning Notification", default=1440) + fault_delay = fields.Integer(string="Fault Notification", default=1440) + + offline_last_notification = fields.Datetime(string="Last Offline notification sent") + sum_state_last_notification = fields.Datetime(string="Last SumState notification sent") + + device_name = fields.Text(compute="_compute_device_name", store="True") + user_login = fields.Text(compute="_compute_user_login", store="True") + + user_role = fields.Selection( + [("admin", "Admin"), ("installer", "Installer"), ("owner", "Owner"), ("guest", "Guest"),], + compute="_compute_user_role", store="False") + + @api.depends("device_id") + def _compute_device_name(self): + for rec in self: + rec.device_name = rec.device_id.name; + + @api.depends("user_id") + def _compute_user_login(self): + for rec in self: + rec.user_login = rec.user_id.login; + + @api.depends("user_id", "device_id") + def _compute_user_role(self): + for rec in self: + user_role: DeviceUserRole = rec.user_id.device_role_ids.search([('device_id','=',rec.device_id.id)]) + if user_role: + return user_role.role + else: + return rec.user_id.global_role diff --git a/addons/openems/models/partner.py b/addons/openems/models/partner.py new file mode 100644 index 0000000..37ab8e5 --- /dev/null +++ b/addons/openems/models/partner.py @@ -0,0 +1,12 @@ +from odoo import fields, models + + +class ResPartner(models.Model): + _inherit = "res.partner" + + installer_setup_protocols_ids = fields.One2many( + "openems.setup_protocol", "installer_id", "Installed OpenEMS Edge" + ) + customer_setup_protocols_ids = fields.One2many( + "openems.setup_protocol", "customer_id", "Owner of OpenEMS Edge" + ) diff --git a/addons/openems/models/setup_protocol.py b/addons/openems/models/setup_protocol.py new file mode 100644 index 0000000..548576e --- /dev/null +++ b/addons/openems/models/setup_protocol.py @@ -0,0 +1,49 @@ +from odoo import fields, models + + +class SetupProtocol(models.Model): + _name = "openems.setup_protocol" + _description = "OpenEMS Edge Setup Protocols (IBN)" + _order = "create_date desc" + + customer_id = fields.Many2one("res.partner", "Customer", required=True) + different_location_id = fields.Many2one("res.partner", "Different Location") + installer_id = fields.Many2one("res.partner", "Installer", required=True) + device_id = fields.Many2one("openems.device", "OpenEMS Edge", required=True) + productionlot_ids = fields.One2many( + "openems.setup_protocol_production_lot", "setup_protocol_id", "Serial Numbers" + ) + item_ids = fields.One2many( + "openems.setup_protocol_item", "setup_protocol_id", "Entry Items" + ) + + +class SetupProtocolProductionLot(models.Model): + _name = "openems.setup_protocol_production_lot" + _description = "OpenEMS Edge Setup Protocol Serial Number" + _order = "setup_protocol_id, category, sequence asc" + + sequence = fields.Integer("Sort") + category = fields.Char("Category") + name = fields.Char("Name") + lot_id = fields.Many2one("stock.production.lot", "Serial Number") + setup_protocol_id = fields.Many2one( + "openems.setup_protocol", "Setup Protocol", ondelete="cascade" + ) + + +class SetupProtocolItem(models.Model): + _name = "openems.setup_protocol_item" + _description = "OpenEMS Edge Setup Protocol Entry Item" + _order = "setup_protocol_id, category, sequence asc" + + sequence = fields.Integer("Sort") + category = fields.Char("Category") + name = fields.Char("Name") + value = fields.Char("Value") + setup_protocol_id = fields.Many2one( + "openems.setup_protocol", "Setup Protocol", ondelete="cascade" + ) + view = fields.Char("View Identifier") + field = fields.Char("Field Identifier") + diff --git a/addons/openems/models/stock_production_lot.py b/addons/openems/models/stock_production_lot.py new file mode 100644 index 0000000..37ebb22 --- /dev/null +++ b/addons/openems/models/stock_production_lot.py @@ -0,0 +1,23 @@ +from odoo import fields, models, api + + +class ProductionLot(models.Model): + _inherit = "stock.lot" + + device_id = fields.Many2one( + 'openems.device', compute='compute_device_id', inverse='device_inverse') + device_ids = fields.One2many('openems.device', 'stock_production_lot_id') + + @api.depends('device_ids') + def compute_device_id(self): + if len(self.device_ids) > 0: + self.device_id = self.device_ids[0] + + def device_inverse(self): + if len(self.device_ids) > 0: + if len(self.device_id.stock_production_lot_id) > 0: + raise ValueError("A serial number has already been assigned to the device") + + device = self.env['openems.device'].browse(self.device_ids[0].id) + device.stock_production_lot_id = False + self.device_id.stock_production_lot_id = self diff --git a/addons/openems/models/user.py b/addons/openems/models/user.py new file mode 100644 index 0000000..321dd87 --- /dev/null +++ b/addons/openems/models/user.py @@ -0,0 +1,37 @@ +from odoo import fields, models + + +class ResUsers(models.Model): + _inherit = "res.users" + + branding_partner_id = fields.Many2one("res.partner", string="Branding Partner") + global_role = fields.Selection( + [ + ("admin", "Admin"), + ("installer", "Installer"), + ("owner", "Owner"), + ("guest", "Guest"), + ], + default="guest", + required=True, + ) + device_role_ids = fields.One2many( + "openems.device_user_role", "user_id", string="Roles" + ) + alerting_settings = fields.One2many( + "openems.alerting", "user_id", string="Alerting" + ) + openems_language = fields.Selection( + [ + ("EN", "English"), + ("DE", "German"), + ("CZ", "Czech"), + ("NL", "Dutch"), + ("ES", "Spanish"), + ("FR", "French"), + ("HU", "Hungarian"), + ("JA", "Japanese"), + ], + default="DE", + required=True, + ) diff --git a/addons/openems/report/setup_protocol.xml b/addons/openems/report/setup_protocol.xml new file mode 100644 index 0000000..c9db4ec --- /dev/null +++ b/addons/openems/report/setup_protocol.xml @@ -0,0 +1,311 @@ + + + + OpenEMS Setup Protocol + openems.setup_protocol + qweb-pdf + openems.report_openems_setup_protocol_template + ('IBN-' + object.openems_device_id.name + '-' + object.create_date.strftime('%d.%m.%Y')) + + + diff --git a/addons/openems/security/ir.model.access.csv b/addons/openems/security/ir.model.access.csv new file mode 100644 index 0000000..1ccc0f1 --- /dev/null +++ b/addons/openems/security/ir.model.access.csv @@ -0,0 +1,31 @@ +id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink +access_openems_device_portal,access_openems_device_portal,openems.model_openems_device,base.group_portal,1,0,0,0 +access_openems_device_user,access_openems_device_user,openems.model_openems_device,base.group_user,1,0,0,0 +access_openems_device_manager,access_openems_device_manager,openems.model_openems_device,openems.group_openems_manager,1,1,1,0 +access_openems_device_tag_portal,access_openems_device_tag_portal,openems.model_openems_device_tag,base.group_portal,1,0,0,0 +access_openems_device_tag_user,access_openems_device_tag_user,openems.model_openems_device_tag,base.group_user,1,0,0,0 +access_openems_device_tag_manager,access_openems_device_tag_manager,openems.model_openems_device_tag,openems.group_openems_manager,1,1,1,1 +access_openems_device_user_role_portal,access_openems_device_user_role_portal,openems.model_openems_device_user_role,base.group_portal,1,0,0,0 +access_openems_device_user_role_user,access_openems_device_user_role_user,openems.model_openems_device_user_role,base.group_user,1,0,0,0 +access_openems_device_user_role_manager,access_openems_device_user_role_manager,openems.model_openems_device_user_role,openems.group_openems_manager,1,1,1,1 +access_openems_alerting_portal,access_openems_alerting_portal,openems.model_openems_alerting,base.group_portal,1,0,0,0 +access_openems_alerting_user,access_openems_alerting_user,openems.model_openems_alerting,base.group_user,1,0,0,0 +access_openems_alerting_manager,access_openems_alerting_manager,openems.model_openems_alerting,openems.group_openems_manager,1,1,1,1 +access_openems_systemmessage_portal,access_openems_systemmessage_portal,openems.model_openems_systemmessage,base.group_portal,1,0,0,0 +access_openems_systemmessage_user,access_openems_systemmessage_user,openems.model_openems_systemmessage,base.group_user,1,0,0,0 +access_openems_systemmessage_manager,access_openems_systemmessage_manager,openems.model_openems_systemmessage,openems.group_openems_manager,1,1,1,1 +access_openems_openemsconfigupdate_portal,access_openems_openemsconfigupdate_portal,openems.model_openems_openemsconfigupdate,base.group_portal,1,0,0,0 +access_openems_openemsconfigupdate_user,access_openems_openemsconfigupdate_user,openems.model_openems_openemsconfigupdate,base.group_user,1,0,0,0 +access_openems_openemsconfigupdate_manager,access_openems_openemsconfigupdate_manager,openems.model_openems_openemsconfigupdate,openems.group_openems_manager,1,1,1,1 +access_openems_setup_protocol_portal,access_openems_setup_protocol_portal,openems.model_openems_setup_protocol,base.group_portal,1,0,0,0 +access_openems_setup_protocol_user,access_openems_setup_protocol_user,openems.model_openems_setup_protocol,base.group_user,1,0,0,0 +access_openems_setup_protocol_manager,access_openems_setup_protocol_manager,openems.model_openems_setup_protocol,openems.group_openems_manager,1,1,1,1 +access_openems_setup_protocol_production_lot_portal,access_openems_setup_protocol_production_lot_portal,openems.model_openems_setup_protocol_production_lot,base.group_portal,1,0,0,0 +access_openems_setup_protocol_production_lot_user,access_openems_setup_protocol_production_lot_user,openems.model_openems_setup_protocol_production_lot,base.group_user,1,0,0,0 +access_openems_setup_protocol_production_lot_manager,access_openems_setup_protocol_production_lot_manager,openems.model_openems_setup_protocol_production_lot,openems.group_openems_manager,1,1,1,1 +access_openems_setup_protocol_item_portal,access_openems_setup_protocol_item_portal,openems.model_openems_setup_protocol_item,base.group_portal,1,0,0,0 +access_openems_setup_protocol_item_user,access_openems_setup_protocol_item_user,openems.model_openems_setup_protocol_item,base.group_user,1,0,0,0 +access_openems_setup_protocol_item_manager,access_openems_setup_protocol_item_manager,openems.model_openems_setup_protocol_item,openems.group_openems_manager,1,1,1,1 +access_openems_production_lot_portal,access_openems_production_lot_portal,stock.model_stock_lot,base.group_portal,1,0,0,0 +access_openems_production_lot_user,access_openems_production_lot_user,stock.model_stock_lot,base.group_user,1,0,0,0 +access_openems_production_lot_manager,access_openems_production_lot_manager,stock.model_stock_lot,openems.group_openems_manager,1,0,0,0 diff --git a/addons/openems/security/openems.xml b/addons/openems/security/openems.xml new file mode 100644 index 0000000..ef87c2f --- /dev/null +++ b/addons/openems/security/openems.xml @@ -0,0 +1,54 @@ + + + + OpenEMS + 30 + + + + Read access + Members of this group have reading access to all devices + + + + + Manager + Members of this group can manage all devices + + + + + + + Website: Show only approved devices to Portal and User + + ['|', ('user_role_ids.user_id','in',[user.id]), ('alerting_settings.user_id','in',[user.id])] + + + + + + + + + Website: Show all devices to readers group + + [(1,'=',1)] + + + + + + + + diff --git a/addons/openems/setup/.setuptools-odoo-make-default-ignore b/addons/openems/setup/.setuptools-odoo-make-default-ignore new file mode 100644 index 0000000..207e615 --- /dev/null +++ b/addons/openems/setup/.setuptools-odoo-make-default-ignore @@ -0,0 +1,2 @@ +# addons listed in this file are ignored by +# setuptools-odoo-make-default (one addon per line) diff --git a/addons/openems/setup/README b/addons/openems/setup/README new file mode 100644 index 0000000..a63d633 --- /dev/null +++ b/addons/openems/setup/README @@ -0,0 +1,2 @@ +To learn more about this directory, please visit +https://pypi.python.org/pypi/setuptools-odoo diff --git a/addons/openems/static/description/icon.png b/addons/openems/static/description/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..ee0aed1a0d5b623df9c4f3ead2a8d92ab7efc315 GIT binary patch literal 53271 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

`b%zWJVoybJJC+al7(vmUoDSw-d(zU?;>j| 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 + + + + Device: Tree + openems.device + + + + + + + + + + + + + + + + + Device: Search + openems.device + + + + + + + + + + + + + + + + + + + + + Device: Form + openems.device + +

+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + +
+ + + + + + Device DeviceUserRole: Tree + openems.device_user_role + + + + + + + + + + Devices + ir.actions.act_window + openems.device + tree,form + + + + + + Device Configuration Updates + openems.openemsconfigupdate + + + + Device Configuration Updates: Tree + openems.openemsconfigupdate + + + + + + + + + + + Device Configuration Updates: Form + openems.openemsconfigupdate + +
+ + + + + + + +
+
+
+ + + + Systemmessages + openems.systemmessage + + + + Device Systemmessage: Tree + openems.systemmessage + + + + + + + + + + + Device Systemmessage: Form + openems.systemmessage + +
+ + + + + + + +
+
+
+ + + + + + + + + diff --git a/addons/openems/views/partner.xml b/addons/openems/views/partner.xml new file mode 100644 index 0000000..874530e --- /dev/null +++ b/addons/openems/views/partner.xml @@ -0,0 +1,28 @@ + + + + OpenEMS Partner: Form + res.partner + + + + + + + + + + + + + + + + + + + + + + + diff --git a/addons/openems/views/setup_protocol.xml b/addons/openems/views/setup_protocol.xml new file mode 100644 index 0000000..bf2eee2 --- /dev/null +++ b/addons/openems/views/setup_protocol.xml @@ -0,0 +1,82 @@ + + + + SetupProtocol: Form + openems.setup_protocol + +
+ + +
+ + +
+ + + diff --git a/addons/web_m2x_options/static/src/components/form.esm.js b/addons/web_m2x_options/static/src/components/form.esm.js new file mode 100644 index 0000000..ecb37d2 --- /dev/null +++ b/addons/web_m2x_options/static/src/components/form.esm.js @@ -0,0 +1,404 @@ +/** @odoo-module **/ + +import { + Many2ManyTagsField, + Many2ManyTagsFieldColorEditable, +} from "@web/views/fields/many2many_tags/many2many_tags_field"; + +import {Dialog} from "@web/core/dialog/dialog"; +import {FormController} from "@web/views/form/form_controller"; +import {FormViewDialog} from "@web/views/view_dialogs/form_view_dialog"; +import {Many2OneAvatarField} from "@web/views/fields/many2one_avatar/many2one_avatar_field"; +import {Many2OneBarcodeField} from "@web/views/fields/many2one_barcode/many2one_barcode_field"; +import {Many2OneField} from "@web/views/fields/many2one/many2one_field"; +import {ReferenceField} from "@web/views/fields/reference/reference_field"; +import {X2ManyField} from "@web/views/fields/x2many/x2many_field"; +import {isX2Many} from "@web/views/utils"; +import {is_option_set} from "@web_m2x_options/components/relational_utils.esm"; +import {patch} from "@web/core/utils/patch"; +import {sprintf} from "@web/core/utils/strings"; +import {useService} from "@web/core/utils/hooks"; + +const {Component} = owl; + +/** + * Patch Many2ManyTagsField + **/ +patch(Many2ManyTagsField.prototype, "web_m2x_options.Many2ManyTagsField", { + setup() { + this._super(...arguments); + this.actionService = useService("action"); + }, + /** + * @override + */ + getTagProps(record) { + const props = this._super(...arguments); + props.onClick = (ev) => this.onMany2ManyBadgeClick(ev, record); + return props; + }, + async onMany2ManyBadgeClick(event, record) { + var self = this; + if (self.props.open) { + var context = self.context; + var id = record.data.id; + if (self.props.readonly) { + event.preventDefault(); + event.stopPropagation(); + const action = await self.orm.call( + self.props.relation, + "get_formview_action", + [[id]], + {context: context} + ); + self.actionService.doAction(action); + } else { + const view_id = await self.orm.call( + self.props.relation, + "get_formview_id", + [[id]], + {context: context} + ); + + const write_access = await self.orm.call( + self.props.relation, + "check_access_rights", + [], + {operation: "write", raise_exception: false} + ); + var can_write = self.props.canWrite; + self.dialog.add(FormViewDialog, { + resModel: self.props.relation, + resId: id, + context: context, + title: self.env._t("Open: ") + self.string, + viewId: view_id, + mode: !can_write || !write_access ? "readonly" : "edit", + onRecordSaved: () => self.props.value.model.load(), + }); + } + } + }, +}); + +Many2ManyTagsField.props = { + ...Many2ManyTagsField.props, + open: {type: Boolean, optional: true}, + canWrite: {type: Boolean, optional: true}, + nodeOptions: {type: Object, optional: true}, +}; + +const Many2ManyTagsFieldExtractProps = Many2ManyTagsField.extractProps; +Many2ManyTagsField.extractProps = ({attrs, field}) => { + const canOpen = Boolean(attrs.options.open); + const canWrite = attrs.can_write && Boolean(JSON.parse(attrs.can_write)); + return Object.assign(Many2ManyTagsFieldExtractProps({attrs, field}), { + open: canOpen, + canWrite: canWrite, + nodeOptions: attrs.options, + }); +}; + +/** + * Many2ManyTagsFieldColorEditable + **/ +patch( + Many2ManyTagsFieldColorEditable.prototype, + "web_m2x_options.Many2ManyTagsFieldColorEditable", + { + async onBadgeClick(event, record) { + if (this.props.canEditColor && !this.props.open) { + this._super(...arguments); + } + if (this.props.open) { + Many2ManyTagsField.prototype.onMany2ManyBadgeClick.bind(this)( + event, + record + ); + } + }, + } +); + +Many2ManyTagsFieldColorEditable.props = { + ...Many2ManyTagsFieldColorEditable.props, + open: {type: Boolean, optional: true}, + canWrite: {type: Boolean, optional: true}, + nodeOptions: {type: Object, optional: true}, +}; + +/** + * CreateConfirmationDialog + * New customized component for Many2One Field + **/ + +class CreateConfirmationDialog extends Component { + get title() { + return sprintf(this.env._t("New: %s"), this.props.name); + } + + async onCreate() { + await this.props.create(); + this.props.close(); + } + async onCreateEdit() { + await this.props.createEdit(); + this.props.close(); + } +} +CreateConfirmationDialog.components = {Dialog}; +CreateConfirmationDialog.template = + "web_m2x_options.Many2OneField.CreateConfirmationDialog"; + +/** + * Many2OneField + **/ + +patch(Many2OneField.prototype, "web_m2x_options.Many2OneField", { + setup() { + this._super(...arguments); + this.ir_options = Component.env.session.web_m2x_options; + }, + /** + * @override + */ + get Many2XAutocompleteProps() { + const props = this._super(...arguments); + return { + ...props, + searchLimit: this.props.searchLimit, + searchMore: this.props.searchMore, + canCreate: this.props.canCreate, + nodeOptions: this.props.nodeOptions, + }; + }, + + async openConfirmationDialog(request) { + var m2o_dialog_opt = + is_option_set(this.props.nodeOptions.m2o_dialog) || + (_.isUndefined(this.props.nodeOptions.m2o_dialog) && + is_option_set(this.ir_options["web_m2x_options.m2o_dialog"])) || + (_.isUndefined(this.props.nodeOptions.m2o_dialog) && + _.isUndefined(this.ir_options["web_m2x_options.m2o_dialog"])); + if (this.props.canCreate && this.state.isFloating && m2o_dialog_opt) { + return new Promise((resolve, reject) => { + this.addDialog(CreateConfirmationDialog, { + value: request, + name: this.props.string, + create: async () => { + try { + await this.quickCreate(request); + resolve(); + } catch (e) { + reject(e); + } + }, + createEdit: async () => { + try { + await this.quickCreate(request); + await this.props.record.model.load(); + this.openMany2X({ + resId: this.props.value[0], + context: this.user_context, + }); + resolve(); + } catch (e) { + reject(e); + } + }, + }); + }); + } + }, +}); + +const Many2OneFieldExtractProps = Many2OneField.extractProps; +Many2OneField.extractProps = ({attrs, field}) => { + return Object.assign(Many2OneFieldExtractProps({attrs, field}), { + searchLimit: attrs.options.limit, + searchMore: attrs.options.search_more, + nodeOptions: attrs.options, + }); +}; + +Many2OneField.props = { + ...Many2OneField.props, + searchMore: {type: Boolean, optional: true}, + nodeOptions: {type: Object, optional: true}, +}; + +/** + * FIXME: find better way to extend props in Many2OneField + * Override ReferenceField + * Since extracted/added props: nodeOptions and searchMore into Many2OneField props + * and this component inherited props from Many2OneField + * So, must override props here to avoid constraint validateProps (props schema) in owl core + */ + +ReferenceField.props = { + ...ReferenceField.props, + searchMore: {type: Boolean, optional: true}, + nodeOptions: {type: Object, optional: true}, +}; + +/** + * FIXME: find better way to extend props in Many2OneField + * Override Many2OneBarcodeField + * Since extracted/added props: nodeOptions and searchMore into Many2OneField props + * and this component inherited props from Many2OneField + * So, must override props here to avoid constraint validateProps (props schema) in owl core + */ + +Many2OneBarcodeField.props = { + ...Many2OneBarcodeField.props, + searchMore: {type: Boolean, optional: true}, + nodeOptions: {type: Object, optional: true}, +}; + +/** + * FIXME: find better way to extend props in Many2OneField + * Override Many2OneAvatarField + * Since extracted/added props: nodeOptions and searchMore into Many2OneField props + * and this component inherited props from Many2OneField + * So, must override props here to avoid constraint validateProps (props schema) in owl core + */ +Many2OneAvatarField.props = { + ...Many2OneAvatarField.props, + searchMore: {type: Boolean, optional: true}, + nodeOptions: {type: Object, optional: true}, +}; + +/** + * FIXME: find better way to extend props in Many2OneField + * Override mailing_m2o_filter + * Since extracted/added props: nodeOptions and searchMore into Many2OneField props + * and this component inherited props from Many2OneField + * So, must override props here to avoid constraint validateProps (props schema) in owl core + * This component is in module mass_mailing as optional module, + * So need to import dynamic way + */ +try { + (async () => { + // Make sure component mailing_m2o_filter in mass mailing module loaded + const installed_mass_mailing = await odoo.ready( + "@mass_mailing/js/mailing_m2o_filter" + ); + if (installed_mass_mailing) { + const {FieldMany2OneMailingFilter} = await odoo.runtimeImport( + "@mass_mailing/js/mailing_m2o_filter" + ); + FieldMany2OneMailingFilter.props = { + ...FieldMany2OneMailingFilter.props, + searchMore: {type: Boolean, optional: true}, + nodeOptions: {type: Object, optional: true}, + }; + } + })(); +} catch { + console.log( + "Ignore overriding props of component mailing_m2o_filter since the module is not installed" + ); +} + +/** + * X2ManyField + **/ +patch(X2ManyField.prototype, "web_m2x_options.X2ManyField", { + /** + * @override + */ + async openRecord(record) { + var self = this; + var open = this.props.open; + if (open && self.props.readonly) { + var res_id = record.data.id; + const action = await self.env.model.orm.call( + self.props.value.resModel, + "get_formview_action", + [[res_id]] + ); + return self.env.model.actionService.doAction(action); + } + return this._super.apply(this, arguments); + }, +}); + +const X2ManyFieldExtractProps = X2ManyField.extractProps; +X2ManyField.extractProps = ({attrs}) => { + const canOpen = Boolean(attrs.options.open); + return Object.assign(X2ManyFieldExtractProps({attrs}), { + open: canOpen, + }); +}; + +X2ManyField.props = { + ...X2ManyField.props, + open: {type: Boolean, optional: true}, +}; + +/** + * FormController + **/ +patch(FormController.prototype, "web_m2x_options.FormController", { + /** + * @override + */ + setup() { + var self = this; + this._super(...arguments); + + /** Due to problem of 2 onWillStart in native web core + * (see: https://github.com/odoo/odoo/blob/16.0/addons/web/static/src/views/model.js#L142) + * do the trick to override beforeLoadResolver here to customize viewLimit + */ + this.superBeforeLoadResolver = this.beforeLoadResolver; + this.beforeLoadResolver = async () => { + await self._setSubViewLimit(); + self.superBeforeLoadResolver(); + }; + }, + /** + * @override + * add more method to add subview limit on formview + */ + async _setSubViewLimit() { + const ir_options = Component.env.session.web_m2x_options; + + const activeFields = this.archInfo.activeFields, + fields = this.props.fields, + isSmall = this.user; + + var limit = ir_options["web_m2x_options.field_limit_entries"]; + if (!_.isUndefined(limit)) { + limit = parseInt(limit, 10); + } + + for (const fieldName in activeFields) { + const field = fields[fieldName]; + if (!isX2Many(field)) { + // What follows only concerns x2many fields + continue; + } + const fieldInfo = activeFields[fieldName]; + if (fieldInfo.modifiers.invisible === true) { + // No need to fetch the sub view if the field is always invisible + continue; + } + + if (!fieldInfo.FieldComponent.useSubView) { + // The FieldComponent used to render the field doesn't need a sub view + continue; + } + + let viewType = fieldInfo.viewMode || "list,kanban"; + viewType = viewType.replace("tree", "list"); + if (viewType.includes(",")) { + viewType = isSmall ? "kanban" : "list"; + } + fieldInfo.viewMode = viewType; + if (fieldInfo.views[viewType] && limit) { + fieldInfo.views[viewType].limit = limit; + } + } + }, +}); diff --git a/addons/web_m2x_options/static/src/components/relational_utils.esm.js b/addons/web_m2x_options/static/src/components/relational_utils.esm.js new file mode 100644 index 0000000..1fbe39e --- /dev/null +++ b/addons/web_m2x_options/static/src/components/relational_utils.esm.js @@ -0,0 +1,221 @@ +/** @odoo-module **/ + +import {Many2XAutocomplete} from "@web/views/fields/relational_utils"; +import {patch} from "@web/core/utils/patch"; +import {sprintf} from "@web/core/utils/strings"; +const {Component} = owl; + +export function is_option_set(option) { + if (_.isUndefined(option)) return false; + if (typeof option === "string") return option === "true" || option === "True"; + if (typeof option === "boolean") return option; + return false; +} + +patch(Many2XAutocomplete.prototype, "web_m2x_options.Many2XAutocomplete", { + setup() { + this._super(...arguments); + this.ir_options = Component.env.session.web_m2x_options; + }, + + async loadOptionsSource(request) { + if (this.lastProm) { + this.lastProm.abort(false); + } + // Add options limit used to change number of selections record + // returned. + if (!_.isUndefined(this.ir_options["web_m2x_options.limit"])) { + this.props.searchLimit = parseInt( + this.ir_options["web_m2x_options.limit"], + 10 + ); + this.limit = this.props.searchLimit; + } + + if (typeof this.props.nodeOptions.limit === "number") { + this.props.searchLimit = this.props.nodeOptions.limit; + this.limit = this.props.searchLimit; + } + + // Add options field_color and colors to color item(s) depending on field_color value + this.field_color = this.props.nodeOptions.field_color; + this.colors = this.props.nodeOptions.colors; + + this.lastProm = this.orm.call(this.props.resModel, "name_search", [], { + name: request, + operator: "ilike", + args: this.props.getDomain(), + limit: this.props.searchLimit + 1, + context: this.props.context, + }); + const records = await this.lastProm; + + var options = records.map((result) => ({ + value: result[0], + id: result[0], + label: result[1].split("\n")[0], + })); + + // Limit results if there is a custom limit options + if (this.limit) { + options = options.slice(0, this.props.searchLimit); + } + + // Search result value colors + if (this.colors && this.field_color) { + var value_ids = options.map((result) => result.value); + const objects = await this.orm.call( + this.props.resModel, + "search_read", + [], + { + domain: [["id", "in", value_ids]], + fields: [this.field_color], + } + ); + for (var index in objects) { + for (var index_value in options) { + if (options[index_value].id === objects[index].id) { + // Find value in values by comparing ids + var option = options[index_value]; + // Find color with field value as key + var color = + this.colors[objects[index][this.field_color]] || "black"; + option.style = "color:" + color; + break; + } + } + } + } + + // Quick create + // Note: Create should be before `search_more` (reserve native order) + // One more reason: when calling `onInputBlur`, native select the first option (activeSourceOption) + // which triggers m2o_dialog if m2o_dialog=true + var create_enabled = + this.props.quickCreate && !this.props.nodeOptions.no_create; + + var raw_result = _.map(records, function (x) { + return x[1]; + }); + var quick_create = is_option_set(this.props.nodeOptions.create), + quick_create_undef = _.isUndefined(this.props.nodeOptions.create), + m2x_create_undef = _.isUndefined(this.ir_options["web_m2x_options.create"]), + m2x_create = is_option_set(this.ir_options["web_m2x_options.create"]); + var show_create = + (!this.props.nodeOptions && (m2x_create_undef || m2x_create)) || + (this.props.nodeOptions && + (quick_create || + (quick_create_undef && (m2x_create_undef || m2x_create)))); + if ( + create_enabled && + !this.props.nodeOptions.no_quick_create && + request.length > 0 && + !_.contains(raw_result, request) && + show_create + ) { + options.push({ + label: sprintf(this.env._t(`Create "%s"`), request), + classList: "o_m2o_dropdown_option o_m2o_dropdown_option_create", + action: async (params) => { + try { + await this.props.quickCreate(request, params); + } catch { + const context = this.getCreationContext(request); + return this.openMany2X({context}); + } + }, + }); + } + + // Search more... + // Resolution order: + // 1- check if "search_more" is set locally in node's options + // 2- if set locally, apply its value + // 3- if not set locally, check if it's set globally via ir.config_parameter + // 4- if set globally, apply its value + // 5- if not set globally either, check if returned values are more than node's limit + var search_more = false; + if (!_.isUndefined(this.props.nodeOptions.search_more)) { + search_more = is_option_set(this.props.nodeOptions.search_more); + } else if (!_.isUndefined(this.ir_options["web_m2x_options.search_more"])) { + search_more = is_option_set(this.ir_options["web_m2x_options.search_more"]); + } else { + search_more = + !this.props.noSearchMore && this.props.searchLimit < records.length; + } + if (search_more) { + options.push({ + label: this.env._t("Search More..."), + action: this.onSearchMore.bind(this, request), + classList: "o_m2o_dropdown_option o_m2o_dropdown_option_search_more", + }); + } + + // Create and Edit + const canCreateEdit = + "createEdit" in this.activeActions + ? this.activeActions.createEdit + : this.activeActions.create; + if ( + !request.length && + !this.props.value && + (this.props.quickCreate || canCreateEdit) + ) { + options.push({ + label: this.env._t("Start typing..."), + classList: "o_m2o_start_typing", + unselectable: true, + }); + } + + // Create and edit ... + var create_edit = + is_option_set(this.props.nodeOptions.create) || + is_option_set(this.props.nodeOptions.create_edit), + create_edit_undef = + _.isUndefined(this.props.nodeOptions.create) && + _.isUndefined(this.props.nodeOptions.create_edit), + m2x_create_edit_undef = _.isUndefined( + this.ir_options["web_m2x_options.create_edit"] + ), + m2x_create_edit = is_option_set( + this.ir_options["web_m2x_options.create_edit"] + ); + var show_create_edit = + (!this.props.nodeOptions && (m2x_create_edit_undef || m2x_create_edit)) || + (this.props.nodeOptions && + (create_edit || + (create_edit_undef && (m2x_create_edit_undef || m2x_create_edit)))); + if ( + create_enabled && + !this.props.nodeOptions.no_create_edit && + show_create_edit && + request.length && + canCreateEdit + ) { + const context = this.getCreationContext(request); + options.push({ + label: this.env._t("Create and edit..."), + classList: "o_m2o_dropdown_option o_m2o_dropdown_option_create_edit", + action: () => this.openMany2X({context}), + }); + } + + // No records + if (!records.length && !this.activeActions.create) { + options.push({ + label: this.env._t("No records"), + classList: "o_m2o_no_result", + unselectable: true, + }); + } + + return options; + }, +}); + +Many2XAutocomplete.defaultProps = { + ...Many2XAutocomplete.defaultProps, + nodeOptions: {}, +}; diff --git a/addons/web_m2x_options/tests/__init__.py b/addons/web_m2x_options/tests/__init__.py new file mode 100644 index 0000000..b472ff3 --- /dev/null +++ b/addons/web_m2x_options/tests/__init__.py @@ -0,0 +1,2 @@ +# Copyright 2020 initOS GmbH. +from . import test_ir_config_parameter diff --git a/addons/web_m2x_options/tests/test_ir_config_parameter.py b/addons/web_m2x_options/tests/test_ir_config_parameter.py new file mode 100644 index 0000000..eae00c7 --- /dev/null +++ b/addons/web_m2x_options/tests/test_ir_config_parameter.py @@ -0,0 +1,28 @@ +# Copyright 2020 initOS GmbH. +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). + +from odoo.tests import common + + +class TestIrConfigParameter(common.TransactionCase): + @classmethod + def setUpClass(cls): + super(TestIrConfigParameter, cls).setUpClass() + cls.env["ir.config_parameter"].set_param("web_m2x_options.limit", 10) + cls.env["ir.config_parameter"].set_param("web_m2x_options.create_edit", "True") + cls.env["ir.config_parameter"].set_param("web_m2x_options.create", "True") + cls.env["ir.config_parameter"].set_param("web_m2x_options.search_more", "False") + cls.env["ir.config_parameter"].set_param("web_m2x_options.m2o_dialog", "True") + + def test_web_m2x_options_key(self): + web_m2x_options = self.env["ir.config_parameter"].get_web_m2x_options() + self.assertIn("web_m2x_options.limit", web_m2x_options) + self.assertNotIn("web_m2x_options.m2o_dialog_test", web_m2x_options) + + def test_web_m2x_options_value(self): + web_m2x_options = self.env["ir.config_parameter"].get_web_m2x_options() + self.assertEqual(web_m2x_options["web_m2x_options.limit"], "10") + self.assertTrue(bool(web_m2x_options["web_m2x_options.create_edit"])) + self.assertTrue(bool(web_m2x_options["web_m2x_options.create"])) + self.assertEqual(web_m2x_options["web_m2x_options.search_more"], "False") + self.assertTrue(bool(web_m2x_options["web_m2x_options.m2o_dialog"])) From 85246fa39c03838facb1d67fedffcc2757149495 Mon Sep 17 00:00:00 2001 From: belloafeez Date: Fri, 2 Aug 2024 10:35:26 +0100 Subject: [PATCH 24/54] dsgwe Signed-off-by: belloafeez --- odoo/Dockerfile | 1 + 1 file changed, 1 insertion(+) diff --git a/odoo/Dockerfile b/odoo/Dockerfile index 7481bed..b7339c8 100644 --- a/odoo/Dockerfile +++ b/odoo/Dockerfile @@ -79,6 +79,7 @@ RUN curl -o odoo.deb -sSL http://nightly.odoo.com/${ODOO_VERSION}/nightly/deb/od # Copy entrypoint script and Odoo configuration file COPY ./entrypoint.sh / +RUN chmod +x ./entrypoint.sh COPY ./odoo.conf /etc/odoo/ # Set permissions and Mount /var/lib/odoo to allow restoring filestore and /mnt/extra-addons for users addons From 0c27c48afb455996cfde00edbb37faf09b9edd35 Mon Sep 17 00:00:00 2001 From: belloafeez Date: Fri, 2 Aug 2024 10:51:13 +0100 Subject: [PATCH 25/54] updated Signed-off-by: belloafeez --- odoo/Dockerfile | 2 ++ 1 file changed, 2 insertions(+) diff --git a/odoo/Dockerfile b/odoo/Dockerfile index b7339c8..58a92bc 100644 --- a/odoo/Dockerfile +++ b/odoo/Dockerfile @@ -97,6 +97,8 @@ ENV ODOO_RC /etc/odoo/odoo.conf COPY wait-for-psql.py /usr/local/bin/wait-for-psql.py +RUN chmod +x /usr/local/bin/wait-for-psql.py + # Set default user when running the container USER odoo From dd76041ff6189ff6043a4a0d36713b183a2a6d50 Mon Sep 17 00:00:00 2001 From: belloafeez Date: Fri, 2 Aug 2024 11:09:05 +0100 Subject: [PATCH 26/54] updated Signed-off-by: belloafeez --- odoo/Dockerfile | 107 +- odoo/Odoo.config | 16 - odoo/entrypoint.sh | 49 - odoo/extra-addons/openems/.gitignore | 3 - odoo/extra-addons/openems/__init__.py | 1 - odoo/extra-addons/openems/__manifest__.py | 40 - .../openems/controllers/__init__.py | 1 - .../openems/controllers/alerting.py | 86 - .../extra-addons/openems/controllers/const.py | 5 - .../openems/controllers/openems_backend.py | 276 --- .../openems/controllers/setup_protocol.py | 142 -- odoo/extra-addons/openems/controllers/user.py | 32 - .../openems/data/OpenEMS-Logo.jpg | Bin 152320 -> 0 bytes odoo/extra-addons/openems/data/demo.xml | 12 - .../openems/data/ir_config_parameter.xml | 9 - .../openems/data/res_partner_category.xml | 11 - odoo/extra-addons/openems/i18n/de.po | 1666 ----------------- odoo/extra-addons/openems/i18n/openems.pot | 1666 ----------------- .../openems/mail/openems/alerting_offline.xml | 275 --- .../mail/openems/alerting_sum_state.xml | 268 --- .../mail/openems/setup_protocol_customer.xml | 170 -- .../mail/openems/setup_protocol_installer.xml | 173 -- .../mail/openems/user_registration.xml | 197 -- .../migrations/16.0.1.0.1/post-migrate.py | 9 - .../migrations/16.0.1.0.1/pre-migrate.py | 7 - odoo/extra-addons/openems/models/__init__.py | 1 - odoo/extra-addons/openems/models/device.py | 321 ---- odoo/extra-addons/openems/models/partner.py | 12 - .../openems/models/setup_protocol.py | 49 - .../openems/models/stock_production_lot.py | 23 - odoo/extra-addons/openems/models/user.py | 37 - .../openems/report/setup_protocol.xml | 311 --- .../openems/security/ir.model.access.csv | 31 - .../extra-addons/openems/security/openems.xml | 54 - .../.setuptools-odoo-make-default-ignore | 2 - odoo/extra-addons/openems/setup/README | 2 - .../openems/static/description/icon.png | Bin 53271 -> 0 bytes .../openems/static/mail/OpenEMS-Logo.jpg | Bin 152320 -> 0 bytes odoo/extra-addons/openems/views/device.xml | 320 ---- odoo/extra-addons/openems/views/partner.xml | 28 - .../openems/views/setup_protocol.xml | 82 - .../views/stock_production_lot_views.xml | 13 - odoo/extra-addons/openems/views/user.xml | 25 - .../extra-addons/partner_firstname/README.rst | 146 -- .../partner_firstname/__init__.py | 2 - .../partner_firstname/__manifest__.py | 30 - .../partner_firstname/exceptions.py | 12 - odoo/extra-addons/partner_firstname/hooks.py | 9 - .../extra-addons/partner_firstname/i18n/am.po | 130 -- .../extra-addons/partner_firstname/i18n/ar.po | 131 -- .../extra-addons/partner_firstname/i18n/bg.po | 130 -- .../extra-addons/partner_firstname/i18n/bs.po | 131 -- .../extra-addons/partner_firstname/i18n/ca.po | 139 -- .../extra-addons/partner_firstname/i18n/cs.po | 130 -- .../extra-addons/partner_firstname/i18n/da.po | 135 -- .../extra-addons/partner_firstname/i18n/de.po | 136 -- .../partner_firstname/i18n/el_GR.po | 131 -- .../partner_firstname/i18n/en_GB.po | 131 -- .../extra-addons/partner_firstname/i18n/es.po | 136 -- .../partner_firstname/i18n/es_CR.po | 131 -- .../partner_firstname/i18n/es_EC.po | 131 -- .../partner_firstname/i18n/es_MX.po | 131 -- .../partner_firstname/i18n/es_VE.po | 131 -- .../extra-addons/partner_firstname/i18n/et.po | 130 -- .../extra-addons/partner_firstname/i18n/eu.po | 130 -- .../extra-addons/partner_firstname/i18n/fi.po | 130 -- .../extra-addons/partner_firstname/i18n/fr.po | 138 -- .../partner_firstname/i18n/fr_CA.po | 131 -- .../partner_firstname/i18n/fr_CH.po | 131 -- .../extra-addons/partner_firstname/i18n/gl.po | 130 -- .../extra-addons/partner_firstname/i18n/hr.po | 132 -- .../partner_firstname/i18n/hr_HR.po | 132 -- .../extra-addons/partner_firstname/i18n/hu.po | 138 -- .../extra-addons/partner_firstname/i18n/it.po | 136 -- .../extra-addons/partner_firstname/i18n/ja.po | 130 -- .../extra-addons/partner_firstname/i18n/lt.po | 131 -- .../extra-addons/partner_firstname/i18n/lv.po | 131 -- .../extra-addons/partner_firstname/i18n/mk.po | 130 -- .../extra-addons/partner_firstname/i18n/mn.po | 130 -- .../extra-addons/partner_firstname/i18n/nb.po | 131 -- .../partner_firstname/i18n/nb_NO.po | 131 -- .../extra-addons/partner_firstname/i18n/nl.po | 130 -- .../partner_firstname/i18n/nl_BE.po | 131 -- .../partner_firstname/i18n/nl_NL.po | 138 -- .../i18n/partner_firstname.pot | 124 -- .../extra-addons/partner_firstname/i18n/pl.po | 132 -- .../extra-addons/partner_firstname/i18n/pt.po | 130 -- .../partner_firstname/i18n/pt_BR.po | 138 -- .../partner_firstname/i18n/pt_PT.po | 131 -- .../extra-addons/partner_firstname/i18n/ro.po | 131 -- .../extra-addons/partner_firstname/i18n/ru.po | 132 -- .../extra-addons/partner_firstname/i18n/sk.po | 130 -- .../extra-addons/partner_firstname/i18n/sl.po | 131 -- .../partner_firstname/i18n/sr@latin.po | 132 -- .../extra-addons/partner_firstname/i18n/sv.po | 130 -- .../extra-addons/partner_firstname/i18n/th.po | 130 -- .../extra-addons/partner_firstname/i18n/tr.po | 130 -- .../partner_firstname/i18n/tr_TR.po | 131 -- .../extra-addons/partner_firstname/i18n/vi.po | 130 -- .../partner_firstname/i18n/zh_CN.po | 131 -- .../partner_firstname/i18n/zh_TW.po | 131 -- .../partner_firstname/models/__init__.py | 3 - .../models/base_config_settings.py | 71 - .../partner_firstname/models/res_partner.py | 270 --- .../partner_firstname/models/res_users.py | 49 - .../partner_firstname/readme/CONFIGURE.rst | 14 - .../partner_firstname/readme/CONTRIBUTORS.rst | 23 - .../partner_firstname/readme/DESCRIPTION.rst | 2 - .../partner_firstname/readme/ROADMAP.rst | 3 - .../partner_firstname/readme/USAGE.rst | 13 - .../static/description/icon.png | Bin 9455 -> 0 bytes .../static/description/index.html | 488 ----- .../partner_firstname/tests/__init__.py | 12 - .../partner_firstname/tests/base.py | 65 - .../tests/test_config_settings.py | 35 - .../partner_firstname/tests/test_copy.py | 95 - .../partner_firstname/tests/test_create.py | 79 - .../partner_firstname/tests/test_defaults.py | 64 - .../partner_firstname/tests/test_delete.py | 38 - .../partner_firstname/tests/test_empty.py | 73 - .../partner_firstname/tests/test_name.py | 119 -- .../partner_firstname/tests/test_order.py | 38 - .../tests/test_partner_form.py | 106 -- .../partner_firstname/tests/test_user_form.py | 51 - .../views/base_config_view.xml | 28 - .../partner_firstname/views/res_partner.xml | 105 -- .../partner_firstname/views/res_user.xml | 25 - odoo/extra-addons/readme.md | 1 - odoo/extra-addons/web_m2x_options/README.rst | 217 --- odoo/extra-addons/web_m2x_options/__init__.py | 1 - .../web_m2x_options/__manifest__.py | 21 - odoo/extra-addons/web_m2x_options/i18n/ar.po | 133 -- odoo/extra-addons/web_m2x_options/i18n/de.po | 159 -- odoo/extra-addons/web_m2x_options/i18n/es.po | 145 -- .../web_m2x_options/i18n/es_BO.po | 116 -- odoo/extra-addons/web_m2x_options/i18n/fi.po | 132 -- odoo/extra-addons/web_m2x_options/i18n/fr.po | 158 -- odoo/extra-addons/web_m2x_options/i18n/hr.po | 150 -- odoo/extra-addons/web_m2x_options/i18n/it.po | 133 -- odoo/extra-addons/web_m2x_options/i18n/nl.po | 162 -- .../web_m2x_options/i18n/nl_NL.po | 125 -- .../web_m2x_options/i18n/pt_BR.po | 156 -- odoo/extra-addons/web_m2x_options/i18n/sl.po | 133 -- odoo/extra-addons/web_m2x_options/i18n/tr.po | 132 -- .../web_m2x_options/i18n/web_m2x_options.pot | 115 -- .../web_m2x_options/i18n/zh_CN.po | 153 -- .../web_m2x_options/models/__init__.py | 2 - .../models/ir_config_parameter.py | 18 - .../web_m2x_options/models/ir_http.py | 11 - .../web_m2x_options/readme/CONTRIBUTORS.rst | 16 - .../web_m2x_options/readme/CREDITS.rst | 1 - .../web_m2x_options/readme/DESCRIPTION.rst | 10 - .../web_m2x_options/readme/ROADMAP.rst | 6 - .../web_m2x_options/readme/USAGE.rst | 95 - .../static/description/icon.png | Bin 9455 -> 0 bytes .../static/description/index.html | 412 ---- .../static/src/components/base.xml | 46 - .../static/src/components/form.esm.js | 404 ---- .../src/components/relational_utils.esm.js | 221 --- .../web_m2x_options/tests/__init__.py | 2 - .../tests/test_ir_config_parameter.py | 28 - odoo/odoo.conf | 37 - odoo/wait-for-psql.py | 32 - 163 files changed, 4 insertions(+), 19258 deletions(-) delete mode 100644 odoo/Odoo.config delete mode 100644 odoo/entrypoint.sh delete mode 100644 odoo/extra-addons/openems/.gitignore delete mode 100644 odoo/extra-addons/openems/__init__.py delete mode 100644 odoo/extra-addons/openems/__manifest__.py delete mode 100644 odoo/extra-addons/openems/controllers/__init__.py delete mode 100644 odoo/extra-addons/openems/controllers/alerting.py delete mode 100644 odoo/extra-addons/openems/controllers/const.py delete mode 100644 odoo/extra-addons/openems/controllers/openems_backend.py delete mode 100644 odoo/extra-addons/openems/controllers/setup_protocol.py delete mode 100644 odoo/extra-addons/openems/controllers/user.py delete mode 100644 odoo/extra-addons/openems/data/OpenEMS-Logo.jpg delete mode 100644 odoo/extra-addons/openems/data/demo.xml delete mode 100644 odoo/extra-addons/openems/data/ir_config_parameter.xml delete mode 100644 odoo/extra-addons/openems/data/res_partner_category.xml delete mode 100644 odoo/extra-addons/openems/i18n/de.po delete mode 100644 odoo/extra-addons/openems/i18n/openems.pot delete mode 100644 odoo/extra-addons/openems/mail/openems/alerting_offline.xml delete mode 100644 odoo/extra-addons/openems/mail/openems/alerting_sum_state.xml delete mode 100644 odoo/extra-addons/openems/mail/openems/setup_protocol_customer.xml delete mode 100644 odoo/extra-addons/openems/mail/openems/setup_protocol_installer.xml delete mode 100644 odoo/extra-addons/openems/mail/openems/user_registration.xml delete mode 100644 odoo/extra-addons/openems/migrations/16.0.1.0.1/post-migrate.py delete mode 100644 odoo/extra-addons/openems/migrations/16.0.1.0.1/pre-migrate.py delete mode 100644 odoo/extra-addons/openems/models/__init__.py delete mode 100644 odoo/extra-addons/openems/models/device.py delete mode 100644 odoo/extra-addons/openems/models/partner.py delete mode 100644 odoo/extra-addons/openems/models/setup_protocol.py delete mode 100644 odoo/extra-addons/openems/models/stock_production_lot.py delete mode 100644 odoo/extra-addons/openems/models/user.py delete mode 100644 odoo/extra-addons/openems/report/setup_protocol.xml delete mode 100644 odoo/extra-addons/openems/security/ir.model.access.csv delete mode 100644 odoo/extra-addons/openems/security/openems.xml delete mode 100644 odoo/extra-addons/openems/setup/.setuptools-odoo-make-default-ignore delete mode 100644 odoo/extra-addons/openems/setup/README delete mode 100644 odoo/extra-addons/openems/static/description/icon.png delete mode 100644 odoo/extra-addons/openems/static/mail/OpenEMS-Logo.jpg delete mode 100644 odoo/extra-addons/openems/views/device.xml delete mode 100644 odoo/extra-addons/openems/views/partner.xml delete mode 100644 odoo/extra-addons/openems/views/setup_protocol.xml delete mode 100644 odoo/extra-addons/openems/views/stock_production_lot_views.xml delete mode 100644 odoo/extra-addons/openems/views/user.xml delete mode 100644 odoo/extra-addons/partner_firstname/README.rst delete mode 100644 odoo/extra-addons/partner_firstname/__init__.py delete mode 100644 odoo/extra-addons/partner_firstname/__manifest__.py delete mode 100644 odoo/extra-addons/partner_firstname/exceptions.py delete mode 100644 odoo/extra-addons/partner_firstname/hooks.py delete mode 100644 odoo/extra-addons/partner_firstname/i18n/am.po delete mode 100644 odoo/extra-addons/partner_firstname/i18n/ar.po delete mode 100644 odoo/extra-addons/partner_firstname/i18n/bg.po delete mode 100644 odoo/extra-addons/partner_firstname/i18n/bs.po delete mode 100644 odoo/extra-addons/partner_firstname/i18n/ca.po delete mode 100644 odoo/extra-addons/partner_firstname/i18n/cs.po delete mode 100644 odoo/extra-addons/partner_firstname/i18n/da.po delete mode 100644 odoo/extra-addons/partner_firstname/i18n/de.po delete mode 100644 odoo/extra-addons/partner_firstname/i18n/el_GR.po delete mode 100644 odoo/extra-addons/partner_firstname/i18n/en_GB.po delete mode 100644 odoo/extra-addons/partner_firstname/i18n/es.po delete mode 100644 odoo/extra-addons/partner_firstname/i18n/es_CR.po delete mode 100644 odoo/extra-addons/partner_firstname/i18n/es_EC.po delete mode 100644 odoo/extra-addons/partner_firstname/i18n/es_MX.po delete mode 100644 odoo/extra-addons/partner_firstname/i18n/es_VE.po delete mode 100644 odoo/extra-addons/partner_firstname/i18n/et.po delete mode 100644 odoo/extra-addons/partner_firstname/i18n/eu.po delete mode 100644 odoo/extra-addons/partner_firstname/i18n/fi.po delete mode 100644 odoo/extra-addons/partner_firstname/i18n/fr.po delete mode 100644 odoo/extra-addons/partner_firstname/i18n/fr_CA.po delete mode 100644 odoo/extra-addons/partner_firstname/i18n/fr_CH.po delete mode 100644 odoo/extra-addons/partner_firstname/i18n/gl.po delete mode 100644 odoo/extra-addons/partner_firstname/i18n/hr.po delete mode 100644 odoo/extra-addons/partner_firstname/i18n/hr_HR.po delete mode 100644 odoo/extra-addons/partner_firstname/i18n/hu.po delete mode 100644 odoo/extra-addons/partner_firstname/i18n/it.po delete mode 100644 odoo/extra-addons/partner_firstname/i18n/ja.po delete mode 100644 odoo/extra-addons/partner_firstname/i18n/lt.po delete mode 100644 odoo/extra-addons/partner_firstname/i18n/lv.po delete mode 100644 odoo/extra-addons/partner_firstname/i18n/mk.po delete mode 100644 odoo/extra-addons/partner_firstname/i18n/mn.po delete mode 100644 odoo/extra-addons/partner_firstname/i18n/nb.po delete mode 100644 odoo/extra-addons/partner_firstname/i18n/nb_NO.po delete mode 100644 odoo/extra-addons/partner_firstname/i18n/nl.po delete mode 100644 odoo/extra-addons/partner_firstname/i18n/nl_BE.po delete mode 100644 odoo/extra-addons/partner_firstname/i18n/nl_NL.po delete mode 100644 odoo/extra-addons/partner_firstname/i18n/partner_firstname.pot delete mode 100644 odoo/extra-addons/partner_firstname/i18n/pl.po delete mode 100644 odoo/extra-addons/partner_firstname/i18n/pt.po delete mode 100644 odoo/extra-addons/partner_firstname/i18n/pt_BR.po delete mode 100644 odoo/extra-addons/partner_firstname/i18n/pt_PT.po delete mode 100644 odoo/extra-addons/partner_firstname/i18n/ro.po delete mode 100644 odoo/extra-addons/partner_firstname/i18n/ru.po delete mode 100644 odoo/extra-addons/partner_firstname/i18n/sk.po delete mode 100644 odoo/extra-addons/partner_firstname/i18n/sl.po delete mode 100644 odoo/extra-addons/partner_firstname/i18n/sr@latin.po delete mode 100644 odoo/extra-addons/partner_firstname/i18n/sv.po delete mode 100644 odoo/extra-addons/partner_firstname/i18n/th.po delete mode 100644 odoo/extra-addons/partner_firstname/i18n/tr.po delete mode 100644 odoo/extra-addons/partner_firstname/i18n/tr_TR.po delete mode 100644 odoo/extra-addons/partner_firstname/i18n/vi.po delete mode 100644 odoo/extra-addons/partner_firstname/i18n/zh_CN.po delete mode 100644 odoo/extra-addons/partner_firstname/i18n/zh_TW.po delete mode 100644 odoo/extra-addons/partner_firstname/models/__init__.py delete mode 100644 odoo/extra-addons/partner_firstname/models/base_config_settings.py delete mode 100644 odoo/extra-addons/partner_firstname/models/res_partner.py delete mode 100644 odoo/extra-addons/partner_firstname/models/res_users.py delete mode 100644 odoo/extra-addons/partner_firstname/readme/CONFIGURE.rst delete mode 100644 odoo/extra-addons/partner_firstname/readme/CONTRIBUTORS.rst delete mode 100644 odoo/extra-addons/partner_firstname/readme/DESCRIPTION.rst delete mode 100644 odoo/extra-addons/partner_firstname/readme/ROADMAP.rst delete mode 100644 odoo/extra-addons/partner_firstname/readme/USAGE.rst delete mode 100644 odoo/extra-addons/partner_firstname/static/description/icon.png delete mode 100644 odoo/extra-addons/partner_firstname/static/description/index.html delete mode 100644 odoo/extra-addons/partner_firstname/tests/__init__.py delete mode 100644 odoo/extra-addons/partner_firstname/tests/base.py delete mode 100644 odoo/extra-addons/partner_firstname/tests/test_config_settings.py delete mode 100644 odoo/extra-addons/partner_firstname/tests/test_copy.py delete mode 100644 odoo/extra-addons/partner_firstname/tests/test_create.py delete mode 100644 odoo/extra-addons/partner_firstname/tests/test_defaults.py delete mode 100644 odoo/extra-addons/partner_firstname/tests/test_delete.py delete mode 100644 odoo/extra-addons/partner_firstname/tests/test_empty.py delete mode 100644 odoo/extra-addons/partner_firstname/tests/test_name.py delete mode 100644 odoo/extra-addons/partner_firstname/tests/test_order.py delete mode 100644 odoo/extra-addons/partner_firstname/tests/test_partner_form.py delete mode 100644 odoo/extra-addons/partner_firstname/tests/test_user_form.py delete mode 100644 odoo/extra-addons/partner_firstname/views/base_config_view.xml delete mode 100644 odoo/extra-addons/partner_firstname/views/res_partner.xml delete mode 100644 odoo/extra-addons/partner_firstname/views/res_user.xml delete mode 100644 odoo/extra-addons/readme.md delete mode 100644 odoo/extra-addons/web_m2x_options/README.rst delete mode 100644 odoo/extra-addons/web_m2x_options/__init__.py delete mode 100644 odoo/extra-addons/web_m2x_options/__manifest__.py delete mode 100644 odoo/extra-addons/web_m2x_options/i18n/ar.po delete mode 100644 odoo/extra-addons/web_m2x_options/i18n/de.po delete mode 100644 odoo/extra-addons/web_m2x_options/i18n/es.po delete mode 100644 odoo/extra-addons/web_m2x_options/i18n/es_BO.po delete mode 100644 odoo/extra-addons/web_m2x_options/i18n/fi.po delete mode 100644 odoo/extra-addons/web_m2x_options/i18n/fr.po delete mode 100644 odoo/extra-addons/web_m2x_options/i18n/hr.po delete mode 100644 odoo/extra-addons/web_m2x_options/i18n/it.po delete mode 100644 odoo/extra-addons/web_m2x_options/i18n/nl.po delete mode 100644 odoo/extra-addons/web_m2x_options/i18n/nl_NL.po delete mode 100644 odoo/extra-addons/web_m2x_options/i18n/pt_BR.po delete mode 100644 odoo/extra-addons/web_m2x_options/i18n/sl.po delete mode 100644 odoo/extra-addons/web_m2x_options/i18n/tr.po delete mode 100644 odoo/extra-addons/web_m2x_options/i18n/web_m2x_options.pot delete mode 100644 odoo/extra-addons/web_m2x_options/i18n/zh_CN.po delete mode 100644 odoo/extra-addons/web_m2x_options/models/__init__.py delete mode 100644 odoo/extra-addons/web_m2x_options/models/ir_config_parameter.py delete mode 100644 odoo/extra-addons/web_m2x_options/models/ir_http.py delete mode 100644 odoo/extra-addons/web_m2x_options/readme/CONTRIBUTORS.rst delete mode 100644 odoo/extra-addons/web_m2x_options/readme/CREDITS.rst delete mode 100644 odoo/extra-addons/web_m2x_options/readme/DESCRIPTION.rst delete mode 100644 odoo/extra-addons/web_m2x_options/readme/ROADMAP.rst delete mode 100644 odoo/extra-addons/web_m2x_options/readme/USAGE.rst delete mode 100644 odoo/extra-addons/web_m2x_options/static/description/icon.png delete mode 100644 odoo/extra-addons/web_m2x_options/static/description/index.html delete mode 100644 odoo/extra-addons/web_m2x_options/static/src/components/base.xml delete mode 100644 odoo/extra-addons/web_m2x_options/static/src/components/form.esm.js delete mode 100644 odoo/extra-addons/web_m2x_options/static/src/components/relational_utils.esm.js delete mode 100644 odoo/extra-addons/web_m2x_options/tests/__init__.py delete mode 100644 odoo/extra-addons/web_m2x_options/tests/test_ir_config_parameter.py delete mode 100644 odoo/odoo.conf delete mode 100644 odoo/wait-for-psql.py diff --git a/odoo/Dockerfile b/odoo/Dockerfile index 58a92bc..23bcdbd 100644 --- a/odoo/Dockerfile +++ b/odoo/Dockerfile @@ -1,106 +1,7 @@ -FROM debian:bullseye-slim +# Use Odoo 16.0 as the base image +FROM odoo:16.0 -SHELL ["/bin/bash", "-xo", "pipefail", "-c"] -# Generate locale C.UTF-8 for postgres and general locale data -ENV LANG C.UTF-8 - -# Retrieve the target architecture to install the correct wkhtmltopdf package -ARG TARGETARCH - -# Install some deps, lessc and less-plugin-clean-css, and wkhtmltopdf -RUN apt-get update && \ - apt-get install -y --no-install-recommends \ - ca-certificates \ - curl \ - dirmngr \ - fonts-noto-cjk \ - gnupg \ - libssl-dev \ - node-less \ - npm \ - python3-magic \ - python3-num2words \ - python3-odf \ - python3-pdfminer \ - python3-pip \ - python3-phonenumbers \ - python3-pyldap \ - python3-qrcode \ - python3-renderpm \ - python3-setuptools \ - python3-slugify \ - python3-vobject \ - python3-watchdog \ - python3-xlrd \ - python3-xlwt \ - xz-utils && \ - if [ -z "${TARGETARCH}" ]; then \ - TARGETARCH="$(dpkg --print-architecture)"; \ - fi; \ - WKHTMLTOPDF_ARCH=${TARGETARCH} && \ - case ${TARGETARCH} in \ - "amd64") WKHTMLTOPDF_ARCH=amd64 && WKHTMLTOPDF_SHA=9df8dd7b1e99782f1cfa19aca665969bbd9cc159 ;; \ - "arm64") WKHTMLTOPDF_SHA=58c84db46b11ba0e14abb77a32324b1c257f1f22 ;; \ - "ppc64le" | "ppc64el") WKHTMLTOPDF_ARCH=ppc64el && WKHTMLTOPDF_SHA=7ed8f6dcedf5345a3dd4eeb58dc89704d862f9cd ;; \ - esac \ - && curl -o wkhtmltox.deb -sSL https://github.com/wkhtmltopdf/packaging/releases/download/0.12.6.1-3/wkhtmltox_0.12.6.1-3.bullseye_${WKHTMLTOPDF_ARCH}.deb \ - && echo ${WKHTMLTOPDF_SHA} wkhtmltox.deb | sha1sum -c - \ - && apt-get install -y --no-install-recommends ./wkhtmltox.deb \ - && rm -rf /var/lib/apt/lists/* wkhtmltox.deb - -# install latest postgresql-client -RUN echo 'deb http://apt.postgresql.org/pub/repos/apt/ bullseye-pgdg main' > /etc/apt/sources.list.d/pgdg.list \ - && GNUPGHOME="$(mktemp -d)" \ - && export GNUPGHOME \ - && repokey='B97B0AFCAA1A47F044F244A07FCC7D46ACCC4CF8' \ - && gpg --batch --keyserver keyserver.ubuntu.com --recv-keys "${repokey}" \ - && gpg --batch --armor --export "${repokey}" > /etc/apt/trusted.gpg.d/pgdg.gpg.asc \ - && gpgconf --kill all \ - && rm -rf "$GNUPGHOME" \ - && apt-get update \ - && apt-get install --no-install-recommends -y postgresql-client \ - && rm -f /etc/apt/sources.list.d/pgdg.list \ - && rm -rf /var/lib/apt/lists/* - -# Install rtlcss (on Debian buster) -RUN npm install -g rtlcss - -# Install Odoo -ENV ODOO_VERSION 16.0 -ARG ODOO_RELEASE=20240624 -ARG ODOO_SHA=a51d6f097b24096d38959f4cd97ae5fb2cd2807b -RUN curl -o odoo.deb -sSL http://nightly.odoo.com/${ODOO_VERSION}/nightly/deb/odoo_${ODOO_VERSION}.${ODOO_RELEASE}_all.deb \ - && echo "${ODOO_SHA} odoo.deb" | sha1sum -c - \ - && apt-get update \ - && apt-get -y install --no-install-recommends ./odoo.deb \ - && rm -rf /var/lib/apt/lists/* odoo.deb - -# Copy entrypoint script and Odoo configuration file -COPY ./entrypoint.sh / -RUN chmod +x ./entrypoint.sh -COPY ./odoo.conf /etc/odoo/ - -# Set permissions and Mount /var/lib/odoo to allow restoring filestore and /mnt/extra-addons for users addons -RUN chown odoo /etc/odoo/odoo.conf \ - && mkdir -p /mnt/extra-addons \ - && chown -R odoo /mnt/extra-addons -VOLUME ["/var/lib/odoo", "/mnt/extra-addons"] - -COPY ./extra-addons /mnt/extra-addons -# Expose Odoo services -EXPOSE 8069 8071 8072 - -# Set the default config file -ENV ODOO_RC /etc/odoo/odoo.conf - -COPY wait-for-psql.py /usr/local/bin/wait-for-psql.py - -RUN chmod +x /usr/local/bin/wait-for-psql.py - -# Set default user when running the container -USER odoo - -ENTRYPOINT ["/entrypoint.sh"] -CMD ["odoo"] \ No newline at end of file +# Expose port 8069 for Odoo web interface +EXPOSE 8069 \ No newline at end of file diff --git a/odoo/Odoo.config b/odoo/Odoo.config deleted file mode 100644 index 75705c9..0000000 --- a/odoo/Odoo.config +++ /dev/null @@ -1,16 +0,0 @@ -# Place in openems-backend/config.d/Metadata -:org.apache.felix.configadmin.revision:=L"2" -database="postgres" -debugMode="ON" -odooHost="localhost" -odooPassword="admin" -odooPort=I"8069" -odooProtocol="HTTP" -odooUid=I"2" -pgConnectionPoolSize=I"40" -pgHost="localhost" -pgPassword="odoo" -pgPort=I"5432" -pgUser="odoo" -poolSize=I"30" -service.pid="Metadata.Odoo" \ No newline at end of file diff --git a/odoo/entrypoint.sh b/odoo/entrypoint.sh deleted file mode 100644 index f802bcb..0000000 --- a/odoo/entrypoint.sh +++ /dev/null @@ -1,49 +0,0 @@ -#!/bin/bash - -set -e - -if [ -v PASSWORD_FILE ]; then - PASSWORD="$(< $PASSWORD_FILE)" -fi - -# set the postgres database host, port, user and password according to the environment -# and pass them as arguments to the odoo process if not present in the config file -: ${HOST:=${DB_PORT_5432_TCP_ADDR:='db'}} -: ${PORT:=${DB_PORT_5432_TCP_PORT:=5432}} -: ${USER:=${DB_ENV_POSTGRES_USER:=${POSTGRES_USER:='odoo'}}} -: ${PASSWORD:=${DB_ENV_POSTGRES_PASSWORD:=${POSTGRES_PASSWORD:='odoo'}}} - -DB_ARGS=() -function check_config() { - param="$1" - value="$2" - if grep -q -E "^\s*\b${param}\b\s*=" "$ODOO_RC" ; then - value=$(grep -E "^\s*\b${param}\b\s*=" "$ODOO_RC" |cut -d " " -f3|sed 's/["\n\r]//g') - fi; - DB_ARGS+=("--${param}") - DB_ARGS+=("${value}") -} -check_config "db_host" "$HOST" -check_config "db_port" "$PORT" -check_config "db_user" "$USER" -check_config "db_password" "$PASSWORD" - -case "$1" in - -- | odoo) - shift - if [[ "$1" == "scaffold" ]] ; then - exec odoo "$@" - else - wait-for-psql.py ${DB_ARGS[@]} --timeout=30 - exec odoo "$@" "${DB_ARGS[@]}" - fi - ;; - -*) - wait-for-psql.py ${DB_ARGS[@]} --timeout=30 - exec odoo "$@" "${DB_ARGS[@]}" - ;; - *) - exec "$@" -esac - -exit 1 diff --git a/odoo/extra-addons/openems/.gitignore b/odoo/extra-addons/openems/.gitignore deleted file mode 100644 index e41d5e2..0000000 --- a/odoo/extra-addons/openems/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ -.swp -.swo -**/__pycache__ diff --git a/odoo/extra-addons/openems/__init__.py b/odoo/extra-addons/openems/__init__.py deleted file mode 100644 index 72d3ea6..0000000 --- a/odoo/extra-addons/openems/__init__.py +++ /dev/null @@ -1 +0,0 @@ -from . import controllers, models diff --git a/odoo/extra-addons/openems/__manifest__.py b/odoo/extra-addons/openems/__manifest__.py deleted file mode 100644 index 232ebf1..0000000 --- a/odoo/extra-addons/openems/__manifest__.py +++ /dev/null @@ -1,40 +0,0 @@ -{ - "name": "OpenEMS", - "summary": "Everything related to OpenEMS (Open Energy Management System)", - "version": "16.0.1.0.1", - "author": "OpenEMS Association e.V.", - "maintainer": "OpenEMS Association e.V.", - "contributors": [ - "Stefan Feilmeier " - "Maximilian Lang " - ], - "website": "https://openems.io", - "license": "AGPL-3", - "category": "Specific Industry Applications", - "depends": ["base", "web", "mail", "crm", "resource", "stock", "web_m2x_options", "partner_firstname"], - "data": [ - "data/ir_config_parameter.xml", - "data/res_partner_category.xml", - "security/openems.xml", - "security/ir.model.access.csv", - "report/setup_protocol.xml", - "views/device.xml", - "views/partner.xml", - "views/setup_protocol.xml", - "views/user.xml", - "views/stock_production_lot_views.xml", - "mail/openems/alerting_offline.xml", - "mail/openems/alerting_sum_state.xml", - "mail/openems/setup_protocol_customer.xml", - "mail/openems/setup_protocol_installer.xml", - "mail/openems/user_registration.xml", - ], - "demo": ["data/demo.xml"], - "js": [], - "css": [], - "qweb": [], - "images": [], - "test": [], - "installable": True, - "application": True, -} diff --git a/odoo/extra-addons/openems/controllers/__init__.py b/odoo/extra-addons/openems/controllers/__init__.py deleted file mode 100644 index 3e863cd..0000000 --- a/odoo/extra-addons/openems/controllers/__init__.py +++ /dev/null @@ -1 +0,0 @@ -from . import openems_backend, setup_protocol, user, alerting diff --git a/odoo/extra-addons/openems/controllers/alerting.py b/odoo/extra-addons/openems/controllers/alerting.py deleted file mode 100644 index 7a848f2..0000000 --- a/odoo/extra-addons/openems/controllers/alerting.py +++ /dev/null @@ -1,86 +0,0 @@ -import logging -from datetime import datetime -from enum import Enum - -from odoo import http -from odoo.http import request - -class SumState(Enum): - FAULT = 0 - WARNING = 1 - -class Message: - sentAt: datetime - edgeId: str - userIds: list[int] - - def __init__(self, sentAt: datetime, edgeId: str, userIds: list[int]) -> None: - self.sentAt = sentAt - self.edgeId = edgeId - self.userIds = userIds - -class SumStateMessage(Message): - state: SumState - - def __init__(self, sentAt: datetime, edgeId: str, userIds: list[int], state: SumState) -> None: - super().__init__(sentAt, edgeId, userIds) - self.state = state - -class Alerting(http.Controller): - __logger = logging.getLogger("Alerting") - - @http.route("/openems_backend/mail/alerting_sum_state", type="json", auth="user") - def sum_state_alerting(self, sentAt: str, params: list[dict]): - msgs = self.__get_sum_state_params(sentAt, params) - update_func = lambda role, at: { role.write({"sum_state_last_notification": at})} - - if len(msgs) == 0: - self.__logger.error("Scheduled SumState-Alerting-Mail without any recipients!!!") - - template = request.env.ref('openems.alerting_sum_state') - for msg in msgs: - self.__send_mails(template, msg, update_func) - - return {} - - @http.route("/openems_backend/mail/alerting_offline", type="json", auth="user") - def offline_alerting(self, sentAt: str, params: list[dict]): - msgs = self.__get_offline_params(sentAt, params) - update_func = lambda role, at: { role.write({"offline_last_notification": at})} - - template = request.env.ref("openems.alerting_offline") - for msg in msgs: - self.__send_mails(template, msg, update_func) - - return {} - - def __get_offline_params(self, sentAt, params) -> list[Message]: - msgs = list() - sent = datetime.strptime(sentAt, "%Y-%m-%d %H:%M:%S") - for param in params: - edgeId = param["edgeId"] - recipients = param["recipients"] - msgs.append(Message(sent, edgeId, recipients)); - return msgs - - def __get_sum_state_params(self, sentAt, params) -> list[SumStateMessage]: - msgs = list() - sent = datetime.strptime(sentAt, "%Y-%m-%d %H:%M:%S") - for param in params: - edgeId = param["edgeId"] - recipients = param["recipients"] - state = param["state"] - msgs.append(SumStateMessage(sent, edgeId, recipients, state)); - return msgs - - def __send_mails(self, template, msg: Message, update_func): - roles = http.request.env['openems.alerting'].search( - [('user_id','in',msg.userIds),('device_id','=',msg.edgeId)] - ) - - for role in roles: - try: - template.send_mail(res_id=role.id, force_send=True) - update_func(role, msg.sentAt) - except Exception as err: - self.__logger.error("[" + str(err) + "] Unable to send template[" + str(template.name) +"] to edgeUser[user=" + str(role.id) + ", edge=" + str(msg.edgeId)+ "]") \ No newline at end of file diff --git a/odoo/extra-addons/openems/controllers/const.py b/odoo/extra-addons/openems/controllers/const.py deleted file mode 100644 index c6fbc01..0000000 --- a/odoo/extra-addons/openems/controllers/const.py +++ /dev/null @@ -1,5 +0,0 @@ -from odoo.modules.module import get_module_resource - -import base64 - -OPENEMS_LOGO_BASE64 = base64.b64encode(open(get_module_resource('openems', 'data', 'OpenEMS-Logo.jpg') , "rb").read()) \ No newline at end of file diff --git a/odoo/extra-addons/openems/controllers/openems_backend.py b/odoo/extra-addons/openems/controllers/openems_backend.py deleted file mode 100644 index d0dcb80..0000000 --- a/odoo/extra-addons/openems/controllers/openems_backend.py +++ /dev/null @@ -1,276 +0,0 @@ -from odoo import http - - -class OpenemsBackend(http.Controller): - @http.route("/openems_backend/info", auth="user", type="json") - def index(self): - # Get user - user_id = http.request.env.context.get("uid") - res_users = http.request.env["res.users"].sudo() - user_rec = res_users.search_read( - [("id", "=", user_id)], - ["login", "name", "groups_id", "global_role", "openems_language"], - )[0] - res_users.browse([user_id]) - - # Get res group model - res_groups_model = http.request.env["res.groups"].sudo() - - # Get Manager and Reader group - manager_group = res_groups_model.env.ref("openems.group_openems_manager") - reader_group = res_groups_model.env.ref("openems.group_openems_reader") - - manager_group_id = manager_group["id"] - reader_group_id = reader_group["id"] - - # Get user attributes - global_role = user_rec["global_role"] - if manager_group_id in user_rec["groups_id"]: - # Manager group - global_role = "admin" - - # return empty device (use pagination) list if user is manager or reader - if manager_group_id in user_rec["groups_id"] or reader_group_id in user_rec["groups_id"]: - return { - "user": { - "id": user_rec["id"], - "login": user_rec["login"], - "name": user_rec["name"], - "global_role": global_role, - "language": user_rec["openems_language"], - "has_multiple_edges": True - }, - "devices": [], - } - - # Get specific Device roles - device_user_role_model = http.request.env["openems.device_user_role"] - user_role_ids = device_user_role_model.search_read( - [("user_id", "=", user_id)], ["id", "role"] - ) - - # Get Devices - device_model = http.request.env["openems.device"] - devices = device_model.search_read( - [], ["id", "name", "user_role_ids", "comment", "producttype", - "lastmessage", "first_setup_protocol_date", "openems_sum_state_level"] - ) - - devs = [] - for device_rec in devices: - # Set user role per group - role = "guest" - if manager_group_id in user_rec["groups_id"]: - # Manager group - role = "admin" - elif reader_group_id in user_rec["groups_id"]: - # Reader group - role = "guest" - - # Set specific user role - for device_role_id in device_rec["user_role_ids"]: - for user_role_id in user_role_ids: - if device_role_id == user_role_id["id"]: - role = user_role_id["role"] - - # Prepare result - dev = { - "id": device_rec["id"], - "name": device_rec["name"], - "comment": device_rec["comment"], - "producttype": device_rec["producttype"], - "role": role, - "lastmessage": device_rec["lastmessage"], - "openems_sum_state_level": device_rec["openems_sum_state_level"] - } - - if device_rec["first_setup_protocol_date"]: - dev["first_setup_protocol_date"] = device_rec[ - "first_setup_protocol_date" - ] - - devs.append(dev) - - return { - "user": { - "id": user_rec["id"], - "login": user_rec["login"], - "name": user_rec["name"], - "global_role": global_role, - "language": user_rec["openems_language"], - "has_multiple_edges": len(devs) > 1 - }, - "devices": devs, - } - - @http.route("/openems_backend/get_edge_with_role", auth="user", type="json") - def get_edge_with_role(self, edge_id: str): - user_id = http.request.env.context.get("uid") - res_users = http.request.env["res.users"].sudo() - user_rec = res_users.search_read( - [("id", "=", user_id)], - ["login", "name", "groups_id"], - )[0] - - # Get res group model - res_groups_model = http.request.env["res.groups"].sudo() - - # Get Manager and Reader group - manager_group = res_groups_model.env.ref("openems.group_openems_manager") - reader_group = res_groups_model.env.ref("openems.group_openems_reader") - - manager_group_id = manager_group["id"] - reader_group_id = reader_group["id"] - - # get devices for which the user has permissions - device_model = http.request.env["openems.device"] - devices = device_model.search_read( - [("name", "=", edge_id)], - ["id", "name", "comment", "producttype", "lastmessage", "first_setup_protocol_date", "openems_sum_state_level"]) - - if len(devices) != 1: - return {} - - device = devices[0] - - # Get specific Device roles - device_user_role_model = http.request.env["openems.device_user_role"] - device_user_roles = device_user_role_model.search_read( - [("user_id", "=", user_id), - ("device_id", "=", device["id"])], ["id", "role"] - ) - - # Set user role per group - role = "guest" - if manager_group_id in user_rec["groups_id"]: - # Manager group - role = "admin" - elif reader_group_id in user_rec["groups_id"]: - # Reader group - role = "guest" - - # Set specific user role - if len(device_user_roles) > 0: - role = device_user_roles[0]["role"] - - dev = { - "id": device["id"], - "name": device["name"], - "comment": device["comment"], - "producttype": device["producttype"], - "role": role, - "lastmessage": device["lastmessage"], - "openems_sum_state_level": device["openems_sum_state_level"] - } - if device["first_setup_protocol_date"]: - dev["first_setup_protocol_date"] = device["first_setup_protocol_date"] - - return dev - - @http.route("/openems_backend/get_edges", auth="user", type="json") - def get_edges(self, limit, page, query=None, searchParams=None): - # Get user - user_id = http.request.env.context.get("uid") - res_users = http.request.env["res.users"].sudo() - user_rec = res_users.search_read( - [("id", "=", user_id)], - ["login", "name", "groups_id", "global_role"], - )[0] - - # Get res group model - res_groups_model = http.request.env["res.groups"].sudo() - - # Get Manager and Reader group - manager_group = res_groups_model.env.ref("openems.group_openems_manager") - reader_group = res_groups_model.env.ref("openems.group_openems_reader") - - manager_group_id = manager_group["id"] - reader_group_id = reader_group["id"] - - # Get specific Device roles - device_user_role_model = http.request.env["openems.device_user_role"] - user_role_ids = device_user_role_model.search_read( - [("user_id", "=", user_id)], ["id", "role"] - ) - - domains = [] - logical_operators = [] - additional_domains = [] - if query: - logical_operators.extend(['|', '|']) - domains = [ - ("name", "ilike", query), - ("comment", "ilike", query), - ("producttype", "ilike", query)] - - if searchParams: - if searchParams.get("producttype"): - additional_domains.append( - ("producttype", "in", searchParams.get("producttype"))) - - if searchParams.get("sumState"): - sum_states = list(map(lambda s: s.lower(), searchParams.get("sumState"))) - additional_domains.append( - ("openems_sum_state_level", "in", sum_states)) - - if "isOnline" in searchParams: - additional_domains.append( - ("openems_is_connected", "=", searchParams.get("isOnline"))) - - if len(additional_domains) > 1: - for _ in range(len(additional_domains) - 1): - logical_operators.insert(0, '&') - - # insert 'and' if both are not 'None' - if query and searchParams: - logical_operators.insert(0, '&') - - domains.extend(additional_domains) - logical_operators.extend(domains) - - # Get Devices - device_model = http.request.env["openems.device"] - devices = device_model.search_read( - logical_operators, - ["id", "name", "user_role_ids", "comment", "producttype", - "lastmessage", "first_setup_protocol_date", "openems_sum_state_level"], - limit=limit, offset=(page * limit) - ) - devs = [] - for device_rec in devices: - # Set user role per group - role = "guest" - if manager_group_id in user_rec["groups_id"]: - # Manager group - role = "admin" - elif reader_group_id in user_rec["groups_id"]: - # Reader group - role = "guest" - - # Set specific user role - for device_role_id in device_rec["user_role_ids"]: - for user_role_id in user_role_ids: - if device_role_id == user_role_id["id"]: - role = user_role_id["role"] - - # Prepare result - dev = { - "id": device_rec["id"], - "name": device_rec["name"], - "comment": device_rec["comment"], - "producttype": device_rec["producttype"], - "role": role, - "lastmessage": device_rec["lastmessage"], - "openems_sum_state_level": device_rec["openems_sum_state_level"] - } - - if device_rec["first_setup_protocol_date"]: - dev["first_setup_protocol_date"] = device_rec[ - "first_setup_protocol_date" - ] - - devs.append(dev) - - return { - "devices": devs, - } diff --git a/odoo/extra-addons/openems/controllers/setup_protocol.py b/odoo/extra-addons/openems/controllers/setup_protocol.py deleted file mode 100644 index d64b18e..0000000 --- a/odoo/extra-addons/openems/controllers/setup_protocol.py +++ /dev/null @@ -1,142 +0,0 @@ -import base64 - -from odoo import http -from odoo.http import request - - -class SetupProtocol(http.Controller): - @http.route("/openems_backend/sendSetupProtocolEmail", type="json", auth="user") - def index(self, setupProtocolId, edgeId): - setup_protocol_model = request.env["openems.setup_protocol"] - setup_protocol_record = setup_protocol_model.search_read( - [("id", "=", setupProtocolId)] - ) - if len(setup_protocol_record) != 1: - raise ValueError("Setup protocol not found for id [" + edgeId + "]") - - device_model = request.env["openems.device"] - device_rec = device_model.search_read([("name", "=", edgeId)]) - if len(device_rec) != 1: - raise ValueError("Device not found for id [" + edgeId + "]") - - name = ( - "IBN-" - + edgeId - + "-" - + setup_protocol_record[0]["create_date"].strftime("%d.%m.%Y") - + ".pdf" - ) - - data = request.env.ref( - "openems.action_openems_setup_protocol_report" - )._render_qweb_pdf([setupProtocolId]) - ibnPdf = request.env["ir.attachment"].create( - { - "res_model": "openems.device", - "res_id": device_rec[0]["id"], - "name": name, - "store_fname": name, - "datas": base64.b64encode(data[0]), - } - ) - - templates = self.getTemplates(device_rec[0]['oem'], ibnPdf) - - templates['installer'].send_mail(setupProtocolId, force_send=True) - templates['customer'].send_mail(setupProtocolId, force_send=True) - - return {} - - def getTemplates(self, oem: str, protocol): - templates = {'customer': None, 'installer': None} - - templates['customer'] = request.env.ref( - "openems.setup_protocol_email_customer") - templates['installer'] = request.env.ref( - "openems.setup_protocol_email_installer") - - logo = request.env.ref("openems.attachment_logo_openems") - - templates['customer'].attachment_ids = [ - (6, 0, [protocol.id, logo.id])] - templates['installer'].attachment_ids = [ - (6, 0, [protocol.id, logo.id])] - - return templates - - @http.route('/openems_backend/get_latest_setup_protocol', type='json', auth='user') - def get_latest_setup_protocol(self, edge_name): - # search for device - device_model = request.env['openems.device'] - device = device_model.search([('name', '=', edge_name)]) - - response = dict() - if not len(device.setup_protocol_ids) > 0: - return response - - latest_protocol = device.setup_protocol_ids[0] - - # build customer object - customer = latest_protocol.customer_id - customer_values = dict({ - "firstname": customer['firstname'], - "lastname": customer['lastname'], - "email": customer['email'], - "phone": customer['phone'], - "address": { - "street": customer['street'], - "city": customer['city'], - "zip": customer['zip'], - "country": customer['country_id']['name'] - } - }) - - # check company for customer - customer_company = customer['commercial_company_name'] - if customer_company: - customer_values.update({ - "company": { - "name": customer['commercial_company_name'] - } - }) - response.update({"customer": customer_values}) - - # check different location is available - location = latest_protocol['different_location_id'] - if location: - location_values = dict({ - "firstname": location['firstname'], - "lastname": location['lastname'], - "email": location['email'], - "phone": location['phone'], - "address": { - "street": location['street'], - "city": location['city'], - "zip": location['zip'], - "country": location['country_id']['name'] - } - }) - - # check company for different location - different_location_company = location['commercial_company_name'] - if different_location_company: - location_values.update({ - "company": { - "name": location['commercial_company_name'] - } - }) - response.update({"location": location_values}) - - # build items object - items = list() - for item in latest_protocol.item_ids: - items.append({ - "view": item['view'], - "field": item['field'], - "category": item['category'], - "name": item['name'], - "value": item['value'] - }) - response.update({"items": items}) - - return response diff --git a/odoo/extra-addons/openems/controllers/user.py b/odoo/extra-addons/openems/controllers/user.py deleted file mode 100644 index 75ec137..0000000 --- a/odoo/extra-addons/openems/controllers/user.py +++ /dev/null @@ -1,32 +0,0 @@ -from odoo import http -from odoo.http import request - -class User(http.Controller): - @http.route("/openems_backend/sendRegistrationEmail", type="json", auth="user") - def index(self, userId, password=None, oem: str = ''): - user_model = request.env["res.users"] - user_record = user_model.search_read([("id", "=", userId)], ["partner_id"]) - if len(user_record) != 1: - raise ValueError("User not found for id [" + userId + "]") - - partner = user_record[0] - partner_id = partner.get("partner_id") - if partner_id is None: - raise ValueError("User has no partner") - - if password is None: - password = "*****" - # load template - template = self.getTemplate(oem) - # set mail values - email_values = { - 'password': password - } - # send mail - template.with_context(email_values).send_mail( - res_id=partner_id[0], force_send=True) - return {} - - def getTemplate(self, oem: str): - template = request.env.ref("openems.registration_email") - return template diff --git a/odoo/extra-addons/openems/data/OpenEMS-Logo.jpg b/odoo/extra-addons/openems/data/OpenEMS-Logo.jpg deleted file mode 100644 index 13ae0fba6120a7472998decceef335398be01035..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 152320 zcmeEv1zZ$u7w;?~(%m5)(xtSkAR(Z1D4>$kodT`}g3?HrfOL0RNJxu_NQsCvsHB3y zou$$BebG<8@BZ#}l$~?_r=B@8PtLQj@^a-hfOkS#P8xtfAb>3R4_Fz*`*PgH)EEF1 z6@h~Q0PF|QAQS*9NI}3KeF)_yZ3bZlkXLaeP$&w3p8!7iW9MxOpseD+{(_j;RXci+ zzcxVypn(ptKsp8dfgfPRRr%^!)xpU4ycMmqk*S5Hk*Sd#0H^{EfDvE}oCmA`T0k14 zO#utQa`kKkfC>QB1o*KZ{P}zQ&A{Ib{LR4M4E)W&-wgc!nE{kQ06xM1P3nm1AjB{Hv|9wW?*FydGUgSgN+C` zx0OBDc|&V`BQ67LOKz9*Hr%{iJlufT5f_{D2IfW%wE9LSrdHxC?<*g$(3%>GvuFw` z@+jI!8eK4zb+a>4bvvnM;AU3N zF04ELPO@on)Xu@w-T^^=RwJ)VH?_5tjygJA05kn#KG%xBA>Xu6I&WxbYGoq9$8(5> zR^QdZ$ez~G%FxKz)XK<^*6_T;`StQ`=xrJv2XmxhWM>ag51gi5XK4Ajc-L*Vt8Cgy zTb#GQpk(T@VY|U^+Jlv1-F`!~p}Ofq(%Qn>P8F;*MiS~)2InnI_3h3(7#XgcZIfTM9ySg>4kjiZ2_8Nn5iv0_7A`3n2@x3q5it?m2?QCmK|w`F zMMWpV#>6K2_?v-W&cNhj z4oy-$cJExu`VQ;N3-5b#KBvaB^)`jQdt2U{PW#LL5F0p5v=P>J`M#OVA08{|DDWxk z%~=65qj}HQhfTkoY6Cm--#*SvbQ30)2B>Q-41ueq2MtBa3lC9gS8{R0n=l#vw%2Wj zkYkU-lhDufU(b10H|sFt11`fFYdzs)zgt>NN?8osrul0m8PMa#WPteSN6qW53(&YXNziOM^(nstkKXd@RunfuYCp8EHc*Sn-2n5p_5mD z=SzLL&a}VmZp~o7A9js#)b>aJ-dH>LgVbi{8OGmq36_fN)yW7C)YiiRY1@1R>uAWo zAJ5o^{0hlxKEO6M(-%v-&4|2-i`-*Duyq=`4g4jN`t+=?a-YmWiwoPI&a?A#Q>U~? zCTV}k*QPQWm5Ju3Hq|=5O#~#Uy9YV%r3Rkv(tvJ^;ydl|0o5njnb7ahU9w~p zmHVyZE56s3wKTt5TJ)s=_PyX=`D6x165G?FX4~sL+z6ldK}uUs7wlghAXMNf?$3)C z-5daH=#ZamHO);-eBb-aZmD=0sgK%U&3U)sYU7NadMCM6+vb-YuG#at>na`L_uSq% z!vzq`?B!G%U;odkJNkn)n}7a1Gv2*_uC(mk$!oCh6!)LJ$BA>M^7~ldY5k0an6_2w zE}fG8LGCnqtK;c2qsmVYe-Qm6KzF{Seg9l|SdSCzdp%0bPS@U7vEReH&{|Ak$xNO4sYk7>VGL`rE~_-62X%^m2ANN_Y{-U-3=19CZL zZ@Y*cf9Y1CVo{s8OM4C7`f-HIb!hTsTxrX1c6NZ$wWX%!Q)uVDzkC1yyL)-=gXTOx zN`8*0;P*tcW;5mesL|+bcT${*82Y1RHwY5Go4IV~@w?}KP=-hzHh9eQAZ0l82hq;~ zR64ShV!w`V*bgcYhSIE1U3CrU50YI0kQ=Y3uDkZu{HTni?fFhP{7&+(jG`g3$4xnh zIyG2-bcfMsGG@w8LIwR%v@1l!aWtnYJQ;y5R;o2)N4v^g6CMH~VhH0H%W>PwS?>`@ znc&mY_q|yNM7x2I@VI%$I9y9%KPvB2Ee$gnOBdxsknA6|SCM3T0ZlTI)(;58Rbw4T z7HC{)5r}pJ5na;@dm*l_k3bihrMpF7UM*&J*X3l}f19`tr?d=#GxW9|&Bk{V1PDaC zf_P(el>)vW+O1h0i~(`f$e}g$PoKSAUQ*e@enx>~*b2f?Ymwp+gc^L*?j2{3 z%k1(YN91B3yLZlkqjoSvGGMBWJU1z+YU~+8=?;*ZqVT$FQ4K!2HRrCFibM||_=avopd(K$ ztk!hiV81(q>t1gwg<;>JzsAxLC70BESon#Pz|)#fEHi&1TnhxRJ*T5Oe-gFPX|{>` zAUo|(#Jhu$lQf>3imjTggCf*NN-mjAV(D)DNupP6kUHWW_}ltzeq2LY730_wTFc1T zmTDmkuxoH1PHDwqWn;wp$faV&o>zj0obnLMS5c7p&Qavs=4AFd~-j z7KO-4rg3GJBbs2sUECWRjX2x!j}r~n<7v~jI=V2#5xGSK6g*H5v;9Pj*a!j2>0s&Q z`Z$%f@&$WM|ful-DxoqC*NBeUJyOOMqyL+OEV2HI( z!e2pAJTvOi&h#N3YXTbjXD*)d=t%g9M|i92h}xz{4nwTaqV?fP zw)ub5m9IHQibyO9`}9rk3gS3mk4}iWY~}g}u^3Rn7h%6hWAzhjlmW*JxBH*l{ef%( z$eDV!6qGkTTw#cd(&TI>XE{lLSO{+>K4CN=A(kQy858tQcuq$k7XKPbQgNszEqi(9 zCr{r&xp!u>9x>^NopK6)l)8}psRo8n4DRR&d!?p3Z-!9%t6;tDeC>F)&_l#_qD}_9 z_fw|3Zy*#?*+%#g-%IgJKq!T1gPUV!bz>ePl>QbjqkfY=-w_VGhhF;wA|K zZnmoKa!N*QdhDqA*@*XVvS5hCzlegXyi>%^E{Lt@7)!H%wlt}2|K3-*R|&D926-kI z$MkKF|F{QQa}Vx`$*ISF^b&?J8gikSQP=aYy*!AdLI%7d>^Ch%5y`-}>c*mFZ%K+9 z5KDg<-7hmSW%Gp^hR_faG%*sQ)A<65KnlK}Co}u@lU@>RA;1^Q=Claxeh0#kglL`z z-@YKWMW-&dQZ2oWAQ*hikxgBU*lgdK%HX5sy4r}Pzm7s=&rM$ZQ2aFkp(#$^OxP>c z#VG`p3x}8Y1iQKJ87M--bg<%pL*bt+E+91d7trg#)l%d$1F{I!AR$vD!DloWe-J`s z&$CzN756{?K>`O*6{f@Y8P_9j!Vp^g8;DHZ&_SJ^KjaTZs3~W4aF*Kr^$#*|k4G)* zbUNbBNmxOaGtRoApM0p1+z&A7JpRm&CJbDdLXny zt~4ePHEU{F{sW_qtx`Fjhi}+yigw+Cwoxpc{S9$Nx!aI6l2?q{h2kgOx#Fm_4{@=x zQ}Yj2{|SI0iLKl3^?Dj%X9Dl=GIBnSe;)uR+qGt#^V50S?*(u^tC0GOb|wwQ6GXz_ z$F%LO13F(iOdz~`(u)gn?=muJ*}#&`55{X$EzdONVwD+$>j~S`xzx%XJ z#E`nIrlB4|l_G3J95Kq<#5yW8*F@7iGu1}Z2Y%p8%}lqUz>bNk8~6|XaM|#}qd7Gj zlHBgPCxZB)|NZN;skTusA$uheg~-K0!_UIz>>g)C1V=l)9AMj3SVD*T3o-pFJ}*v= z@_OY?Cu|q4(@5zJPIjXlWup8DT0{i;zW|YlRelf*qZXM<`vs#Ns!H#=y_}k^fSdIH zgO?vWJZ>?Ndh*9zi*H;i#((#A5%b;abG?bfSzg_9DY5x2Jqe zQf%#)`*Vf)nJ461iY0y}QBJ+4y(VoHu%D@I$EyZXCOtE=dvZ!AhIzIN_Kc<@zFRW1 z8}CR);g0CLQT)$!z=@Wd{LfZ0ceqDVc2wWR%jq39zspd&7?GzGCG5tWu}jdS{AcTf zyK%649f&0M*-o0Qy!-v$yLt0Q#Ia!FKiVCe_vW@v7vd@6?qlyx6R*zheb;@n(OmMZ zT<7zF138~PsUxBPW{Y~iD!=bDZ{KGT+fbCAHzy^t3M*8(sz6xRbFfR z9`u%#duZ^|1Kkxs`u^1GfATJ36OB!2`(>$nq6JjL^eeLnP?obV{U?(@C1aHu&(e2T z+z!%)fDHy_b9O0U&s)ViT zqZ)-xbVN*b{JdFA=5?>k>$_MnvsR%X{c)n~oyvXF4|f^wKTu0%D2~mGqJ*xym~Q0v zsNnNB{j(8aVMiRMcVh3xni@thy98VISKSTs|DYiMVoL4OS~y!;(qq4_2hrBEd@MfD zVq3zB&=UMc1g^IyfB1zB{l+s4&)Wz7&}#{VA=g0+{EWCUBkG6^9aN*JsrHDecI^#d z`x%+Cr4;#5d)F=4IttCx|X|1?iV@ve*|u4KDg>PV^Jrm)XRTH8U8CRr}H^}?}t^2v5QQm_=Iakd~~ zJGKWj>oHbNgU(pkcGnszlsFc-dRL&^K>&$ke(IL`!om>kc35xTtlKlgKVdtz2lT%D zS!ZzSv%@n%o3p*~MF+JVAS7V4mm+I&XFrK_M)HNy-gihOJ%yd$PA=^z4?zCvoBM#Z z&<@aGX|c{+glDeeV{qMvl1Qr-}@(|2f8QwUq<_SXYQ9U8VGaj(dB)Esc15W%UB;KZF(0zp=nur@xit_4(aq#rtp8|=enu0Mi{ykO$8{+euw^P zR_U^9lRFEV(szE}w~>3a;clOZ5YgWjFA@9vogQjk-y!epJ89p+f0{Lq=Xbm{^y)je z1Pu;mp*=HOcN~dK0_PSQ+V?pl4(nQ^aog)bhhT14Ro+O?cVz^EyJw9m1-9nCBvJO> z9Up&q_^{I_$3*S__)CwSr9s6u8RoW_x7djSfRhQKXw7t7x;C87u@pE{z=vn-nt&- z=Gy_1j41%4QQi71ds!}gGrlBw(|z2d<_1aIwo9RuJjk2t+p4l#Vg4iq6&tQ2y}A_z zqe*z6NqC-EY!(Ip;2b7r%#u2m7MN;eAuaAp*@!H~_IXNp5fDD%ICjv!gvtlR9VQ!5 zM=fW>JT{*=0Q|NA_1($6Zt)-(iA8>$PGE7@4hT3VeM#dVzq(}rb$_*5lNEv`DHqC(^OQDWD+iFc?-jM+%N{;mq3cWPZGxCM9r#-J|m{e)R#Y zt`k=56RVNx?cTrmrZ)!u z`Y`g^g$rxJA^WpWIkAM;5QjZo2t7<`14kjpNF_}vGq?7$6MW7XSFd$hv)Hpwk-S*# zw;rgp8v#&KNjvQ*C02Q)UJbVg4Flj~QaSNzDt}$&XxfzJf-#!0a?#gI@x!Z%MAuZ} z>X;PIt!n^4SoOTalIOcEU{mr(32fWpcbn@=pl80=s6#Aw?`FY38nQoD{ML!6hd^lE z$OF3e^;(F-%Y%F50u0Iek|tf@n^h28QYo433Uk})!|WT1?peoAwf@nv{^$&Hj78pn zFf9+dAwoLqtjkuCyIOp(MSP&Ulo==V1UNDM$*$jRU8%GyhQjL!AX;LO|5co6`$WS%OJ_eqH@qVi#4c0BOncLU0Lke?lWqL= zmYF;NL9`x6+s4F&q@wUDxCVrz`IVxC^lnPo>RdaSK~VQYkNj54iSlf*K;FE1!|`67 zSAYC;Rowogax!-z&*_2pHC>ju_<|S;p6P7nwZlv@p+XVKAz&OUOI)Hn3s|^LP>YW8j z-c+)6-JwNIi48J~`_!-LNDH8!ec#Db{(5Tj*Eb~UFX)!((ZJweTRZ*$C91<~$QT{m zsrRWOQSF7$E5)tRDA1~9*CtMU9J)u>u<2Gra5zgW_9K?zCIZpceb*H-*=}2ilf{=e z((gCYFAD&ql?%=9CYOe9Z0Py;KL2?BQ|VIx(x`p%{>4{*IwPD5qc`7<6?a5z=l}rr z^>NdJuT`(NkiDTWj#0{(Qe;dg>~xRm7tvzPesS^K1`K}d@qprazu~?OVC@VEp6JNG zcbo~j6W#-^xT8>e=}hZ)Q(s7Ts3JFe?%}Ng8FDVw9W^J7sEwuP^`a2OyHUgpT%w2W zLD6=&1iy?m&hchJ{NWCioz0`xQ?n4d1)iSh-k(@7S-lMcg+>MY70HHm7*`FgwRd|)_sL``^emPnY>$b=tKLtOy*7qj!%+&} z+}C#0{V!A@007^{TIf5Hu)?;Al$Gkd;9R+|1%MQqo-nj(A^U#SHa+9Y^3?nO@uAzG z9X5ZI!8nFKn*G7?tJ;=V@?IQMqkAq}07yZuzMk+=b57U-AB=V8iwkl)HAA;-!%^*11EZ@9RhO9P$RRWa`Y3{{~ZH+wAs1+q)hsrDK7dsXAiUWVaX7OlL zdHviw=tc;XQ43+FQmPGh{Y)nEEyC~kl}!{}?|A7M98K48mv$4|Qv&sV*24Sf^1RU= z*m@j@_9+i+#dp)^R(a$rmi~o#<-!STQX8MHS9SwQdeAi%0N%GzUmjcpELAv{eU#YP%Z52bm`TS!&`$hbXl8G)F zt7Vo-mex4 zV$fEBJUYE`jhNXlEpX*dU3&1}D>AYdA^M%-fG$VaT9Mf~ea1~cuZ{VTuPI3Ax5C?t zgSyoQgstb`Do7L`TXjy4H^XVLwE*vm#Jt)^(Y!VOzwwE2jO~;GVQOCTS}@d)(&--) z(^nZDsf(-$AcZQok3Vh|*?(KmAE|Qf2?4Mc0vLOiGfRb5MgN@-ylR^T@O`73;M>)B z5ZZ#bVSSn~ID_|Adv%8`#F>yEzAgsbR$i!2g+xl{Ll|DwuYsmwrNEv(hRuPW!#mN;w)B*8H2$;l!wtOB+^FFa3AuaX3qG;*=i zXa8HB+G#<2u| z<1rRJuT0La)-@d=vZMp-23aFIkz__V57#h9gRtV+F7Wa&!Ydb=xXcS*i2d3xV*Mff zZvjYwk8Kvf-H5g^l`uedT4=b7c)fs|?ojd^zba*j3IOQ3@2bJqDD(wye*bqAZhHL< z0xau?h2t5bGgPtrA-ypc){622J14%NQ#R~Nqg=dwy|8qT_KZ`Ok7x^q{^pBV?4tTaB@m7WCSp-t-hu-SjnMBj{#z``a-shV zr~1r`7Uhd4EI%-t)Hh*pC7XLq?P=spWf3#=)Kq?p&S|1{AK>vfY(0PH)sAyt|1)I$O zia-h+B-n_JQC;xAX^S@suy#fxi-K+-S>*~FWMqFtHl5KgN*>TS_1aa|8YUq!$VfjtApnMI|}r-6n``DHv@k&@c&*0Fp2aHk0ZH~ z-_ZTv53km<%fmWHRg^(5g9iu`qFWVqXtmnX{@;;!yoLY>y%1Oy2$T47 zK>1!BRQPjqtS^*CtX0ifxBwwC1J$UbREp8u2`+5{FoZ$(J&0K9xky_EN?A|bEzXa# z!%KF56Vd(b{2cJyxSv*K%Wti zJ>EVSr^~v4a=AK!ay+K zKH&pADIy(H{OvQekaK>{oPLCEwhV;$_Bm9ynp1*Sw;;TcNuiff1Ij|H$!ng2n}6_y zZz<;`x>7S9G{D9nwTmLxih=>F_bwo<{qX7xYQKtvt$bGqjhfFg$B8#k0P^s|t$G!a zmb7?PDVR{)zKHJBOnO)FlHR!R*}i03h&dSer>^e@KM=`=4w|!4G0W=YYVe5eT`~Hj zsj8E*Q7~IE%`g!hmUiY=v5FhYP>fWL04bK|AMVKlILsLlvr@%8oCVy7m*o87L{?l zliSV?-8MwUMQIheb)O?d3IK>tjz@evBy10$m@T>Ble`8Okl%R1C}|i0o{$54c>Dy9 zYudp_#&DUEkW&^gUkZp#TlOP#S-o}F8AgffJJMoI=Mwd*4^N$<1$g!^wQ#E_xXDme z5erQ-E=Ms!BuAySmXEQtf2rX;?LwygfTGXe49YpUDr;2T)~zL6i?1F1XmpqO`YgzxQYBJd?6D?`fBeZsxj&bP?MbMlU#{3?DI$Mh!|DR3X;9X9l!@Cjsu zym0Zi^`lt#w~ES1r1$`~GG4>c;vqP4dzOb)#}LUU_5o3H|L_b%$4fD=KLk({ zB}|*o6OOBP1qlL=8Ailv2`A^C;f(}>Emg2VgN%TOm`_78O z~1HAHpSnm?-Zo=johEb{d#EuEF zIOqqlp`wrp@Q;^Hiro}iD&`yakvb&+a4~WD^o?|R3&6l~?$N>Oieoz`#~uDm%nr;u zM9TeDBi+;a$jL8uS+F~=BkPr;Q}ib4X#of>#;AXoS8w>enZ^W)3WL#E^m&ImPXIu% z({qF^W5q@i0M!caPoRr$oQq@u$X#YJp3C#)e6oS7-GX&U5r9GC<<%w&z&i#74-ubc zMq9B*yd(1-WVZ_H{g?%NB(BwI($b*CI0eHyMPwhmh)&suEH_XwRd7t_JZYNhT%YVw z5Z`qGrb~x%i4NZS_g;g%?U~87DUUA2YC{V_ds_Ob7Q*q4NX# zKiGL*qr_o^ymqZ$?Hu3^(Fk>$-M@)9Tam4{t#IhiAOGGf^z(hx0DCXw>TZL(=S$iy z)~N%X9S4pCo;+cY2bL%F@qkZL4Q#b<5HE|J21i1sasgPh9$X5+j6Z7y0P}hG`7oV< zIhulcu5-u_=lq|YN>7BsFApN+;;;W{(ZNUw&h5>iH0w|w-p(o!3RY_XY`9u(<@-MF zXjn*Ags%1ooA;TxiJB9;l=~vsV+y+0x785N>%>WcCICPt7ZAChrtjn;*n0~k*L&ef zgfq(#09|tjM3omPm}h7~9SDX@D_cOSvhX#S5JPjpbAFn4b=E4t=JQ=BkX$#nI$A{w zXBHF@Um#S2fo6MiKt|C6Xc+RAFOi>xf!oztn$hd;N>qz85CGfjIFk2ezIruD$ELnd zEh_u&MJ&DYJ#bXDFcAvigu1#(KIavGh>XrVM~B?&^Qs+e2SX!1RHHq6+dvQfaj45X zKfwausR95SZ5zrygHi1T9MW+Rqd6brFyXNR5Guhn_U6F8$U9d>Qywv20uE;YoWd4+ zn&Z%As#u?$7mZ915Y<6ev+S}EdWsgybPmUM;#9`)go3UQfI*>R@EBEjzM5HTXG_n< zJ9rKEZbR@|OaI(M+NVkuei6rl=6nstpPxKW3o@J484IPp`SI9{!0J%%E%}WK@g{OR zP+_l**8%auf>|=>?{yTn$Dg`@rVW!$6A*r3;p%}7);A>YD<;&^77cEREP=o{{b-z` zJN~?&CycQscA>hu)(iP40nCR_i(9J z=zZvN2>B>20B9$TGS(-Dj0?p<;YxdRAQAGuX1nnP?z}DTi^3a5V6|eO1NjUOqKhOf z5ddDO`%**=2#}&xsFs2A5G;=RWGXlKx1HY@M0riSnnGk zPZ<;RI1nhNeKsdYA=AzplL3Wm?a?6P1)+3y(&c>0vUEU z`Z^@?Ygtxnz#d&HfQqG7#|1z_!cH?MfJ+1Lk-KrPcqF+U6fjn}Vg`nVJi=dcfZ~kH z(q9BQOcbriqFFEv%;cof$7vxow~}svI+Dyr9ZI%5s^l-%oE$9~0ojK-(bgPDPvj z>ImY0T$+vWkec=m8f$Srs~daSv~EQEd;Xh&zZv+Ofxj8}n}NR>*vJ6xN)2!b4_q@x zLfVgtf(#%b!#9;ckdRSOfqiI7_ymNsJcpn*ctj+mFk(8vbG&>4jQsQr4+B?vfc+2% z06|4s0fuyh8za~b_Jt-7Q|LBiPT-hN;9MwZJ?0~1lRTm%&O9hsc`Y&dL}<9x2^E{? zrq0ZFg6sqr(1^4(nUY7bh(Ze;S$&D2(@0JDNac~jX`_5sAIU9`tEgU;eUeaWP2%oL zl=WJr;3V;#XJQ0Y4L4mwf&+E@(Yw2HPdvR@CVF)y*dc@H*30X(OQh5#+RqfnO)Io# zn`YW|rdu0kbVCZQ`fg{O$S`_778s<9aqK)3t2eT@d5we0?326ljadZPsd+qDjca$u+G>%}=VQevX>1+s9c{!0ifELu66I zP1!OL%#=ChvB8XD)eDE8`e8_nbQxtag*M$V3Q_su@tpq_%fd zB%OVSTrkUSaoRDR!$IN2Iqc&+WTFxR6WRi%&Ig4LpP?w}PBluo{mk=TWichDHe;WY zYscH3j?{_rCv@shQ;m{|dc>ZbK0!@!)J}-oSWPLNxGyj6nu9;IRx$d1V}v90ah8P- zlR{9`iQ9V3qQMMqx{vxO=^;-U50zhJ{m_$brxDCzDJ#TqWl>QbBZ#_@Tqn|}ILb*y z$$_sSSnWw{Or+*iNa7PG4!FwjWk{ zFu$l`@TJ>;O+1ze`sk%efm_iL+s45MZQXL`Rsf%{LU-dt-&&p6tHQAB7wOrD+aW6e zX+iMOyJ0&04ZYNvi6SiLG#=^8>#9g8;bF??1eGR9OecJcJN$RyIw7_5_M@7mt-%i3KU?lwJUUerQ%pX7}y z?4Yb`<%>CC{^Z=IJ52TP%kh+BtoxV?F&F>Kv2_ zZXQ1OIzG4D2D?LDlEZ!6SJZ?$E=b1A%jq~OgP;wL>Q_gj6F#ImtwgOu%H4Om2UA(6 zNLrt2Jz@2|s}-Le^YB=u9oMPYQW>i}kE?~V7tB-R1nfBd!DK9Vj9xS_3A!;6QnU}7 zw&D!2eI3^#GwusR8k4jXcGhE;F?+}b1byP_E5DwfyXRy7vPMw8hXEj?V#wDN*MDzy zwo|u!-*`l|y~zzm_Jb;y<$HvQ4*85G^Q0KJLaHyNXQj~}4bn2&SeW<0a4>=*}T z>aun-3j6ii>d1L}4@l3QRLeySlNKFJN5H{*{8Y@eV!WVrshUK8mK}^M(wB*9S-dsv zTkzKx2__FIsynf-cw`4!W|4np5!LtfAGWcIyrv*Lf6pWEn#iO!g8JH}~ zY^y;W`A7T~C(wFJFc~rNrD_>QTc|9Ea3752#!O?!<6XJ)R2KhK2{)ysPtuV9+hvAP zQToxTXbbt?!_!43%MO?_lnyJvQEjE;{4r{W+#i*cTFSgX*=vCtPoI`(M~0*G#kAM2 zB63dSvpwtrPEQ(C=_WmEyoCOcvBlTVe&ow+81-^IvazK$FfPeJS&O9*zjXdC_9;UA zXTswcEc}KLB&XqC%W|11;R!Pg89At0WVg2(Rd%VWIMAU;2^OO?+v##VpKXDJ)7QF~ zuOYf82gFR{3v7$H?8ZH=TxxZ1NwuL7=xn=TtI)uT5ptO4@=?d*M*J@k!L6 zi58JND*Kj)s{HEhl139bMk9r*b_vui%6w_+J-))d#6>uIOCBntvWNJdM;Xc9YddgH z$mkdafBc(h&XQA{>QDu5o|x_?C$$4s<2f%gReZ?lS}C*hl@1@*N5xFOQZ?(qhmxD7 z`Fvm1(qtQ(p6%&5v#v;us_NoWm6Aq{mkY(>=268hr$@5yOj_Kv49%{%JwlW#knLJ) z-kPcBdSdzV%n0vC-0ZlxtWO?S4bMMi2) zgF-JJgro!+r1&baI=f1pNIUqnVNsdcOC?w;9nIyo#c@-OdietMLn1{XDon2&Pvf6Z z&VM$gZ`qp7_|)fPwsf*esF}lOylB;QxgvUx_sZo&cge|$m zLB^$N1srhV-`7AVl*z8+!A^dmF2|M8r;}Ew`T9CNVqTh=fd-TxoqG;|!8(VA~1cCl)I`*AP(Kf9moviVH0vg5-YWiI+dq zon{r#5YT7{g9*6f9~d1riz(%PG%+Ui>xIc65z%Fl6jeLUZ!aa#%5<`WZOUWVD-M`3 z6oWd-iL9#M(hNdFoog{fL(=c7qASwOQ>T6qc$`6iE7ns*FRBzOQ%gaA{m6K|T6+6H zDC@h>BiI!qR+)~CgWQ*c-@A;9ia3N^VP979z0IRO7UliE&d+uDHtuEXepfXVNACo= zK_9s+^-I#cFj(dU{xfkD$$RM%C;>h36?5|QP`?U`?+s$<^Guiud5vx^+NN?q8L z70|fO4K6~vEw8*5k$g>%+Rbc$-V#V(9>~Xj+io~jh*=Zox`i*VW#%cE>cI)YCpT>A zqD4?=Yr_sQX&Z1@_~PqgxFbcWYPU)wC!DV8F*-?w1l*~WG_(lq7WsrSt(X~eJE_Iu zPE!ID>%7q0?9iS&A0Q2jvWC;tZ(C!gz+siJfbc^17a&|BljBbGJ&T}@*vks^=Nn$P zec0zPusj=PRdOe=Ob3symF18!mZfGqz=FL3RI;)9953`M7g-=exlxdqKN~S;cJC8} zM?`N}HiI=5>~kEG7E`SbjW$O6XRH7KW4(M|cC??*a@RY%hu=JbBP)Qh)}y+o_s-ld zLBBChmCwEW`P z>K0VC^sv5FzQ(Fz(Jo&zj(wC{5YTP2!8>(hQ)&qo7Gc4HS`$kZG7Kc#Z9E?NLs4;FUogC$=Udn)b$0|%= znV`?dq(t@BLYk;lEdgbQ7gyl}7{RqJqt0XW6jjb+S6ZC$4kh+;1TDn4z)Xn#tIgaC39c#drD|Mn`QXj9U{L}slXn_oE zif1v4IfGQBPVvIyr!83m$syM-cz)T}a_j9|T4udFbK*DNhgK_}RIGL&H0$ajN@~tA zQ*X?4obg-4_C#tf?NntuO30PSMvSr?1n`KN4hMwRm(Fo{A`3&Q=%i+;yBz2a(MP>_%)AVfxRj!OcCBZ4Dp?53lg)<~2c z+Vr8f4N!rOefQOIFY~n=YB0RjvveI0*msn^L(NXsD{Ax;DRWyBdl2(cr7>FUXHOJ> zb54C{*nD)^)dKxOglgil6;zOxV_;dI4nwJW$%*Vn>&F9_5lH}k|SIV9P=#~eGO;* z7JU}7ddPdy8P()INWDeH_!?MrL_=jVvO*N4z!sZ!`~cSjjecYyo8Yy+jXB=nXN;-7?Li{83_JiY<7mR%!Iq_c}9=mmp6Epc()vN$ckRZ`R zt6Q}%P(xm3KBo@~6JN3JE-nc?-JHs zs?eX`m)3rVBII>b4*Jdwyd>Wh;OT@q=Zd_n28-305!P z`L|rAK&w{W7wC#F4Pl*0l2nhUIV!G6rGY+KHWVRvv)+WrD4o&QM}kO1KRVB$R{CnK zF$KlUD{$QJTZ`?hi*)CX9zAyJ>!~+S1_sYx)uMiUIbEtbsLb*~+fxankAnp!sfqUA z{P8@-laGcb2Onhmq*H0wNBsQ6ji(=?{KNV&!+^Wg{EU{f%tlx}VuWLTIJZA>8r-&5 z)MD%!j82=6RgLI8V`G4u)0W5!yiPVVPLj?zO=3<`RZ)cXLXbdEIZ-;W=okb!QLR^C z1&Bj-@+~LHXG{9f-+cNcTeDks>0oE4#2Jo~B#*Zg8E;QN4iaI7NDemLDAG*Dze!gS zbtR}>iS!hQ`%rUP-_hV4(<%|u_7kYM-Z>2IwkPR2Pu@~y{Uj~+@&Nm7*R-=l^e^2V}0gJ zd#)i?_5#rxO|2(2w6R3Mof!^EMSOzP(|oGTXh?YJ-nG=kNwn>!B{*#|Lvu~wzT%cny3C>aga4ko`( z&&0Db&+fqC@agd!8q7^c6;JOyNs;PNJg_))xnK z>Pk|Z;?I7GR{UU0ttNikE7$0JX1A8vq6Wpi@0d(y9QtYR;hB4`C-S~cQtFv9Kzynx zYBMXxr!tW*F@y&n4e!iv1zTe>@;A71bylQDu5Y<>J$ zq7R5*PN#xAo#T z;5T#bpro-FOc$tCXXp+V57>7!l94PeBKhvQkd|bL$*vnbl6{%h7uuh3E8j^C7f`c_ zCge=6@5eO0N|+s#Qd))CBd3ye60f88$|0WmnoLvPkH@-m9XO-FQ}PUbpO&^leFK>g zvdTvVwf%Vy&M|i3qN*QcbasapI_W1G9bZw1hOl%?!ElB+!p*QTc7<@QNA5Q1X;qHlM+M z|FDY$+4;8)5=~Pj&tMN`KENaExg&Z>@l>=68uXFAKp%Ow==k-Q5!RwQ6eWS4MM*u6 zyH@~VW1UacmZogp9T@NMB^h0?PDOeP<~!w8M0qW2-I)xQ8L}W#H>A;@&HFff6AGu*WAQ!L&c@!CN`2ZZdZkXJ(}F z(SatbH@Tu6GMV{@(XijEo_U7)ss^)&Q`WIdxv`JL|HZkHnu-R;$M0IcQ9gXu>PPzU zMwtEnZ(U`0<##?>e^X4k^!ClGs=G=9H_8)~%IV%3boqK**L3b2l5}&@-OpMcX*6p1 zA*y{=5h-6aj_2_5JM6P^7>B*k%aEZqIho>qJ=e31WO|HnmJOWWPPC2Orygp#edS14 zf32SLhtjO>GZ6+n%J~?*nAt@bv3@|H+aZk5f^%wUFV(F@nTEY_rX9ZUwAz?(T0YjG zZ^at!P*%1wjz4zpt+`t7OO4Mq^A^OQg;&d!yB`+&ZB@$z8VuhW^c@$^;*Sv!d`4M# z$?F4~)X0@;IoD%(kIIZ+hf($3XtyXMc-kGPHiTo@MQro>*}34c*n-Zhb5|N&DoeK> zqBQFoZ2gv`(a6V*x#&#DJlDQx3}zDLyw7fUNs`b{C`W{GqV}ZA!-2^%!JApA+5J}u z9`+bY06$)4Cg1*2;=0ZXOT1SO{f8|_8Ki0S^W;8+NgZaU`6|LHBl`lYI*6>`J+^@q z8%`s*_%V}Hee8&x^@mqvqE?5M%bmUQqlo;H&B#C0$$M?9xEYi)LdJFqoWm&#els@Xs&ZM~0LYEKN(NnJgb?+NG z<6GQC>!aCGE^$`+R=wAfX+1Nfl@Zpun8kR;$kl6vo;|6R7&nCP~) zCRU2yC?D@Dm%l`=(sMcvZ_+g)wrK?jG3B@ra-91j6Z@-%6CVpy?oEZ}!kKd3OqzF0 z1C;mNW^YS+GE~1SC8(g&Empr7!&mw30RaucGgc{{G859WyLtZ4UZ&6prMHn$eswGhL5i4|jQ*dYnJ1lxlo4z=$~4tt)=`er`( zN~~LpVac*jeblX5!tS;HdtnXYxw;YN*(29*xWWhy3=nAEXUuh%)B6;BZ-(jOn-d>v zZrkd&o7{2d=?!*fUIDNNuj<@=aI-IV(9-VRFuX3tVJjYtFX(WbD(b(;d04MWu?x;r zy;Q$?0XvC&{lXralT33~C=r_XKFcSNRgj6w*PmVvnPlz~?-b}KI4oaJEIb4@ryriz zrW1;Beb8e%O@+gBk%D;Yf@c05y?Rv6%M+mmF7jdz{V6lrEyQcolft<@Y%6CSch=$; z_;caNq^@;&xp9Yi4+niJvuqFz0iW?lIVuCS?@oRwDR;J80p9kQd^^cG*{F{FDS-Id z!SS;s`P152td*YObT^!>Q|LkzW!SYA^EtJ2n^zx?D%;G8HWP<@r%ny7yo%T4mFD*& z`j-wCF6DZ=%o&{v7%sKdjGf%S)O7h~)sU8E8)ZcFlW*vCqH6K79%p~@UnxwWW+)Vlu8GbKMK7-gW)U2wxw_#LE=EAfZ*SmxEbzmc{2Qw#QfW)?4d0$I; z72Yt1U7vWNM6lX0$D7-~*w2tP=}heUDlZ_WjI6R%{kr@6a-XVz!Sl11XyDaHu<^{N zdkwEhy13qfT`~CfqM;V-W$!$|FEguYK4Qx_^6GJmb41 zA-KD{L$Gk}80A?uA&X+cxVs)`z~+8Ebn1mG97=k@8vyH5I5fv(=?*P zkUrpj!#xaSSh;G(5&*vKZEm--*(Wt$e@$#>t~Ofhdg4ik4&uoFjMB*eC>B@0vh1Gu zw7Ys>4V*oZ@j2C1NJ&~-UuS5=^9pyPGc*`B0UvqeQr0wRV~MP&(=<+cvZ{4a)o6UO zs_CoKG>YbuLBKJ&^O_l9&7UN!t36$`wNT2bBe23+^Z)o9;P^Ag`S=JUpScMpM+Dw7p15@<10<;MIE+h0d^VsH8 zqTaHQQrSQI^RUrIJY%~>^2`5k+YkJY)V6CUA4J~mSxsvDxYg#G$n#rqX-#8^6_rjp z%+GPvvT+`d7vW~ZuP->r+gStx3VovqhWrv3h|F(* z&Xn7jhH&=3_-goa4 zDCJcZE)&1#@q6%_gdZ}3EQJ<45sWA}c={o-mqP{|^?mR`$_x0iG^zmJYn`k|7+BMY zx)K_MrCyr&5=CxFFT0&a^NY~g7AZzj>$;d-mDc&l)Dwwq#kIUD1E9b>ofDsIMUiv& z&t|IWPZzkgpEa97RWBPDzX46H$lUs9nDadpBR>fm*E&|S=1cl|cll7pg&gP54wmWR z4x&Cy>^=tR)_$L9zY>0*Tzy=A(FfGQN?7_TjA0%(0`^Wa7@_RmMg`xB8JtxO`aQb= zC$^sTaqMT}8jof5?+TfH^l|7R8a$G{P@|!e)nfh60oX}VyQ?Ud~Q zQu$v6lK&5RORP~|XPdbA5dk#LqlE-1hh>^@XJQ_?5$UyXwr4wv4sJ~2j2|^hpVU=d zhVex<-`D*|R_+!v+;*6f@%y^}tu*B!YmB*Wr5f|Ou7o)E78&ti9k54u)_8dhY$#kO zOc(d<`u9ID(8xU}CJZbzRu7K^3;Q1Czmaxl8dlvk)MBnhHl(ULw=+b1A;jmCY5Zo)dS7!o@CI>q&arcVeWL-x ze_U_M;8jsQz$y?eRNvYMz0fjyM%Kga+}?1Pvk8L)C`dyC%X!gsMg!&3K5_IKMD- z(fxB_v^mg3ct=iHA_o>dcP>tj^m@!9eD5wo5&b1YmNM4)b{!~gRkp>Jvq($+V{}=H zA(%iXC=s0)JRle7ad)1Nd?r*E`+@RuS#28{K1CQMw&doLrWy6-4U4Q-_6E%{N@RJk&+=IkrKpT~D=lu&4)cJzGHD;2H-z*qh&j-6a1>6R0*Y zo|TWgH%P!a%y%f|Vuj0s6kRtBT=JF#V&>R8;1bK>U&RRGq*IG_Ds1VPf?#FU)pp8i zYe=Udu0C|6M)N=tihp2Q5x5=mezJxc)&Y||Fst@dWh+$>9-O}~ufnc;CM z@-x9dr~;Ss>cfC`U?d$o&|W{EcB1VPJ*DnI>L-f9wd4R}t?A-ErZ&G5*%eBwz5IXC z%fTkL({->j&D738|G=RqO#b~f1)(5z!B7*Ow>CTWj~;fY(e!w0gy6q$FJC$zBY%?v~N z=u5AH<+!KG_a)V-k%Gx=tZ4V&%p2Q=Z8xukA5DG3UTn?Rat4rbr%G2H#5W@W8=%RH zatHt%7XakJMZlNY0X=`=e9cVmBa-KOqSTYhC<@6J^oA$o3LR7Jt&IlXz3M!vP@D3^ zdmyOp43_kzHASxlL;#b{N_TY!Li70BqeoO7oJzCWPJDS(ur6NiFbKZ9sF#YHme&33 zqR!_P^Ps=lOz^uw75Rqkn9JOt7Pl|q%^JcRsgVN!_viTZZP)DhsbGOH_c~FZL(4?S zAlEF<6q}xX+g-f#>?NO#6}Aay>>7GjKtxB84x%1?+c%G!S_6%H&D7KNwE~c<4^o5A zAA`()3yF}?hW|d9;jyAk#Ne?RtP+A%bLmXOrWLQm{py|)E3S=?A7tRkP>_EM9z zLUA5mg$RU{x^xD4gIQ^uCsM>KRbb)_o$`@*L_vS)fc@(t9A>^vDn@9J=QW0JpTiG6 zQ>>z|TwPgSH`NZ&{mgfC^yUu!T5J++`Z#7y}3I=B@o06F-Ibp)L+ds&X zp93b(oq!MTyaloMoIS=r5eO-?ovHR)h?c{=Gp!nbTFX{3-Q=*hb{x$n9Y0%tKq}zi z4q*re60Tjw^NWW1);MLkB(c?%nX?o5d1L&nE#1Ye3jG=G`^zat_0!WFiOZBMlkHSq z-SZY47&(+2AD8|(BDtbuJzvmYxW=ePClehSuAE&R z;t{0hnTp zY7QNGvC{!mOPV&62KKjd%Q3nINxV3f_=fhkGArl>;y|^u)3Y9_3EBOX!xYuAxTT9{ z1Pak{KP;qMa89lYi<@a%N}9LRmZ(^U$oQWR(1tB~Cl%WDBW2^=n2p6b;-!iEB=aXr z9#QcKk#YN*k>%KRlJ+KT21j~gzLv$qShjJI?_sgG0xvD%Zi)jFzgQ^a2A#wLS-78e zhaGwCr)h0K28}ync-&N>lKw`LERyDJCYGp7wn=4mi!hy|(SqzCe_J;&V68pSuoJuH z7paR&mto(~6SN(iwuw7KO$HjDc1PU+c67JUX6lN#g(axj26+Ya4raL$k$gru!})<> zV4Pv^rIV&Q@eRd(RwmQX9^dPHSKw~e@~VcNJmU?xSQ1M=&TW$@Xg{lz+S@)D;WW^= z0M!QR@?a8GQ0eT)rZ%R9rS{1GA>Lnj=-$SDr12p3jVA%B^$u9n=8LXs5&P#;qd=X{$x9^zU*xWhGJJKca&Y7Q87W@1wH_<;>mzC_E3WnMcIsIN zEL0-SW_Q}C9;*jL7;ELvu)3-np^I-!7XB>Wue2dnkGwH5qC4KvCzML%Sx=3U=|{Qo4-QhQ&LBj49qFug&FzS zj?p?21s)Hy_vw1xyq5xC$jrlZz&+*Wdj7sF%Rl>dn!ClSIEVm2zp;%mmN`qJI|WdbIhJGNEARP$@l{hIxI70tE27c1>Mth?J9YHwZocm5gnO#(rUujM zt+jYX3NH0D(u`9qB%H!;d=Ig^nwlLj2p57lU~sOXz`nxk5o&5dgPQJ}JEGxb3&r)_`{298qSpN>m=5?+<|0K_f+Ixea>ru}D_}nJQ2sul zL1Y;TOwSv8vFy(<60A3w{H3lzu4V02uYSWJWzZiOnIl45yyZ{2tC3QpT!;6h0hD(D zwB4~}zsJ&)gEynWA8!RyaK_(6wxkLFUr(5apcgJ6v|#doVDNVflVnsV<+_GZp`t-I zYL%#q~y0gmGs&epl5JzdGI0NP&aqf@u@h@95@<&rE(ebv8! ze2BhWdnH;NA)3f14%0CVHZM|JY}0Sn9jq0>n;ZQ@Ne84}cs#g- zU+f(j9#%iCZRRpDIvKM>a2d^mhrQeNHd$Iv&LU3O@t#o~F~5hFJ>OwSvI zN_TAOF+SE_Ho%wo9vlWEtlCncZziyRTveBz&g#_U`{udJtI_m@d5Q-2A$iy0y9r2$ zC2L>$n{4S-H^_;6lNvj1?P|50pSAY)FrsN0+s3hCRNIg@+r?&i3~p?6zldh@FR}7v zr6Z!q82$p84Z7{P#e2MiP+Z|7al#jGmTh=!zmo76#Z@$DSi%pV(#eib>Vf-@)Kgw) zlzM*k_R!?hX08L{n&nJ-U}T0BlcQJ5-lV9H=C63CDFGho37yXALTpfR)@?Q$5eO$b z(?qUc#Hx8n9N(6OgM>nllL(C;Kd%E8sb%^gvB5Y{D*_y$jmE-dTlgyd9VZ82D0i4@va16Xj55pP=7;0}JrwDgs72~$F@N+g@gMtu z0Y(HoLY!aUkftepL!XIf9-^O*1U^93?h0y6yt@tAwE!B0Nw+(B82AbVD>J^r#=~3W z(EI9p^I+EZO+r;6Q}=SWgueEo=yUIGU_VL97J4QhD*v@XP%7qG78WJMYNsIG;vblHw2zNf-J}AX z*2E~SgHRnCm2;bKsnm@;6XU8ANg`?Eb|3&GbvbdY`3IRp$cU2yrFcpj@ zSjH5l7j8~xx^ZZ_6=o~$%s4+(IFGV`_Sz%BCyEL@Jq-o!{T%+sG&<{>{Z-u{L9}N3 zSI-qG6)h2}9OY4(KO{8diNECpMBSsHCXp+cgokRlV=-C7yQIJF?kwMF`bP0sE?j%F zzUJG3*KK4pCpyWib<1tO#tuod!!f`p(WP+UTO-qtm)L7A(S&2wffbNog$HN3PqYXf zx{^@k%d@QBy5F&jyr1TEWj5W>+4OGMjo;i-uu-H^_?Pwi@XohHg~Tpt0BBB5@L8iX z=-XQ!HI~U!1xiPBcnkg7AI9bP@n`pVr$T+GJu%-0_3Q9s{@sEB50CgB9_FuW=ieO} zFmRYyP`8dMHk-I}06fM=3XZ>?9Tyx*PDyp#?(bJ|@z?))cVPeH-6?J~t>=lLQM5J?s*88NeXMK*uoEV!V9V8jE;r!T>2r*bbaf&jfU$}MYx2e z7x5goUJOL%l=sD$JY$*OUVCFoK2fZYF6j69Vp*fKTQ1b|6E*vUb0KT{SF5G&`r>6%{vhZek2yDM#Iytko^bgDhahk`b+Gf*E22Y%s zu_bG47cH3=Tck9wk*`92q><-T7vCO2q&3!xm7AwF_TF7kXojtmB+FwQKuMecES|Sz zXSwnNhS5YRi8dQ~S;p~)OdFOgb=IOyj#L#Zj}lz@fXBm#CbHYv zkdoqC+jBfO> zpgexHH{J)4SL^%#2-Fymegm5^rU#&J+bsHn_E8DZW{t z$^ZHX2AIgoSNvMhi8HQM6X9%IeWGoN`CCv%V?OESV0a--c%*0DTj(~c(1a%LY^>CvyezG+&k_nZzv93 zBt`0Kx72M&ILXQe&s8f-7FX%4YNe(#8&-bA$Wy!3ORq5gWLHmLKkxU%vI8nC(N0Zg z${;4EqSN%9w6fcb$G4lH>4o)XXNyEDwVSzxPm~O%7MCbE;M6cspY02P&aqB;YWJ7;tks4M%Z@bLrW2 zzNS+&OU#-|3G}xQ4o_{v1Tu)|aC6#2vx5t(#3^8MbNA+Mn5q{$8<^P}c(j7ilO_}w zAEqluC}vYSe)94}g5J2x^uVN2rZ?eb8U8EWWn6lWov&ct2z(bJ?xa)o2An^QuNih` zL-F{hvQmw3KVSoc5)&t;LQY*9aG_ZVR^}E=CHO=7@lu-FUalT@AR_uj>SCU3Df1ip zus+I5xMadCXaolIedM_K!O`EN*48WBvoAl4EKcaimYc0H6;Mz$#tU(F^#`?q7FP}B zBLI1*tt3kRLOU}nAO;fW)(RQJB*$LnuQ$GZ6K4w=)jZp_+QB@vJ0SEJy5NX3znz=T zm0j5tCK{L$I$EM~Pz>QII#BB&I4)1^`e*7x=&19e1vnp+tr~9-#TT6s;jwJ}U^QC% zI5!KOX=ZsqKsZ<*VdBL{=?721=Aj)7|G?Z=K-Zb$r+>3zDk1SvYDKY5vd~oRi-r=f zQ4oaywPFWyytp#11LdQYTUU4@K43tV13k?O1S}cao{W?6!*c4x{#ph|q*Q>$XQ)+B zBhPEe^NUnH&95WlxQ1)nRtqBpK2mb$)66Y;MYJ@Quin;J8(&1!~_#2() z<_&HC5+GDEm1p1 zawUw#={1?Yu>YZoE?BShIU^&>Un{5brq{G8qq@&T;xEBUKCtB0C^d&<`}4kr1lfsnavTdYu)-9xLM}2Y??vBNxWXd)wUoq&`7$wb*WIuW4F#(ZmRbqZ!`ss|wSQRhL&n z>tZ>tlZL`exLSGO9v9#aAg~bOipQ<LoB6I3%^=n{t+zGT;(e z0jie&kPi%z&c6jq+1rZi<%VVeZu#XOIhfG824V0Gu6KF;k*Bc>{7P6!4G11XFNcM7 zKJ3kq$WtFW4*6I@mPt*mD`6Qvh&77+Yo8-TqUc92P6#dLEmfX;w}fRZz5&7LfSC#PdfNaxmQ8VXP;~9Zp3=WKRCI)OG3kd!FQ*O zRUSf5phXLwKNh8uDRighW+MW6rJ)B!!J?6U)F{I!NpcRCt2s51&_EB>_#Hx5x+1(i zkMuVmH*7EoQi8AXHl?W*8>nuz8LxZyarb-S3fpeTyuMB}OR0nj@nmY@G1<@v@$2(#r*6`Ga(HFFb2H6v1tnI^h~} zG6^<{>4@Dlp~;9l zHJ6JIQ-sD7rmCz*06Qc(wLm*NcO0eyB#GXu*(8a-r5cCOwSmx^#oWf~*K_<(u@cn) zZBE4Q1C^Bc`lHuVdw5bfcZedbKdo1#Y)^F<B7M&4r51DiqZ@__&4(id4^4|>rVbMZh>TIK$d!_l zfQ)s;Tz0@$v9+XQ#WuU$nBd*-b-GlgbH^MsF?a7*5GN6m0MM5Xy3C~)hb;!?H)s?o z5DH}nSgTyx+Ng<_2A48vTCck!kIP!q}^cgrfjZ;9wFS}~>%qvC5a1ywajp_5{S7$~{1 zu&h+gG1dY|8$Os8e$KuLu9zct1u?#p{UXtb$!I?rradIP!HIdfFnc* zVkYrk1CgakFbsU(SANz%;nxZbGxRAg+E^+P>Lymq6(lD!K&Emsi~4eF>JVcUG2vXH zGHnnN3muiDQfQ)u(?R+&%b5^IdH!)q2A5I}Di}Bq(gnPnBgV^8q!O=1*q!^l%Ty{> zc50Y*F_y3-l8y~QuFrLyrKuYM4FI5o1&;Od2F8d#^n_EZ~rv zg9RuIN_L*N?oO0IMGdoIoZ)n}tsj25gXf4u%baUirQQsc@V-1Dd%9+`TN=d{H^E6< znEkxNdjd5hNS#~T^l}+&KPV*y#{`s22j056;r=OdDkeoOxr9rw^Htv*N^+itdyK1J zsiGlt7XnNA@w3~U&4xOv0oTbK0}j+6Hc@+!$vHi3!J#Y#dWh)|&Pf&H5aZFP;E@QA zF;jUyk-ni);U&#M<=YDTq%6e`#@|Pn4-bww2R%hQ)Q7O`)#k1Krc7`DK^$DQbDom4 z0YsqY0Ygv)dK|CAqEnMb%1uk+u5K=z!^3|SwQu2ag-$n!sfZ<>&mkgsq!%@Qp&-ft zO^Q&rhIUAkW;6V3q3PtwV99|{lfwqFya0tp`Ud~nk#^sL;=-`HQ?bIS!?@cYcWKy@QRZ*rCI_f5nQ#o2^Ve&TY4=`rEILls2J>;Y zHCU+~Y@Qph?i{xtu}|<{B}%f`O0*A45BG_do1cydy~`PG_>N`8otOVAa@1+uK~ifg z{}s)KuR1VCBny3|^lajCc{8x`(QsT#wp^3+3T9_ZZB7v(Sx2-qr2hORx+gjNl3c&rf?P6k?CI@i%?r;SrAglP% zxS>tuFVcjlvzoWjKsm6Cjh8zC*Wid2J_&%H;XgLv)Q_q`QYVXY8xW6?Ry>ldghNaa ziGx63B8oUjidG`oE^v7_Uua{VD~gNWiif_7G^n`fp{(465Cs6jeV8s@DY*b3$eX<2 zP6h9EJm%b@9PV2_jF$D~(U}MTfEmJ;naaa> z>DIMuu4al?%RyhQrUG{=i}5WuGEjYhE|9+<=^6}q6CBYQu&#}x@oKXA4s<0P!Sq(6 zrlIfYU+&m;ZC!Y@&})m)%#46*1Wabx3>Jr&UdEhrPiB!|@7-S|(E2)pEC}~<4?QfOSlbN65L-im_vdUtBeGZo5-ci@e+LGuc zNl;PYvWny_);A4rX>3q8*YVu6xSpK1`XyB2Ks%2Bd0MiWul~#o_3rk>>1V>YprT7~G0oBuoVbt5>3i;utnJg|vcBas8!q}Jwc~7im zr5__>-Za(n;)r(RDDu-0sOApSJ&`1^mg=)3jQ~raiHctHLdg?QA4eO@1Q+F>lI-7OI2SI$?_X3Q8*2qyu<7;mXTtVgs&&2ci_kr=G;cSIp@1T9 zH;Df32oe}j5k*bTOXXgo@*?dXfu9GxplghWr98Dpx2OEf>U1l0wu18G;{>ioO!G*C z=(h?rI>9SaLOAO)^jjrS7cvV)mTMrVs(w7u#thht7h(g3UKP-?#5>lPpS2 zyBpz2O@BGMW9{?(+G2(9_$Vz51(_7VOyGyMO`UFy$fHxNCu;X58PZVu1)}#*FNcg+ zjmr`0L6{$^>cIc&dK~;OrZ8E|Z5;mZtnN#`M`_tRf5Azy|Di}gnMAZf{6O$NFS`5x z6h|i*E1on?G7o)K)UT6Uo|(RsR6hKDG`^Cgw=E=xWJni(ne~4!GJ?@q$7fG#LZ^3f!wjiJHKYZCrNUN^M45(TC=5P=B#D2F$y6aPJY&Q4ta0{&g6?gN1qj zufG_cf(D>L*Kk>1HFR$%A6WCOn*gjzd*7XGM;UA z?FT|!NHJ;_um|U{I%(R!AZ9L!3yF8mHLsM_9u5-zSrSqTk({(G5|{iMNT{HNG2>2$ zda#g@r0IEIu^6fs4O%Dp<;SdklsUR}^R$)yd3|D20DMk&NmE?iVFmT1ZrBRr4EloP zkkhul3QUCCDR2t>*%^kWe)>JLSW&~iwerW5c`bgjxKl61v}Q&;-eC+_^1ZiVoU=}U zd}PIgA#S`lVKBu4iyI2Z__NjzLPuMLkl~rBqIk z%wm7_40|=TRqE+psZ2xED&0yV#{?zp_8DK=eT2dgbz&?fX-R%tew_CFxs-AlP?1;N z6$|H zxJsmm;^Tl(JH9CGf;YpOI{vYd>f$-?HIr;Y^AGMEGui`>F2}x`xv}%#kWdj)mv*#k z`x>Ikn$&PAS$Sg+-(NA@J@FGt{~^doKz+n1EciIUa;cU>FgzJ^*Me*OS}#mR0L*Wj ze?^B??={{pZkULl?GS|2ZtR;#W>UnW@nDT#A*e{_6$2#-YVjSYwGtdNCvM`y~Em z_t}w1DEtn;fUfNLT$~jjTt-xos;9cZjVECXu6N=wZKkzt@tS!6g8~O29X~N~x=RG! zIF^0%v7Ndb8>cJn$%?917Fw4V0Yg6`JDOiNqB^@H(Q1oI(|^9=;f z97b~fu=nT)uQ!lr$6M}?R_HO*tL>;yH}%+E-J^ID$$R#mQCvM~*X?=B?Z0vutGt6- z2((>{b>pj66}5#xGwWNs{5Rb<6&F1#kjtB8Ets~vB14Q`U+xgD6LZt`QIW1R^yG7A~kU~<Ykhy<$NoeP*CSad69VPU=I$-G z^3(uAUPBQf@@568WndM!elMP=4q3NQWTmhH`ji{^bT3+<$cK|&pydC0)Jzq=D?XuuSg8g*t34+z>aoGCZ(fE zTw_rz8T^VFXlMr>*EAN3HWnKT3SjoLg{=Z+|0>TO9vw5B2cakuW9&_~IS4CZfM%`B z_(OBQ-G?3mUn+fFDrZafP$99I`H3BB%wS)!Lg!e73^VVWw-;}TO^k?0Tq0$YSzId? zKrtJdNg+O_=`}(nrj^N!R69`;m@s_o4mZ$OY-aXX>QQJu)7FmknxZ;r?1oR0RfUu$ zeXNI~er71@%0nC9?&eDMb6zTqzE_>)QzmE6KG(M8GcDZy1e4qTvt4gLpU5ocB*&lk z!5j-u4XnqJ2gDyWq|yeBk%6Je1ZGx)MboKe)#H-E3^on;V>5iTOt$7ZtQy8>j+pfM zr>z%u3YuDW|URqABbIAwIg zlvmZ%=;s;x6Q5$+&(c(hh-#*Ea@qyAcs1nJC_b*#v63=i+waoU`}&INvCwpI+Rezs zXu;|~j#TE5l~UW<&$~A!?%17NmlxL?f_$r?OP%w+D1?{mC|F-7jBwi>+0zcrYyAUr zTj>*C5jptj+9!Ov(HdLFXP)4($6@kT%V$Mn)|m2yT2R{oRkMJ@odL8+q)pc-?a!fi$ng*c# zmtWB}!5Kv={inM$9oY7k163i#Q$4n|&!NX3-Y9DpeF+OF(;kz3EoPLC7We!oOwd(( zYmk=uGe%Z8w65%Dcev&(2xTk$itPnuDvRXKB7F zF)HOHK$iR@-1CAfyqX|07Bfc2*Y5=yxUDKz4dnS48)D}^md?RD6lH!j7jWa2ZeMn_ z7%2o#H_;F<4w>E~qJ@-Ko|i>rs0g^uCHfYpbFS*^^_ZBH3M@`HGgMmHRZS!p7tkcw zDX*nLICOI6aH8xhoD{in=iK(?^ouiMHVg`4>P}E(uo#B1v}|pI*pqD9j)#$q%}H_y869FryK2L3xWM=_Zw~9cVpqcTL+tzaNNZ7%QXY)d z*4kDX^^}cH&)?g%-=uTf-1fqe|7yOdkVDd3Ms3psSiEspt`K|M%ov2du{n5y13j9+ z^L|$v56FZym9UCvDN5lX=ZL0ONL)!QhFO85T#Ea1K%26~URk8UC~yxpe=bJeV~AB1 zyB$HH5T8!3`J{({d3ikV1ooCjb}Or+s3d2u@iHsXhDdr1I*NrdvRPFTH(W;YB&K>K z`kG$jt&}|vVxdXir^8;f1qL&df;{t>c8wK8aCa6m{xa^uH$9Qp~T-t$#SrHa7Gv!yR52yQ2^=X$fv zj4$l=vYH63CLg`~w3uuw?CJGFD-=yu$U9X17?l!c^zaAP(drimo0oo!h{{Aa9t*e|z_%BwTl_E*XsqNq#wiFyLn zex}D=v6I1$=3t zEXWn2ow?lTo**kYLEHBTHN=s3<_(ne66VusU3tza%^2_D)zNt9c_NzbcY6`6sv~}a z&t~SS-&J^tZB*#RH4uDG3I{YO@gZ(kDiQ$ua)`8pfiGN*ni~Cte=H4rRX%9tsD8fF zEsv4UPx+t(wv%qEfY~dIh12#Ep9_kPQ2L~m0IQ+L%;Yt>Mz0l83T7uxl-*|OQVn=C zFWrlf?-K=de7XhFYZXw2Z_zZIU==d-j!IM!5Gk4Ph!tkCUk`72NjLh0*oOD2XiMF| z|3pzz3SEmVp))T2r8+A2!tKj}FAJ#^8~#Luq5xzH#o!-`M8-8W3(@BQrd3i} zeM${xvL$jwd(jE4@RKagfshdg86(^C6DbitAu5|(#i{}L-%k?2(2@#8sXH*Kx`3YL zU$|cVK9v=m{pxeF4eehZO5p0T^J%)rwBqRbfc1V(wn*Z0lRFXG8jQXk-9&OR?S2R<2ANuZ+*u{3$EI$mA-Kn<(@nEGm8(4uKETZ?qS{R9%@<0k?i7|%3Xye! zBzt{HAVu{csm1utF|S=|J!cou-($OSiMg`>wE#lTFqr&fqDp@50BT>_Fqt>oPmAsH zXUH`Z{5s*Mpuw+NcYJQD$4s-|0~7kAF}r%z)ly94LN3qs%cZ%w;Xa_N-CPgvO3#UH zW>29F3QV>e-A3moTN9}=dsaWMM0^UkCog0*wzgx$5|pzW=Lvk~KJ;~6!D*(omDSc| zzPENek&`md;Z*rRRFz+3tv%&^NaDSj$rIGmAzUE!u32H-CsB4`Zq08nzV!5H1-rle zemhMEg7galn{7A6(H$(?A^z$Tc@|`B-7y~AG@`I;Ii*EF-29#g&{RLKQ zxIhfD9U5{HGP(($#?-xiD_51aZ(Jne_3QbX{#lkV@^Gu(gjM8zgK8{ZP3& z_Y4_<68Bt394O4A>?#n~MSirHpr(1;wxeZuFOXq(5wUqMnJ|Mh>t5zWUo&Nysh3M4 zEF?dosbSD}Wu|0VgP}R=Q!dz3gK6yMR4!$c?^e{75%@d0lBB=zd$?3FBLQ)nGuKf1 zAWh-bRQ6Z>x?+-tI4sh#=KPqe;TayTgt+*Qe_)zXcz5P(g+ncds5yWox1t>)PeSXoL*w-+}A#s_{+1GuoOs?ag^iudS_>#@iEF0b1yuy3>) zyRIw4N!g!CigVjBYw$38Cm8g}m&kIbqrjnE2Leisc!;jQHlA)WW?bPJ8~7@{>{Vm4 z%8Gmbe?V+(=!T01`nuA{_bs`x`A;a#v0#(7M>k*`s1Rn~>hz-y#pQ4W2-eKo7SmXb zF7RTFsOC6Rd`|WU@O9w`$dw0fe=&dvPxucqZwTZPXKfL_+}X`z0-rE0umekjbXL6g{-sR#^#&(jKd&*tUnQ^?{Rck8}qmcs4!U;|f(OE(8&(GleZ&N$jp zExavwsh!Qw->4ywlb6x>-2bB8{o|qPJLb6oEaggLJpInsKi~(ir4s168rO&+RZHOz zx>gpAm)2~*jlp;lh*c_pvJV8iKO1!Jc0P+Lc&>SF${ahs#Jn8+VcvAv^dl>3yAZrA_%8}(49f3o7&!+2 zTpQ@OV&{y$NtbM-p9E6Kr4!eHhno` zaaEuoLs&kIXGe{bBa{|~*sXjTtFN^hB868f3Ze3n^cX6D`6KOw6;1DJTk&$ce_Ano z#CMCR-Qn?vz)v69`40~12U2sWfD}?c_|pvz^rf;oSlE;itqz6dwd*H%HIzT@^evZX zN)nNRPbzX(Hlq;%eEF96bg!yIkD&R|w!w(~2oXZIN+LRpBt?d=ya3`Zxo$5dsAgHJ z{t7@BqaItc(GYfi;v#KTlbCVAnB?k{yJLSAi1F6DN=2*1=<4v-`7QHgL;ayjo&$i6 ze0jFkrU1Eq$87t`_^ZJ;L{JA4%aUA+o<>IENaF4I%4CCVx14pyguE|lr8!i*)Xye; z`N2L_F`YGUBk#6IJ2`ip1Q!WhfP5@5hnJr!spCF7e!Trk1YLx^<^616F;oZr{kg8| zv}=Ucgz_a9LWGmZUX3%bj^v3S$x3chqa$+loDvJHg?T63 z8*zQ*Vvz?#M7pDI5biIC)k<}wZV2ERZMX~SNU^M|JNi+OZ^r>pPq=^O>to{aE6|Xf z)?ZO_^mic`a=~Cu2j*L^O?h44a&)E={y*$}1ymJX_ctn_NOwp`gCGb9C@Bq60@5WR zed$gGq>=6tK@e%AQ>8_uq`SL2{Vu2odQtRwc-H@0>s^fFnRE8p`?ur7%$zxQ`7ZlJ z(M_>NdO3A$iH?Wk=1Ic7L$g=O(d@{Zb#aYtFySMM1=|IY?>1_{WxlZZU``6fU{#Gw z#_A~%a&h+}q@zO_Tbk_tH(<5%R7TczvYg4d%*rLLJ zI6VF;{<$d*cU39W7Cosb9?PvKG3PN2*AdTq#|T{8d0=m>JiPpb12M|pzs zQih8dzHe6z)*HTlowi7$OPye3K_y=ai{3)ouhD1>F4cN^i*_sfY5}+zL*yXRBac#x z5o~P$@z&@$Wb5UcTR|ziif{$IJP8{<=lbmJ+f1NfylJ*a#rQREP*KFmwHHazHtmS) zap!dIiH^4_Ita*YWQ%8p=GeNm4FpA_z)wl=_yE^)D>L0PD~R+jT%lrrQMl<+V9rWD zULR{(fY|=(>9XRE6Niqgb>dyQ%TNM-etB|2*mpmJ?U=0cH|!GY7nzwx)l`)g8^Tde zjm96L-WHt?}!@T9h&Bq;9Vw+UQ@StCThp?y&$q?Sr zYv(iAZXPGQdw)%E5qs^lPke(lI{V_Icp11+~k~iDk17c<`{WBZuCq+{+>_~%{yi^m!2qG%hOj1+tI+N zWKwRqN=mRKF3vKzF_BLV(_fB*ugQ|aiqy)3kW}Ex#8rxKP-P7li;okM9*yNhEG;ly z)82=KpvAl))hztpmCf=+TQ?%a4ATBd{NU8yPF^!o%O^o@L4|MF0D$XPCiG;NXLa^4 zS12=8kB_=!irho+(KoZ&X>rF)Y{#h~aKbrWC;~WAdXN{SiOy44t=q_w5YGt7W%l0_ z7(?BWTN^E6GY(A4>PEcyafG3QV;iBp{d$*eB{?fk;M#Bng%IA3#n=l22-;p&4)aAw z5C2#hCg_4GX(KOT`8r`c3ALpC!P4i3nQpssQ%GwpL=9mw*RZQap?3PZAO}G2KRS%2ctK@X1!xMIdm5#Km{W1s@F%~ zRetbcjHgeUohlX^ZPta#7!qiyueefJ-gfTN=)Dw?5WlWD-R%ER_2T+e8$Q*mi>92} zuC7eNYH^E=mj(PEhhB$80e4y#uxchv@)^OkP2^eau=UM*I~F))4LYhTR0l)2=!_t~-nj+ZGiftD;$oZ>eKVcCihKfeR z!&mJM_5cMS(7r4`8n+EMKhDBC#r3>0l-uF-7L|MF%xrf43pIF;4b;1PHJz6E_~{h zgzs&dyobd|!^RWv&&4g|NmuVM)UIM`-;J2o6Os*hlgfOylcu=9Pfsygd-tbM&gfU4 zrlM!)`YWk0S=vGjX=cnfDwdkQx+YK|Kj8-*X-eitTFy&s{u#^;y~*#|^U?R(WUn{I z*HZct4I?>9i`{va5<(vs!RYKTnIV4fO^bc<=d#-`mnvL?SYm04uyVWlf(udI%_b4S zIiUiznSbnh78vkj%YHSBB|AsvD`f#Qh#kEm__L zbQJ4N?aAekm5H7*dga@ns+Zu|B%UufhkS}svCX=vul&4l6Eb0Hi3v)^{qZ?Yvs8x{ zMN=2LsDV@0J2pIf!SgTSwaS`%SI^C&182L>Sf2ysTYS3MuRNid7R?I(T$w7Mk`P?u zg7m?BZ@(wc!BZ?J(dC)p$7pd^XfvgAo3Lfn$Q}|maxuY#c_pGu;ycs0m4K=In(LJT z|3aUG2A31f<+`C)1ZS|o7X;7fzk8$&>gi+iO^4#Q%KWMBt{xtSCP*ku z;mKKc-8&H)qD2k?dbR5YOMo!8**)Rcq`hVJMM3R%Tf_8;H$5fHLuisdgQ=LUVA4jh znJ0=$i2G&|V7As5ikj9CD=}NYmQS;5kcMmjRS&{6BHfx&JR%l*u3~wFDI&4LXB#

`b%zWJVoybJJC+al7(vmUoDSw-d(zU?;>j| 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 - - - - - edge0 - OpenEMS Edge #0 - DEMO_API_KEY - - - - diff --git a/odoo/extra-addons/openems/data/ir_config_parameter.xml b/odoo/extra-addons/openems/data/ir_config_parameter.xml deleted file mode 100644 index b1da5cf..0000000 --- a/odoo/extra-addons/openems/data/ir_config_parameter.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - - - edge_monitoring_url - http://localhost:8082/device/ - - - diff --git a/odoo/extra-addons/openems/data/res_partner_category.xml b/odoo/extra-addons/openems/data/res_partner_category.xml deleted file mode 100644 index f56c0e0..0000000 --- a/odoo/extra-addons/openems/data/res_partner_category.xml +++ /dev/null @@ -1,11 +0,0 @@ - - - - - Created via IBN - - - Customer - - - diff --git a/odoo/extra-addons/openems/i18n/de.po b/odoo/extra-addons/openems/i18n/de.po deleted file mode 100644 index cc4c660..0000000 --- a/odoo/extra-addons/openems/i18n/de.po +++ /dev/null @@ -1,1666 +0,0 @@ -# Translation of Odoo Server. -# This file contains the translation of the following modules: -# * openems -# -msgid "" -msgstr "" -"Project-Id-Version: Odoo Server 16.0-20240218\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2024-02-18 11:57+0000\n" -"PO-Revision-Date: 2024-02-18 11:57+0000\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: openems -#: model:mail.template,body_html:openems.setup_protocol_email_installer -msgid "" -"\n" -"\n" -"\n" -"\n" -"\n" -" OpenEMS setup protocol \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -"\n" -"\n" -"\n" -"

\n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -"
\n" -" \n" -"
\n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -"
\n" -" \n" -"
\n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -"
\n" -"

\n" -"

\n" -" \n" -"
\n" -"
Dear \n" -" ,\n" -"
\n" -"
\n" -"
please find the setup protocol for your customer attached.\n" -"
\n" -"
\n" -"
Best Regards
\n" -"
\n" -"
OpenEMS Association e.V.
\n" -"
\n" -"
\n" -" \n" -"
\n" -"
\n" -" \n" -"
\n" -"
\n" -"\n" -"\n" -"\n" -" \n" -" " -msgstr "" - -#. module: openems -#: model:mail.template,body_html:openems.registration_email -msgid "" -"\n" -"\n" -"\n" -"\n" -"\n" -" Registrierung erfolgreich \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -"\n" -"\n" -"\n" -"
\n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -"
\n" -" \n" -"
\n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -"
\n" -" \n" -"
\n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -"
\n" -"

\n" -"

\n" -" \n" -"
\n" -"
Guten Tag \n" -" ,\n" -"
\n" -"
\n" -"
Ihr Zugang zu OpenEMS UI wurde erstellt.
\n" -"
\n" -"
Sie können sich auf OpenEMS UI einloggen, um auf das Online-Monitoring zuzugreifen.
\n" -"
\n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -"
Ihre Zugangsdaten:
E-Mail\n" -" \n" -"
Passwort\n" -" \n" -"
\n" -"
\n" -"
Best Regards
\n" -"
\n" -"
OpenEMS Association e.V.
\n" -"
\n" -"
\n" -" \n" -"
\n" -"
\n" -" \n" -"
\n" -"
\n" -"\n" -"\n" -"\n" -" \n" -" " -msgstr "" - -#. module: openems -#: model:mail.template,body_html:openems.setup_protocol_email_customer -msgid "" -"\n" -"\n" -"\n" -"\n" -"\n" -" Your OpenEMS Edge setup protocol \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -"\n" -"\n" -"\n" -"
\n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -"
\n" -" \n" -"
\n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -"
\n" -" \n" -"
\n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -"
\n" -"

\n" -"

\n" -" \n" -"
\n" -"
Welcome to OpenEMS,
\n" -"
\n" -"
please find your setup protocol for OpenEMS Edge attached.
\n" -"
\n" -"
Best Regards
\n" -"
\n" -"
OpenEMS Association e.V.
\n" -"
\n" -"
\n" -" \n" -"
\n" -"
\n" -" \n" -"
\n" -"
\n" -"\n" -"\n" -"\n" -" \n" -" " -msgstr "" - -#. module: openems -#: model:mail.template,body_html:openems.alerting_email_generic -msgid "" -"\n" -"\n" -"\n" -"\n" -"\n" -" OpenEMS Alert - Edge is offline\n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -"\n" -"\n" -"\n" -"
\n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -"
\n" -" \n" -"
\n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -"
\n" -" \n" -"
\n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -"
\n" -"

\n" -"

\n" -" \n" -"
\n" -"
Dear \n" -" ,\n" -"
\n" -"
\n" -"
Your OpenEMS Edge with number is offline since:
\n" -"
\n" -"
\n" -" \n" -" \n" -" \n" -" \n" -" \n" -" (UTC)\n" -" \n" -"
\n" -"
\n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -"
Info
\n" -" Edge-Version\n" -" \n" -" \n" -"
\n" -" Type\n" -" \n" -" \n" -" \n" -"
\n" -"
\n" -"
Best Regards
\n" -"
\n" -"
OpenEMS Association e.V.
\n" -"
\n" -"
\n" -" \n" -"
\n" -"
\n" -" \n" -"
\n" -" \n" -"
\n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -"
\n" -" \n" -"
\n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -"
\n" -"
Wenn Sie keine E-Mail Benachrichtigung mehr wünschen, können Sie die Funktion hier deaktivieren.
\n" -"
\n" -"
Dies ist eine automatisch generierte Nachricht. Bitte antworten Sie nicht auf diese Nachricht!
\n" -"
\n" -"
\n" -" \n" -"
\n" -"
\n" -" \n" -"
\n" -"\n" -"\n" -"\n" -" \n" -" " -msgstr "" - -#. module: openems -#: model:ir.actions.report,print_report_name:openems.action_openems_setup_protocol_report -msgid "" -"('IBN-' + object.openems_device_id.name + '-' + " -"object.create_date.strftime('%d.%m.%Y'))" -msgstr "" - -#. module: openems -#: model:ir.model.fields,field_description:openems.field_openems_device__apikey -msgid "API-Key" -msgstr "" - -#. module: openems -#: model_terms:ir.ui.view,arch_db:openems.openems_device_form -msgid "Access Role in Online-Monitoring" -msgstr "Zugriffsrollen im Online-Monitoring" - -#. module: openems -#: model:ir.model.fields,field_description:openems.field_openems_device__message_needaction -msgid "Action Needed" -msgstr "" - -#. module: openems -#: model:ir.model.fields,field_description:openems.field_openems_device__active -msgid "Active" -msgstr "" - -#. module: openems -#: model:ir.model.fields.selection,name:openems.selection__openems_device_user_role__role__admin -#: model:ir.model.fields.selection,name:openems.selection__res_users__global_role__admin -msgid "Admin" -msgstr "" - -#. module: openems -#: model:ir.ui.menu,name:openems.menu_openems_admin -msgid "Administration" -msgstr "" - -#. module: openems -#: model_terms:ir.ui.view,arch_db:openems.device_search_view -msgid "Archived" -msgstr "" - -#. module: openems -#: model:ir.model.fields,field_description:openems.field_openems_device__message_attachment_count -msgid "Attachment Count" -msgstr "" - -#. module: openems -#: model:ir.model.fields,field_description:openems.field_res_users__branding_partner_id -msgid "Branding Partner" -msgstr "" - -#. module: openems -#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol_item__category -#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol_production_lot__category -msgid "Category" -msgstr "" - -#. module: openems -#: model:ir.model.fields,field_description:openems.field_openems_device__comment -msgid "Comment" -msgstr "" - -#. module: openems -#: model_terms:ir.ui.view,arch_db:openems.openems_device_form -msgid "Configuration" -msgstr "Konfiguration" - -#. module: openems -#: model_terms:ir.ui.view,arch_db:openems.openems_device_form -msgid "Configuration Updates" -msgstr "Konfigurationsänderungen" - -#. module: openems -#: model:ir.model,name:openems.model_res_partner -msgid "Contact" -msgstr "Kontakt" - -#. module: openems -#: model:ir.model.fields,field_description:openems.field_openems_device__create_uid -#: model:ir.model.fields,field_description:openems.field_openems_device_tag__create_uid -#: model:ir.model.fields,field_description:openems.field_openems_device_user_role__create_uid -#: model:ir.model.fields,field_description:openems.field_openems_openemsconfigupdate__create_uid -#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol__create_uid -#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol_item__create_uid -#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol_production_lot__create_uid -#: model:ir.model.fields,field_description:openems.field_openems_systemmessage__create_uid -msgid "Created by" -msgstr "" - -#. module: openems -#: model:ir.model.fields,field_description:openems.field_openems_device__create_date -#: model:ir.model.fields,field_description:openems.field_openems_device_tag__create_date -#: model:ir.model.fields,field_description:openems.field_openems_device_user_role__create_date -#: model:ir.model.fields,field_description:openems.field_openems_openemsconfigupdate__create_date -#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol__create_date -#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol_item__create_date -#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol_production_lot__create_date -#: model:ir.model.fields,field_description:openems.field_openems_systemmessage__create_date -msgid "Created on" -msgstr "" - -#. module: openems -#: model:res.partner.category,name:openems.res_partner_category_created_via_ibn -msgid "Created via IBN" -msgstr "" - -#. module: openems -#: model:ir.model.fields,field_description:openems.field_openems_systemmessage__timestamp -msgid "Creation date" -msgstr "" - -#. module: openems -#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol__customer_id -#: model:res.partner.category,name:openems.res_partner_category_customer -msgid "Customer" -msgstr "" - -#. module: openems -#: model:ir.model.fields.selection,name:openems.selection__res_users__openems_language__cz -msgid "Czech" -msgstr "" - -#. module: openems -#: model_terms:ir.ui.view,arch_db:openems.report_openems_setup_protocol_template -msgid "Datum:" -msgstr "" - -#. module: openems -#: model_terms:ir.ui.view,arch_db:openems.device_search_view -#: model_terms:ir.ui.view,arch_db:openems.openems_device_tree -msgid "Description" -msgstr "Bezeichnung" - -#. module: openems -#: model_terms:ir.ui.view,arch_db:openems.openems_openemsconfigupdate_tree -msgid "Details" -msgstr "" - -#. module: openems -#: model:ir.model.fields,field_description:openems.field_stock_lot__device_id -#: model:ir.model.fields,field_description:openems.field_stock_lot__device_ids -msgid "Device" -msgstr "" - -#. module: openems -#: model:ir.actions.act_window,name:openems.action_openems_openemsconfigupdate -#: model:ir.ui.menu,name:openems.menu_openems_admin_openemsconfigupdate -msgid "Device Configuration Updates" -msgstr "" - -#. module: openems -#: model:ir.actions.act_window,name:openems.action_openems_device -#: model:ir.ui.menu,name:openems.menu_openems_content_devices -msgid "Devices" -msgstr "" - -#. module: openems -#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol__different_location_id -msgid "Different Location" -msgstr "" - -#. module: openems -#: model:ir.model.fields,field_description:openems.field_openems_device__display_name -#: model:ir.model.fields,field_description:openems.field_openems_device_tag__display_name -#: model:ir.model.fields,field_description:openems.field_openems_device_user_role__display_name -#: model:ir.model.fields,field_description:openems.field_openems_openemsconfigupdate__display_name -#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol__display_name -#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol_item__display_name -#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol_production_lot__display_name -#: model:ir.model.fields,field_description:openems.field_openems_systemmessage__display_name -msgid "Display Name" -msgstr "" - -#. module: openems -#: model:ir.model.fields.selection,name:openems.selection__res_users__openems_language__nl -msgid "Dutch" -msgstr "" - -#. module: openems -#: model:mail.template,name:openems.alerting_email_generic -msgid "E-Mail Alerting" -msgstr "" - -#. module: openems -#: model:mail.template,name:openems.registration_email -msgid "E-Mail Kunden Registrierung" -msgstr "" - -#. module: openems -#: model:mail.template,name:openems.setup_protocol_email_customer -msgid "E-Mail setup protocol for customer" -msgstr "" - -#. module: openems -#: model:mail.template,name:openems.setup_protocol_email_installer -msgid "E-Mail setup protocol for installer" -msgstr "" - -#. module: openems -#: model_terms:ir.ui.view,arch_db:openems.report_openems_setup_protocol_template -msgid "E-Mail-Adresse" -msgstr "" - -#. module: openems -#: model:ir.model.fields,field_description:openems.field_openems_device__emshardware -msgid "EMS Hardware" -msgstr "" - -#. module: openems -#: model:ir.model.fields.selection,name:openems.selection__res_users__openems_language__en -msgid "English" -msgstr "" - -#. module: openems -#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol__item_ids -msgid "Entry Items" -msgstr "" - -#. module: openems -#: model:ir.model.fields.selection,name:openems.selection__openems_device__openems_sum_state_level__fault -msgid "Fault" -msgstr "" - -#. module: openems -#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol_item__field -msgid "Field Identifier" -msgstr "" - -#. module: openems -#: model_terms:ir.ui.view,arch_db:openems.report_openems_setup_protocol_template -msgid "Firmenname" -msgstr "" - -#. module: openems -#: model:ir.model.fields,field_description:openems.field_openems_device__first_setup_protocol_date -msgid "First Setup Protocol Date" -msgstr "" - -#. module: openems -#: model:ir.model.fields,field_description:openems.field_openems_device__message_follower_ids -msgid "Followers" -msgstr "" - -#. module: openems -#: model:ir.model.fields,field_description:openems.field_openems_device__message_partner_ids -msgid "Followers (Partners)" -msgstr "" - -#. module: openems -#: model:ir.model.fields.selection,name:openems.selection__res_users__openems_language__fr -msgid "French" -msgstr "" - -#. module: openems -#: model_terms:ir.ui.view,arch_db:openems.openems_device_form -msgid "General" -msgstr "" - -#. module: openems -#: model:ir.model.fields.selection,name:openems.selection__res_users__openems_language__de -msgid "German" -msgstr "" - -#. module: openems -#: model:ir.model.fields,field_description:openems.field_res_users__global_role -msgid "Global Role" -msgstr "" - -#. module: openems -#: model:ir.model.fields.selection,name:openems.selection__openems_device_user_role__role__guest -#: model:ir.model.fields.selection,name:openems.selection__res_users__global_role__guest -msgid "Guest" -msgstr "" - -#. module: openems -#: model_terms:ir.ui.view,arch_db:openems.openems_device_form -msgid "Hardware" -msgstr "" - -#. module: openems -#: model:ir.model.fields,field_description:openems.field_openems_device__has_message -msgid "Has Message" -msgstr "" - -#. module: openems -#: model:ir.model.fields.selection,name:openems.selection__res_users__openems_language__hu -msgid "Hungarian" -msgstr "" - -#. module: openems -#: model:ir.model.fields,field_description:openems.field_openems_device__id -#: model:ir.model.fields,field_description:openems.field_openems_device_tag__id -#: model:ir.model.fields,field_description:openems.field_openems_device_user_role__id -#: model:ir.model.fields,field_description:openems.field_openems_openemsconfigupdate__id -#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol__id -#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol_item__id -#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol_production_lot__id -#: model:ir.model.fields,field_description:openems.field_openems_systemmessage__id -msgid "ID" -msgstr "" - -#. module: openems -#: model:ir.model.fields,help:openems.field_openems_device__message_needaction -msgid "If checked, new messages require your attention." -msgstr "" - -#. module: openems -#: model:ir.model.fields,help:openems.field_openems_device__message_has_error -#: model:ir.model.fields,help:openems.field_openems_device__message_has_sms_error -msgid "If checked, some messages have a delivery error." -msgstr "" - -#. module: openems -#: model:ir.model.fields.selection,name:openems.selection__openems_device__openems_sum_state_level__info -msgid "Info" -msgstr "" - -#. module: openems -#: model_terms:ir.ui.view,arch_db:openems.report_openems_setup_protocol_template -msgid "Installateur" -msgstr "" - -#. module: openems -#: model_terms:ir.ui.view,arch_db:openems.openems_device_form -msgid "Installation" -msgstr "Inbetriebnahme" - -#. module: openems -#: model_terms:ir.ui.view,arch_db:openems.openems_device_form -msgid "Installation Log" -msgstr "Inbetriebnahme Protokolle" - -#. module: openems -#: model:ir.model.fields,field_description:openems.field_openems_device__setup_password -msgid "Installation key" -msgstr "Installateursschlüssel" - -#. module: openems -#: model:ir.model.fields,field_description:openems.field_res_partner__installer_setup_protocols_ids -#: model:ir.model.fields,field_description:openems.field_res_users__installer_setup_protocols_ids -msgid "Installed OpenEMS Edge" -msgstr "" - -#. module: openems -#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol__installer_id -#: model:ir.model.fields.selection,name:openems.selection__openems_device_user_role__role__installer -#: model:ir.model.fields.selection,name:openems.selection__res_users__global_role__installer -msgid "Installer" -msgstr "" - -#. module: openems -#: model:ir.model.fields,field_description:openems.field_openems_device__internalnote -msgid "Internal note" -msgstr "" - -#. module: openems -#: model:ir.model.fields,field_description:openems.field_openems_device__message_is_follower -msgid "Is Follower" -msgstr "" - -#. module: openems -#: model_terms:ir.ui.view,arch_db:openems.openems_device_form -msgid "Is connected" -msgstr "" - -#. module: openems -#: model_terms:ir.ui.view,arch_db:openems.report_openems_setup_protocol_template -msgid "Kontaktdaten Endkunde" -msgstr "" - -#. module: openems -#: model_terms:ir.ui.view,arch_db:openems.report_openems_setup_protocol_template -msgid "Land" -msgstr "" - -#. module: openems -#: model:ir.model.fields,field_description:openems.field_openems_device____last_update -#: model:ir.model.fields,field_description:openems.field_openems_device_tag____last_update -#: model:ir.model.fields,field_description:openems.field_openems_device_user_role____last_update -#: model:ir.model.fields,field_description:openems.field_openems_openemsconfigupdate____last_update -#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol____last_update -#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol_item____last_update -#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol_production_lot____last_update -#: model:ir.model.fields,field_description:openems.field_openems_systemmessage____last_update -msgid "Last Modified on" -msgstr "" - -#. module: openems -#: model:ir.model.fields,field_description:openems.field_openems_device__write_uid -#: model:ir.model.fields,field_description:openems.field_openems_device_tag__write_uid -#: model:ir.model.fields,field_description:openems.field_openems_device_user_role__write_uid -#: model:ir.model.fields,field_description:openems.field_openems_openemsconfigupdate__write_uid -#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol__write_uid -#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol_item__write_uid -#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol_production_lot__write_uid -#: model:ir.model.fields,field_description:openems.field_openems_systemmessage__write_uid -msgid "Last Updated by" -msgstr "" - -#. module: openems -#: model:ir.model.fields,field_description:openems.field_openems_device__write_date -#: model:ir.model.fields,field_description:openems.field_openems_device_tag__write_date -#: model:ir.model.fields,field_description:openems.field_openems_device_user_role__write_date -#: model:ir.model.fields,field_description:openems.field_openems_openemsconfigupdate__write_date -#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol__write_date -#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol_item__write_date -#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol_production_lot__write_date -#: model:ir.model.fields,field_description:openems.field_openems_systemmessage__write_date -msgid "Last Updated on" -msgstr "" - -#. module: openems -#: model:ir.model.fields,field_description:openems.field_openems_device__lastupdate -msgid "Last data update" -msgstr "" - -#. module: openems -#: model:ir.model.fields,field_description:openems.field_openems_device__lastmessage -msgid "Last message" -msgstr "" - -#. module: openems -#: model:ir.model.fields,field_description:openems.field_openems_device_user_role__last_notification -msgid "Last notification sent" -msgstr "" - -#. module: openems -#: model:ir.model,name:openems.model_stock_lot -msgid "Lot/Serial" -msgstr "Los/Serie" - -#. module: openems -#: model:ir.model.fields,field_description:openems.field_openems_device__message_main_attachment_id -msgid "Main Attachment" -msgstr "" - -#. module: openems -#: model:res.groups,name:openems.group_openems_manager -msgid "Manager" -msgstr "" - -#. module: openems -#: model:ir.model.fields,field_description:openems.field_openems_device__manual_setup_date -msgid "Manual Setup Date" -msgstr "" - -#. module: openems -#: model:res.groups,comment:openems.group_openems_manager -msgid "Members of this group can manage all devices" -msgstr "" - -#. module: openems -#: model:res.groups,comment:openems.group_openems_reader -msgid "Members of this group have reading access to all devices" -msgstr "" - -#. module: openems -#: model:ir.model.fields,field_description:openems.field_openems_systemmessage__text -msgid "Message" -msgstr "" - -#. module: openems -#: model:ir.model.fields,field_description:openems.field_openems_device__message_has_error -msgid "Message Delivery error" -msgstr "" - -#. module: openems -#: model:ir.model.fields,field_description:openems.field_openems_device__message_ids -msgid "Messages" -msgstr "" - -#. module: openems -#: model:ir.model.fields,field_description:openems.field_openems_device__name -#: model:ir.model.fields,field_description:openems.field_openems_device_tag__name -#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol_item__name -#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol_production_lot__name -msgid "Name" -msgstr "" - -#. module: openems -#: model_terms:ir.ui.view,arch_db:openems.report_openems_setup_protocol_template -msgid "Name Installateur" -msgstr "" - -#. module: openems -#: model_terms:ir.ui.view,arch_db:openems.report_openems_setup_protocol_template -msgid "Name Kontaktperson" -msgstr "" - -#. module: openems -#: model:ir.model.fields,field_description:openems.field_openems_device__name_number -msgid "Name Number" -msgstr "" - -#. module: openems -#: model:ir.model.constraint,message:openems.constraint_openems_device_unique_name -msgid "Name needs to be unique" -msgstr "" - -#. module: openems -#: model:ir.model.fields,field_description:openems.field_openems_device_user_role__time_to_wait -msgid "Notification" -msgstr "" - -#. module: openems -#: model:ir.model.fields,field_description:openems.field_openems_device__message_needaction_counter -msgid "Number of Actions" -msgstr "" - -#. module: openems -#: model:ir.model.fields,field_description:openems.field_openems_device__message_has_error_counter -msgid "Number of errors" -msgstr "" - -#. module: openems -#: model:ir.model.fields,help:openems.field_openems_device__message_needaction_counter -msgid "Number of messages requiring action" -msgstr "" - -#. module: openems -#: model:ir.model.fields,help:openems.field_openems_device__message_has_error_counter -msgid "Number of messages with delivery error" -msgstr "" - -#. module: openems -#: model_terms:ir.ui.view,arch_db:openems.openems_device_tree -msgid "OE Connected" -msgstr "" - -#. module: openems -#: model_terms:ir.ui.view,arch_db:openems.openems_device_tree -msgid "OE State" -msgstr "" - -#. module: openems -#: model_terms:ir.ui.view,arch_db:openems.openems_device_tree -msgid "OE Version" -msgstr "" - -#. module: openems -#: model:ir.model.fields,field_description:openems.field_openems_device__oem -msgid "OEM Branding" -msgstr "" - -#. module: openems -#: model:ir.model.fields.selection,name:openems.selection__openems_device__openems_sum_state_level__ok -msgid "Ok" -msgstr "" - -#. module: openems -#: model:ir.model.fields,field_description:openems.field_openems_device__monitoring_url -msgid "Online-Monitoring" -msgstr "" - -#. module: openems -#: model:ir.model.fields.selection,name:openems.selection__openems_device__oem__openems -#: model:ir.module.category,name:openems.module_category_openems -#: model:ir.ui.menu,name:openems.menu_openems -#: model_terms:ir.ui.view,arch_db:openems.openems_users_form -msgid "OpenEMS" -msgstr "" - -#. module: openems -#: model:mail.template,subject:openems.alerting_email_generic -msgid "OpenEMS Alert - Edge is offline" -msgstr "" - -#. module: openems -#: model_terms:ir.ui.view,arch_db:openems.report_openems_setup_protocol_template -msgid "OpenEMS Association e.V." -msgstr "" - -#. module: openems -#: model:ir.model.fields,field_description:openems.field_openems_device__openems_config_components -msgid "OpenEMS Config" -msgstr "" - -#. module: openems -#: model:ir.model.fields,field_description:openems.field_openems_device__openems_config -msgid "OpenEMS Config Full" -msgstr "" - -#. module: openems -#: model:ir.model.fields,field_description:openems.field_openems_device__openems_config_update_ids -msgid "OpenEMS Config Updates" -msgstr "" - -#. module: openems -#: model_terms:ir.ui.view,arch_db:openems.openems_openemsconfigupdate_tree -msgid "OpenEMS Configuration Updates" -msgstr "" - -#. module: openems -#: model:ir.model.fields,field_description:openems.field_openems_device_user_role__device_id -#: model:ir.model.fields,field_description:openems.field_openems_openemsconfigupdate__device_id -#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol__device_id -#: model:ir.model.fields,field_description:openems.field_openems_systemmessage__device_id -#: model:ir.model.fields.selection,name:openems.selection__openems_device__producttype__openems-edge -#: model:ir.ui.menu,name:openems.menu_openems_content -msgid "OpenEMS Edge" -msgstr "" - -#. module: openems -#: model:ir.model,name:openems.model_openems_device -msgid "OpenEMS Edge Device" -msgstr "" - -#. module: openems -#: model:ir.model,name:openems.model_openems_openemsconfigupdate -msgid "OpenEMS Edge Device Configuration Update" -msgstr "" - -#. module: openems -#: model:ir.model,name:openems.model_openems_device_tag -msgid "OpenEMS Edge Device Tag" -msgstr "" - -#. module: openems -#: model:ir.model,name:openems.model_openems_device_user_role -msgid "OpenEMS Edge Device User Role" -msgstr "" - -#. module: openems -#: model:ir.model,name:openems.model_openems_setup_protocol_item -msgid "OpenEMS Edge Setup Protocol Entry Item" -msgstr "" - -#. module: openems -#: model:ir.model,name:openems.model_openems_setup_protocol_production_lot -msgid "OpenEMS Edge Setup Protocol Serial Number" -msgstr "" - -#. module: openems -#: model:ir.model,name:openems.model_openems_setup_protocol -msgid "OpenEMS Edge Setup Protocols (IBN)" -msgstr "" - -#. module: openems -#: model:ir.model,name:openems.model_openems_systemmessage -msgid "OpenEMS Edge Systemmessage" -msgstr "" - -#. module: openems -#: model:ir.model.fields,field_description:openems.field_openems_device__openems_is_connected -msgid "OpenEMS Is connected" -msgstr "" - -#. module: openems -#: model:ir.actions.report,name:openems.action_openems_setup_protocol_report -msgid "OpenEMS Setup Protocol" -msgstr "" - -#. module: openems -#: model:ir.model.fields,field_description:openems.field_openems_device__openems_sum_state_level -msgid "OpenEMS State" -msgstr "" - -#. module: openems -#: model:ir.model.fields,field_description:openems.field_openems_device__openems_version -#: model_terms:ir.ui.view,arch_db:openems.device_search_view -msgid "OpenEMS Version" -msgstr "" - -#. module: openems -#: model_terms:ir.ui.view,arch_db:openems.device_search_view -#: model_terms:ir.ui.view,arch_db:openems.openems_device_tree -msgid "OpenEMS-Number" -msgstr "" - -#. module: openems -#: model:ir.model.fields,field_description:openems.field_res_users__openems_language -msgid "Openems Language" -msgstr "" - -#. module: openems -#: model_terms:ir.ui.view,arch_db:openems.report_openems_setup_protocol_template -msgid "Ort" -msgstr "" - -#. module: openems -#: model:ir.model.fields.selection,name:openems.selection__openems_device_user_role__role__owner -#: model:ir.model.fields.selection,name:openems.selection__res_users__global_role__owner -msgid "Owner" -msgstr "" - -#. module: openems -#: model:ir.model.fields,field_description:openems.field_res_partner__customer_setup_protocols_ids -#: model:ir.model.fields,field_description:openems.field_res_users__customer_setup_protocols_ids -msgid "Owner of OpenEMS Edge" -msgstr "" - -#. module: openems -#: model_terms:ir.ui.view,arch_db:openems.report_openems_setup_protocol_template -msgid "PLZ" -msgstr "" - -#. module: openems -#: model:ir.model.fields,help:openems.field_openems_device__setup_password -msgid "Password for commissioning by the installer" -msgstr "Passwort für die Inbetriebnahme durch den Installateur" - -#. module: openems -#: model_terms:ir.ui.view,arch_db:openems.openems_setup_protocol_form -msgid "Print" -msgstr "" - -#. module: openems -#: model_terms:ir.ui.view,arch_db:openems.openems_device_form -msgid "Product" -msgstr "Produkt" - -#. module: openems -#: model:ir.model.fields,field_description:openems.field_openems_device__producttype -msgid "Product type" -msgstr "" - -#. module: openems -#: model:res.groups,name:openems.group_openems_reader -msgid "Read access" -msgstr "" - -#. module: openems -#: model:mail.template,subject:openems.registration_email -msgid "Registrierung erfolgreich" -msgstr "" - -#. module: openems -#: model:ir.model.fields,field_description:openems.field_openems_device_user_role__role -msgid "Role" -msgstr "" - -#. module: openems -#: model:ir.model.fields,field_description:openems.field_openems_device__user_role_ids -#: model:ir.model.fields,field_description:openems.field_res_users__device_role_ids -msgid "Roles" -msgstr "" - -#. module: openems -#: model:ir.model.fields,field_description:openems.field_openems_device__message_has_sms_error -msgid "SMS Delivery error" -msgstr "" - -#. module: openems -#: model_terms:ir.ui.view,arch_db:openems.openems_device_form -msgid "Security" -msgstr "Sicherheit" - -#. module: openems -#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol_production_lot__lot_id -msgid "Serial Number" -msgstr "" - -#. module: openems -#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol__productionlot_ids -msgid "Serial Numbers" -msgstr "" - -#. module: openems -#: model:ir.model.constraint,message:openems.constraint_openems_device_unique_stock_production_lot_id -msgid "Serial number needs to be unique" -msgstr "" - -#. module: openems -#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol_item__setup_protocol_id -#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol_production_lot__setup_protocol_id -#: model_terms:ir.ui.view,arch_db:openems.report_openems_setup_protocol_template -msgid "Setup Protocol" -msgstr "" - -#. module: openems -#: model:ir.actions.act_window,name:openems.action_openems_admin_setup_protocol -#: model:ir.model.fields,field_description:openems.field_openems_device__setup_protocol_ids -#: model:ir.ui.menu,name:openems.menu_openems_admin_setup_protocol -#: model_terms:ir.ui.view,arch_db:openems.res_partner_form -msgid "Setup Protocols" -msgstr "" - -#. module: openems -#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol_item__sequence -#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol_production_lot__sequence -msgid "Sort" -msgstr "" - -#. module: openems -#: model:ir.model.fields.selection,name:openems.selection__res_users__openems_language__es -msgid "Spanish" -msgstr "" - -#. module: openems -#: model_terms:ir.ui.view,arch_db:openems.report_openems_setup_protocol_template -msgid "Speicherstandort" -msgstr "" - -#. module: openems -#: model_terms:ir.ui.view,arch_db:openems.openems_device_form -msgid "Status" -msgstr "" - -#. module: openems -#: model:ir.model.fields,field_description:openems.field_openems_device__stock_production_lot_id -msgid "Stock Production Lot" -msgstr "" - -#. module: openems -#: model_terms:ir.ui.view,arch_db:openems.report_openems_setup_protocol_template -msgid "Straße / Hausnummer" -msgstr "" - -#. module: openems -#: model_terms:ir.ui.view,arch_db:openems.openems_device_form -msgid "System Messages" -msgstr "" - -#. module: openems -#: model:ir.actions.act_window,name:openems.action_openems_systemmessage -#: model:ir.model.fields,field_description:openems.field_openems_device__systemmessage_ids -#: model:ir.ui.menu,name:openems.menu_openems_admin_systemmessages -msgid "Systemmessages" -msgstr "" - -#. module: openems -#: model_terms:ir.ui.view,arch_db:openems.openems_device_form -msgid "Systemstatus" -msgstr "" - -#. module: openems -#: model:ir.model.fields,field_description:openems.field_openems_device__tag_ids -msgid "Tags" -msgstr "" - -#. module: openems -#: model_terms:ir.ui.view,arch_db:openems.report_openems_setup_protocol_template -msgid "Telefonnummer" -msgstr "" - -#. module: openems -#: model:ir.model.fields,field_description:openems.field_openems_systemmessage__text_teaser -msgid "Text Teaser" -msgstr "" - -#. module: openems -#: model:ir.model.fields,field_description:openems.field_openems_openemsconfigupdate__details -msgid "Update Details" -msgstr "" - -#. module: openems -#: model:ir.model.fields,field_description:openems.field_openems_openemsconfigupdate__teaser -msgid "Update Details Teaser" -msgstr "" - -#. module: openems -#: model:ir.model,name:openems.model_res_users -#: model:ir.model.fields,field_description:openems.field_openems_device_user_role__user_id -msgid "User" -msgstr "Benutzer" - -#. module: openems -#: model:ir.model.constraint,message:openems.constraint_openems_device_user_role_device_user_uniq -msgid "User already exists for this device." -msgstr "" - -#. module: openems -#: model_terms:ir.ui.view,arch_db:openems.openems_systemmessage_tree -msgid "Users" -msgstr "" - -#. module: openems -#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol_item__value -msgid "Value" -msgstr "" - -#. module: openems -#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol_item__view -msgid "View Identifier" -msgstr "" - -#. module: openems -#: model_terms:ir.ui.view,arch_db:openems.report_openems_setup_protocol_template -msgid "Vor- Nachname" -msgstr "" - -#. module: openems -#: model:ir.model.fields.selection,name:openems.selection__openems_device__openems_sum_state_level__warning -msgid "Warning" -msgstr "" - -#. module: openems -#: model:ir.model.fields,field_description:openems.field_openems_device__website_message_ids -msgid "Website Messages" -msgstr "" - -#. module: openems -#: model:ir.model.fields,help:openems.field_openems_device__website_message_ids -msgid "Website communication history" -msgstr "" - -#. module: openems -#: model:mail.template,subject:openems.setup_protocol_email_customer -#: model:mail.template,subject:openems.setup_protocol_email_installer -msgid "Your OpenEMS setup protocol for {{object.openems_device_id.name}}" -msgstr "" diff --git a/odoo/extra-addons/openems/i18n/openems.pot b/odoo/extra-addons/openems/i18n/openems.pot deleted file mode 100644 index c02fb93..0000000 --- a/odoo/extra-addons/openems/i18n/openems.pot +++ /dev/null @@ -1,1666 +0,0 @@ -# Translation of Odoo Server. -# This file contains the translation of the following modules: -# * openems -# -msgid "" -msgstr "" -"Project-Id-Version: Odoo Server 16.0-20240218\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2024-02-18 11:56+0000\n" -"PO-Revision-Date: 2024-02-18 11:56+0000\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: openems -#: model:mail.template,body_html:openems.setup_protocol_email_installer -msgid "" -"\n" -"\n" -"\n" -"\n" -"\n" -" OpenEMS setup protocol \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -"\n" -"\n" -"\n" -"
\n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -"
\n" -" \n" -"
\n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -"
\n" -" \n" -"
\n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -"
\n" -"

\n" -"

\n" -" \n" -"
\n" -"
Dear \n" -" ,\n" -"
\n" -"
\n" -"
please find the setup protocol for your customer attached.\n" -"
\n" -"
\n" -"
Best Regards
\n" -"
\n" -"
OpenEMS Association e.V.
\n" -"
\n" -"
\n" -" \n" -"
\n" -"
\n" -" \n" -"
\n" -"
\n" -"\n" -"\n" -"\n" -" \n" -" " -msgstr "" - -#. module: openems -#: model:mail.template,body_html:openems.registration_email -msgid "" -"\n" -"\n" -"\n" -"\n" -"\n" -" Registrierung erfolgreich \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -"\n" -"\n" -"\n" -"
\n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -"
\n" -" \n" -"
\n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -"
\n" -" \n" -"
\n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -"
\n" -"

\n" -"

\n" -" \n" -"
\n" -"
Guten Tag \n" -" ,\n" -"
\n" -"
\n" -"
Ihr Zugang zu OpenEMS UI wurde erstellt.
\n" -"
\n" -"
Sie können sich auf OpenEMS UI einloggen, um auf das Online-Monitoring zuzugreifen.
\n" -"
\n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -"
Ihre Zugangsdaten:
E-Mail\n" -" \n" -"
Passwort\n" -" \n" -"
\n" -"
\n" -"
Best Regards
\n" -"
\n" -"
OpenEMS Association e.V.
\n" -"
\n" -"
\n" -" \n" -"
\n" -"
\n" -" \n" -"
\n" -"
\n" -"\n" -"\n" -"\n" -" \n" -" " -msgstr "" - -#. module: openems -#: model:mail.template,body_html:openems.setup_protocol_email_customer -msgid "" -"\n" -"\n" -"\n" -"\n" -"\n" -" Your OpenEMS Edge setup protocol \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -"\n" -"\n" -"\n" -"
\n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -"
\n" -" \n" -"
\n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -"
\n" -" \n" -"
\n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -"
\n" -"

\n" -"

\n" -" \n" -"
\n" -"
Welcome to OpenEMS,
\n" -"
\n" -"
please find your setup protocol for OpenEMS Edge attached.
\n" -"
\n" -"
Best Regards
\n" -"
\n" -"
OpenEMS Association e.V.
\n" -"
\n" -"
\n" -" \n" -"
\n" -"
\n" -" \n" -"
\n" -"
\n" -"\n" -"\n" -"\n" -" \n" -" " -msgstr "" - -#. module: openems -#: model:mail.template,body_html:openems.alerting_email_generic -msgid "" -"\n" -"\n" -"\n" -"\n" -"\n" -" OpenEMS Alert - Edge is offline\n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -"\n" -"\n" -"\n" -"
\n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -"
\n" -" \n" -"
\n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -"
\n" -" \n" -"
\n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -"
\n" -"

\n" -"

\n" -" \n" -"
\n" -"
Dear \n" -" ,\n" -"
\n" -"
\n" -"
Your OpenEMS Edge with number is offline since:
\n" -"
\n" -"
\n" -" \n" -" \n" -" \n" -" \n" -" \n" -" (UTC)\n" -" \n" -"
\n" -"
\n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -"
Info
\n" -" Edge-Version\n" -" \n" -" \n" -"
\n" -" Type\n" -" \n" -" \n" -" \n" -"
\n" -"
\n" -"
Best Regards
\n" -"
\n" -"
OpenEMS Association e.V.
\n" -"
\n" -"
\n" -" \n" -"
\n" -"
\n" -" \n" -"
\n" -" \n" -"
\n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -"
\n" -" \n" -"
\n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -"
\n" -"
Wenn Sie keine E-Mail Benachrichtigung mehr wünschen, können Sie die Funktion hier deaktivieren.
\n" -"
\n" -"
Dies ist eine automatisch generierte Nachricht. Bitte antworten Sie nicht auf diese Nachricht!
\n" -"
\n" -"
\n" -" \n" -"
\n" -"
\n" -" \n" -"
\n" -"\n" -"\n" -"\n" -" \n" -" " -msgstr "" - -#. module: openems -#: model:ir.actions.report,print_report_name:openems.action_openems_setup_protocol_report -msgid "" -"('IBN-' + object.openems_device_id.name + '-' + " -"object.create_date.strftime('%d.%m.%Y'))" -msgstr "" - -#. module: openems -#: model:ir.model.fields,field_description:openems.field_openems_device__apikey -msgid "API-Key" -msgstr "" - -#. module: openems -#: model_terms:ir.ui.view,arch_db:openems.openems_device_form -msgid "Access Role in Online-Monitoring" -msgstr "" - -#. module: openems -#: model:ir.model.fields,field_description:openems.field_openems_device__message_needaction -msgid "Action Needed" -msgstr "" - -#. module: openems -#: model:ir.model.fields,field_description:openems.field_openems_device__active -msgid "Active" -msgstr "" - -#. module: openems -#: model:ir.model.fields.selection,name:openems.selection__openems_device_user_role__role__admin -#: model:ir.model.fields.selection,name:openems.selection__res_users__global_role__admin -msgid "Admin" -msgstr "" - -#. module: openems -#: model:ir.ui.menu,name:openems.menu_openems_admin -msgid "Administration" -msgstr "" - -#. module: openems -#: model_terms:ir.ui.view,arch_db:openems.device_search_view -msgid "Archived" -msgstr "" - -#. module: openems -#: model:ir.model.fields,field_description:openems.field_openems_device__message_attachment_count -msgid "Attachment Count" -msgstr "" - -#. module: openems -#: model:ir.model.fields,field_description:openems.field_res_users__branding_partner_id -msgid "Branding Partner" -msgstr "" - -#. module: openems -#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol_item__category -#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol_production_lot__category -msgid "Category" -msgstr "" - -#. module: openems -#: model:ir.model.fields,field_description:openems.field_openems_device__comment -msgid "Comment" -msgstr "" - -#. module: openems -#: model_terms:ir.ui.view,arch_db:openems.openems_device_form -msgid "Configuration" -msgstr "" - -#. module: openems -#: model_terms:ir.ui.view,arch_db:openems.openems_device_form -msgid "Configuration Updates" -msgstr "" - -#. module: openems -#: model:ir.model,name:openems.model_res_partner -msgid "Contact" -msgstr "" - -#. module: openems -#: model:ir.model.fields,field_description:openems.field_openems_device__create_uid -#: model:ir.model.fields,field_description:openems.field_openems_device_tag__create_uid -#: model:ir.model.fields,field_description:openems.field_openems_device_user_role__create_uid -#: model:ir.model.fields,field_description:openems.field_openems_openemsconfigupdate__create_uid -#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol__create_uid -#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol_item__create_uid -#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol_production_lot__create_uid -#: model:ir.model.fields,field_description:openems.field_openems_systemmessage__create_uid -msgid "Created by" -msgstr "" - -#. module: openems -#: model:ir.model.fields,field_description:openems.field_openems_device__create_date -#: model:ir.model.fields,field_description:openems.field_openems_device_tag__create_date -#: model:ir.model.fields,field_description:openems.field_openems_device_user_role__create_date -#: model:ir.model.fields,field_description:openems.field_openems_openemsconfigupdate__create_date -#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol__create_date -#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol_item__create_date -#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol_production_lot__create_date -#: model:ir.model.fields,field_description:openems.field_openems_systemmessage__create_date -msgid "Created on" -msgstr "" - -#. module: openems -#: model:res.partner.category,name:openems.res_partner_category_created_via_ibn -msgid "Created via IBN" -msgstr "" - -#. module: openems -#: model:ir.model.fields,field_description:openems.field_openems_systemmessage__timestamp -msgid "Creation date" -msgstr "" - -#. module: openems -#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol__customer_id -#: model:res.partner.category,name:openems.res_partner_category_customer -msgid "Customer" -msgstr "" - -#. module: openems -#: model:ir.model.fields.selection,name:openems.selection__res_users__openems_language__cz -msgid "Czech" -msgstr "" - -#. module: openems -#: model_terms:ir.ui.view,arch_db:openems.report_openems_setup_protocol_template -msgid "Datum:" -msgstr "" - -#. module: openems -#: model_terms:ir.ui.view,arch_db:openems.device_search_view -#: model_terms:ir.ui.view,arch_db:openems.openems_device_tree -msgid "Description" -msgstr "" - -#. module: openems -#: model_terms:ir.ui.view,arch_db:openems.openems_openemsconfigupdate_tree -msgid "Details" -msgstr "" - -#. module: openems -#: model:ir.model.fields,field_description:openems.field_stock_lot__device_id -#: model:ir.model.fields,field_description:openems.field_stock_lot__device_ids -msgid "Device" -msgstr "" - -#. module: openems -#: model:ir.actions.act_window,name:openems.action_openems_openemsconfigupdate -#: model:ir.ui.menu,name:openems.menu_openems_admin_openemsconfigupdate -msgid "Device Configuration Updates" -msgstr "" - -#. module: openems -#: model:ir.actions.act_window,name:openems.action_openems_device -#: model:ir.ui.menu,name:openems.menu_openems_content_devices -msgid "Devices" -msgstr "" - -#. module: openems -#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol__different_location_id -msgid "Different Location" -msgstr "" - -#. module: openems -#: model:ir.model.fields,field_description:openems.field_openems_device__display_name -#: model:ir.model.fields,field_description:openems.field_openems_device_tag__display_name -#: model:ir.model.fields,field_description:openems.field_openems_device_user_role__display_name -#: model:ir.model.fields,field_description:openems.field_openems_openemsconfigupdate__display_name -#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol__display_name -#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol_item__display_name -#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol_production_lot__display_name -#: model:ir.model.fields,field_description:openems.field_openems_systemmessage__display_name -msgid "Display Name" -msgstr "" - -#. module: openems -#: model:ir.model.fields.selection,name:openems.selection__res_users__openems_language__nl -msgid "Dutch" -msgstr "" - -#. module: openems -#: model:mail.template,name:openems.alerting_email_generic -msgid "E-Mail Alerting" -msgstr "" - -#. module: openems -#: model:mail.template,name:openems.registration_email -msgid "E-Mail Kunden Registrierung" -msgstr "" - -#. module: openems -#: model:mail.template,name:openems.setup_protocol_email_customer -msgid "E-Mail setup protocol for customer" -msgstr "" - -#. module: openems -#: model:mail.template,name:openems.setup_protocol_email_installer -msgid "E-Mail setup protocol for installer" -msgstr "" - -#. module: openems -#: model_terms:ir.ui.view,arch_db:openems.report_openems_setup_protocol_template -msgid "E-Mail-Adresse" -msgstr "" - -#. module: openems -#: model:ir.model.fields,field_description:openems.field_openems_device__emshardware -msgid "EMS Hardware" -msgstr "" - -#. module: openems -#: model:ir.model.fields.selection,name:openems.selection__res_users__openems_language__en -msgid "English" -msgstr "" - -#. module: openems -#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol__item_ids -msgid "Entry Items" -msgstr "" - -#. module: openems -#: model:ir.model.fields.selection,name:openems.selection__openems_device__openems_sum_state_level__fault -msgid "Fault" -msgstr "" - -#. module: openems -#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol_item__field -msgid "Field Identifier" -msgstr "" - -#. module: openems -#: model_terms:ir.ui.view,arch_db:openems.report_openems_setup_protocol_template -msgid "Firmenname" -msgstr "" - -#. module: openems -#: model:ir.model.fields,field_description:openems.field_openems_device__first_setup_protocol_date -msgid "First Setup Protocol Date" -msgstr "" - -#. module: openems -#: model:ir.model.fields,field_description:openems.field_openems_device__message_follower_ids -msgid "Followers" -msgstr "" - -#. module: openems -#: model:ir.model.fields,field_description:openems.field_openems_device__message_partner_ids -msgid "Followers (Partners)" -msgstr "" - -#. module: openems -#: model:ir.model.fields.selection,name:openems.selection__res_users__openems_language__fr -msgid "French" -msgstr "" - -#. module: openems -#: model_terms:ir.ui.view,arch_db:openems.openems_device_form -msgid "General" -msgstr "" - -#. module: openems -#: model:ir.model.fields.selection,name:openems.selection__res_users__openems_language__de -msgid "German" -msgstr "" - -#. module: openems -#: model:ir.model.fields,field_description:openems.field_res_users__global_role -msgid "Global Role" -msgstr "" - -#. module: openems -#: model:ir.model.fields.selection,name:openems.selection__openems_device_user_role__role__guest -#: model:ir.model.fields.selection,name:openems.selection__res_users__global_role__guest -msgid "Guest" -msgstr "" - -#. module: openems -#: model_terms:ir.ui.view,arch_db:openems.openems_device_form -msgid "Hardware" -msgstr "" - -#. module: openems -#: model:ir.model.fields,field_description:openems.field_openems_device__has_message -msgid "Has Message" -msgstr "" - -#. module: openems -#: model:ir.model.fields.selection,name:openems.selection__res_users__openems_language__hu -msgid "Hungarian" -msgstr "" - -#. module: openems -#: model:ir.model.fields,field_description:openems.field_openems_device__id -#: model:ir.model.fields,field_description:openems.field_openems_device_tag__id -#: model:ir.model.fields,field_description:openems.field_openems_device_user_role__id -#: model:ir.model.fields,field_description:openems.field_openems_openemsconfigupdate__id -#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol__id -#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol_item__id -#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol_production_lot__id -#: model:ir.model.fields,field_description:openems.field_openems_systemmessage__id -msgid "ID" -msgstr "" - -#. module: openems -#: model:ir.model.fields,help:openems.field_openems_device__message_needaction -msgid "If checked, new messages require your attention." -msgstr "" - -#. module: openems -#: model:ir.model.fields,help:openems.field_openems_device__message_has_error -#: model:ir.model.fields,help:openems.field_openems_device__message_has_sms_error -msgid "If checked, some messages have a delivery error." -msgstr "" - -#. module: openems -#: model:ir.model.fields.selection,name:openems.selection__openems_device__openems_sum_state_level__info -msgid "Info" -msgstr "" - -#. module: openems -#: model_terms:ir.ui.view,arch_db:openems.report_openems_setup_protocol_template -msgid "Installateur" -msgstr "" - -#. module: openems -#: model_terms:ir.ui.view,arch_db:openems.openems_device_form -msgid "Installation" -msgstr "" - -#. module: openems -#: model_terms:ir.ui.view,arch_db:openems.openems_device_form -msgid "Installation Log" -msgstr "" - -#. module: openems -#: model:ir.model.fields,field_description:openems.field_openems_device__setup_password -msgid "Installation key" -msgstr "" - -#. module: openems -#: model:ir.model.fields,field_description:openems.field_res_partner__installer_setup_protocols_ids -#: model:ir.model.fields,field_description:openems.field_res_users__installer_setup_protocols_ids -msgid "Installed OpenEMS Edge" -msgstr "" - -#. module: openems -#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol__installer_id -#: model:ir.model.fields.selection,name:openems.selection__openems_device_user_role__role__installer -#: model:ir.model.fields.selection,name:openems.selection__res_users__global_role__installer -msgid "Installer" -msgstr "" - -#. module: openems -#: model:ir.model.fields,field_description:openems.field_openems_device__internalnote -msgid "Internal note" -msgstr "" - -#. module: openems -#: model:ir.model.fields,field_description:openems.field_openems_device__message_is_follower -msgid "Is Follower" -msgstr "" - -#. module: openems -#: model_terms:ir.ui.view,arch_db:openems.openems_device_form -msgid "Is connected" -msgstr "" - -#. module: openems -#: model_terms:ir.ui.view,arch_db:openems.report_openems_setup_protocol_template -msgid "Kontaktdaten Endkunde" -msgstr "" - -#. module: openems -#: model_terms:ir.ui.view,arch_db:openems.report_openems_setup_protocol_template -msgid "Land" -msgstr "" - -#. module: openems -#: model:ir.model.fields,field_description:openems.field_openems_device____last_update -#: model:ir.model.fields,field_description:openems.field_openems_device_tag____last_update -#: model:ir.model.fields,field_description:openems.field_openems_device_user_role____last_update -#: model:ir.model.fields,field_description:openems.field_openems_openemsconfigupdate____last_update -#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol____last_update -#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol_item____last_update -#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol_production_lot____last_update -#: model:ir.model.fields,field_description:openems.field_openems_systemmessage____last_update -msgid "Last Modified on" -msgstr "" - -#. module: openems -#: model:ir.model.fields,field_description:openems.field_openems_device__write_uid -#: model:ir.model.fields,field_description:openems.field_openems_device_tag__write_uid -#: model:ir.model.fields,field_description:openems.field_openems_device_user_role__write_uid -#: model:ir.model.fields,field_description:openems.field_openems_openemsconfigupdate__write_uid -#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol__write_uid -#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol_item__write_uid -#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol_production_lot__write_uid -#: model:ir.model.fields,field_description:openems.field_openems_systemmessage__write_uid -msgid "Last Updated by" -msgstr "" - -#. module: openems -#: model:ir.model.fields,field_description:openems.field_openems_device__write_date -#: model:ir.model.fields,field_description:openems.field_openems_device_tag__write_date -#: model:ir.model.fields,field_description:openems.field_openems_device_user_role__write_date -#: model:ir.model.fields,field_description:openems.field_openems_openemsconfigupdate__write_date -#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol__write_date -#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol_item__write_date -#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol_production_lot__write_date -#: model:ir.model.fields,field_description:openems.field_openems_systemmessage__write_date -msgid "Last Updated on" -msgstr "" - -#. module: openems -#: model:ir.model.fields,field_description:openems.field_openems_device__lastupdate -msgid "Last data update" -msgstr "" - -#. module: openems -#: model:ir.model.fields,field_description:openems.field_openems_device__lastmessage -msgid "Last message" -msgstr "" - -#. module: openems -#: model:ir.model.fields,field_description:openems.field_openems_device_user_role__last_notification -msgid "Last notification sent" -msgstr "" - -#. module: openems -#: model:ir.model,name:openems.model_stock_lot -msgid "Lot/Serial" -msgstr "" - -#. module: openems -#: model:ir.model.fields,field_description:openems.field_openems_device__message_main_attachment_id -msgid "Main Attachment" -msgstr "" - -#. module: openems -#: model:res.groups,name:openems.group_openems_manager -msgid "Manager" -msgstr "" - -#. module: openems -#: model:ir.model.fields,field_description:openems.field_openems_device__manual_setup_date -msgid "Manual Setup Date" -msgstr "" - -#. module: openems -#: model:res.groups,comment:openems.group_openems_manager -msgid "Members of this group can manage all devices" -msgstr "" - -#. module: openems -#: model:res.groups,comment:openems.group_openems_reader -msgid "Members of this group have reading access to all devices" -msgstr "" - -#. module: openems -#: model:ir.model.fields,field_description:openems.field_openems_systemmessage__text -msgid "Message" -msgstr "" - -#. module: openems -#: model:ir.model.fields,field_description:openems.field_openems_device__message_has_error -msgid "Message Delivery error" -msgstr "" - -#. module: openems -#: model:ir.model.fields,field_description:openems.field_openems_device__message_ids -msgid "Messages" -msgstr "" - -#. module: openems -#: model:ir.model.fields,field_description:openems.field_openems_device__name -#: model:ir.model.fields,field_description:openems.field_openems_device_tag__name -#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol_item__name -#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol_production_lot__name -msgid "Name" -msgstr "" - -#. module: openems -#: model_terms:ir.ui.view,arch_db:openems.report_openems_setup_protocol_template -msgid "Name Installateur" -msgstr "" - -#. module: openems -#: model_terms:ir.ui.view,arch_db:openems.report_openems_setup_protocol_template -msgid "Name Kontaktperson" -msgstr "" - -#. module: openems -#: model:ir.model.fields,field_description:openems.field_openems_device__name_number -msgid "Name Number" -msgstr "" - -#. module: openems -#: model:ir.model.constraint,message:openems.constraint_openems_device_unique_name -msgid "Name needs to be unique" -msgstr "" - -#. module: openems -#: model:ir.model.fields,field_description:openems.field_openems_device_user_role__time_to_wait -msgid "Notification" -msgstr "" - -#. module: openems -#: model:ir.model.fields,field_description:openems.field_openems_device__message_needaction_counter -msgid "Number of Actions" -msgstr "" - -#. module: openems -#: model:ir.model.fields,field_description:openems.field_openems_device__message_has_error_counter -msgid "Number of errors" -msgstr "" - -#. module: openems -#: model:ir.model.fields,help:openems.field_openems_device__message_needaction_counter -msgid "Number of messages requiring action" -msgstr "" - -#. module: openems -#: model:ir.model.fields,help:openems.field_openems_device__message_has_error_counter -msgid "Number of messages with delivery error" -msgstr "" - -#. module: openems -#: model_terms:ir.ui.view,arch_db:openems.openems_device_tree -msgid "OE Connected" -msgstr "" - -#. module: openems -#: model_terms:ir.ui.view,arch_db:openems.openems_device_tree -msgid "OE State" -msgstr "" - -#. module: openems -#: model_terms:ir.ui.view,arch_db:openems.openems_device_tree -msgid "OE Version" -msgstr "" - -#. module: openems -#: model:ir.model.fields,field_description:openems.field_openems_device__oem -msgid "OEM Branding" -msgstr "" - -#. module: openems -#: model:ir.model.fields.selection,name:openems.selection__openems_device__openems_sum_state_level__ok -msgid "Ok" -msgstr "" - -#. module: openems -#: model:ir.model.fields,field_description:openems.field_openems_device__monitoring_url -msgid "Online-Monitoring" -msgstr "" - -#. module: openems -#: model:ir.model.fields.selection,name:openems.selection__openems_device__oem__openems -#: model:ir.module.category,name:openems.module_category_openems -#: model:ir.ui.menu,name:openems.menu_openems -#: model_terms:ir.ui.view,arch_db:openems.openems_users_form -msgid "OpenEMS" -msgstr "" - -#. module: openems -#: model:mail.template,subject:openems.alerting_email_generic -msgid "OpenEMS Alert - Edge is offline" -msgstr "" - -#. module: openems -#: model_terms:ir.ui.view,arch_db:openems.report_openems_setup_protocol_template -msgid "OpenEMS Association e.V." -msgstr "" - -#. module: openems -#: model:ir.model.fields,field_description:openems.field_openems_device__openems_config_components -msgid "OpenEMS Config" -msgstr "" - -#. module: openems -#: model:ir.model.fields,field_description:openems.field_openems_device__openems_config -msgid "OpenEMS Config Full" -msgstr "" - -#. module: openems -#: model:ir.model.fields,field_description:openems.field_openems_device__openems_config_update_ids -msgid "OpenEMS Config Updates" -msgstr "" - -#. module: openems -#: model_terms:ir.ui.view,arch_db:openems.openems_openemsconfigupdate_tree -msgid "OpenEMS Configuration Updates" -msgstr "" - -#. module: openems -#: model:ir.model.fields,field_description:openems.field_openems_device_user_role__device_id -#: model:ir.model.fields,field_description:openems.field_openems_openemsconfigupdate__device_id -#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol__device_id -#: model:ir.model.fields,field_description:openems.field_openems_systemmessage__device_id -#: model:ir.model.fields.selection,name:openems.selection__openems_device__producttype__openems-edge -#: model:ir.ui.menu,name:openems.menu_openems_content -msgid "OpenEMS Edge" -msgstr "" - -#. module: openems -#: model:ir.model,name:openems.model_openems_device -msgid "OpenEMS Edge Device" -msgstr "" - -#. module: openems -#: model:ir.model,name:openems.model_openems_openemsconfigupdate -msgid "OpenEMS Edge Device Configuration Update" -msgstr "" - -#. module: openems -#: model:ir.model,name:openems.model_openems_device_tag -msgid "OpenEMS Edge Device Tag" -msgstr "" - -#. module: openems -#: model:ir.model,name:openems.model_openems_device_user_role -msgid "OpenEMS Edge Device User Role" -msgstr "" - -#. module: openems -#: model:ir.model,name:openems.model_openems_setup_protocol_item -msgid "OpenEMS Edge Setup Protocol Entry Item" -msgstr "" - -#. module: openems -#: model:ir.model,name:openems.model_openems_setup_protocol_production_lot -msgid "OpenEMS Edge Setup Protocol Serial Number" -msgstr "" - -#. module: openems -#: model:ir.model,name:openems.model_openems_setup_protocol -msgid "OpenEMS Edge Setup Protocols (IBN)" -msgstr "" - -#. module: openems -#: model:ir.model,name:openems.model_openems_systemmessage -msgid "OpenEMS Edge Systemmessage" -msgstr "" - -#. module: openems -#: model:ir.model.fields,field_description:openems.field_openems_device__openems_is_connected -msgid "OpenEMS Is connected" -msgstr "" - -#. module: openems -#: model:ir.actions.report,name:openems.action_openems_setup_protocol_report -msgid "OpenEMS Setup Protocol" -msgstr "" - -#. module: openems -#: model:ir.model.fields,field_description:openems.field_openems_device__openems_sum_state_level -msgid "OpenEMS State" -msgstr "" - -#. module: openems -#: model:ir.model.fields,field_description:openems.field_openems_device__openems_version -#: model_terms:ir.ui.view,arch_db:openems.device_search_view -msgid "OpenEMS Version" -msgstr "" - -#. module: openems -#: model_terms:ir.ui.view,arch_db:openems.device_search_view -#: model_terms:ir.ui.view,arch_db:openems.openems_device_tree -msgid "OpenEMS-Number" -msgstr "" - -#. module: openems -#: model:ir.model.fields,field_description:openems.field_res_users__openems_language -msgid "Openems Language" -msgstr "" - -#. module: openems -#: model_terms:ir.ui.view,arch_db:openems.report_openems_setup_protocol_template -msgid "Ort" -msgstr "" - -#. module: openems -#: model:ir.model.fields.selection,name:openems.selection__openems_device_user_role__role__owner -#: model:ir.model.fields.selection,name:openems.selection__res_users__global_role__owner -msgid "Owner" -msgstr "" - -#. module: openems -#: model:ir.model.fields,field_description:openems.field_res_partner__customer_setup_protocols_ids -#: model:ir.model.fields,field_description:openems.field_res_users__customer_setup_protocols_ids -msgid "Owner of OpenEMS Edge" -msgstr "" - -#. module: openems -#: model_terms:ir.ui.view,arch_db:openems.report_openems_setup_protocol_template -msgid "PLZ" -msgstr "" - -#. module: openems -#: model:ir.model.fields,help:openems.field_openems_device__setup_password -msgid "Password for commissioning by the installer" -msgstr "" - -#. module: openems -#: model_terms:ir.ui.view,arch_db:openems.openems_setup_protocol_form -msgid "Print" -msgstr "" - -#. module: openems -#: model_terms:ir.ui.view,arch_db:openems.openems_device_form -msgid "Product" -msgstr "" - -#. module: openems -#: model:ir.model.fields,field_description:openems.field_openems_device__producttype -msgid "Product type" -msgstr "" - -#. module: openems -#: model:res.groups,name:openems.group_openems_reader -msgid "Read access" -msgstr "" - -#. module: openems -#: model:mail.template,subject:openems.registration_email -msgid "Registrierung erfolgreich" -msgstr "" - -#. module: openems -#: model:ir.model.fields,field_description:openems.field_openems_device_user_role__role -msgid "Role" -msgstr "" - -#. module: openems -#: model:ir.model.fields,field_description:openems.field_openems_device__user_role_ids -#: model:ir.model.fields,field_description:openems.field_res_users__device_role_ids -msgid "Roles" -msgstr "" - -#. module: openems -#: model:ir.model.fields,field_description:openems.field_openems_device__message_has_sms_error -msgid "SMS Delivery error" -msgstr "" - -#. module: openems -#: model_terms:ir.ui.view,arch_db:openems.openems_device_form -msgid "Security" -msgstr "" - -#. module: openems -#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol_production_lot__lot_id -msgid "Serial Number" -msgstr "" - -#. module: openems -#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol__productionlot_ids -msgid "Serial Numbers" -msgstr "" - -#. module: openems -#: model:ir.model.constraint,message:openems.constraint_openems_device_unique_stock_production_lot_id -msgid "Serial number needs to be unique" -msgstr "" - -#. module: openems -#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol_item__setup_protocol_id -#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol_production_lot__setup_protocol_id -#: model_terms:ir.ui.view,arch_db:openems.report_openems_setup_protocol_template -msgid "Setup Protocol" -msgstr "" - -#. module: openems -#: model:ir.actions.act_window,name:openems.action_openems_admin_setup_protocol -#: model:ir.model.fields,field_description:openems.field_openems_device__setup_protocol_ids -#: model:ir.ui.menu,name:openems.menu_openems_admin_setup_protocol -#: model_terms:ir.ui.view,arch_db:openems.res_partner_form -msgid "Setup Protocols" -msgstr "" - -#. module: openems -#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol_item__sequence -#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol_production_lot__sequence -msgid "Sort" -msgstr "" - -#. module: openems -#: model:ir.model.fields.selection,name:openems.selection__res_users__openems_language__es -msgid "Spanish" -msgstr "" - -#. module: openems -#: model_terms:ir.ui.view,arch_db:openems.report_openems_setup_protocol_template -msgid "Speicherstandort" -msgstr "" - -#. module: openems -#: model_terms:ir.ui.view,arch_db:openems.openems_device_form -msgid "Status" -msgstr "" - -#. module: openems -#: model:ir.model.fields,field_description:openems.field_openems_device__stock_production_lot_id -msgid "Stock Production Lot" -msgstr "" - -#. module: openems -#: model_terms:ir.ui.view,arch_db:openems.report_openems_setup_protocol_template -msgid "Straße / Hausnummer" -msgstr "" - -#. module: openems -#: model_terms:ir.ui.view,arch_db:openems.openems_device_form -msgid "System Messages" -msgstr "" - -#. module: openems -#: model:ir.actions.act_window,name:openems.action_openems_systemmessage -#: model:ir.model.fields,field_description:openems.field_openems_device__systemmessage_ids -#: model:ir.ui.menu,name:openems.menu_openems_admin_systemmessages -msgid "Systemmessages" -msgstr "" - -#. module: openems -#: model_terms:ir.ui.view,arch_db:openems.openems_device_form -msgid "Systemstatus" -msgstr "" - -#. module: openems -#: model:ir.model.fields,field_description:openems.field_openems_device__tag_ids -msgid "Tags" -msgstr "" - -#. module: openems -#: model_terms:ir.ui.view,arch_db:openems.report_openems_setup_protocol_template -msgid "Telefonnummer" -msgstr "" - -#. module: openems -#: model:ir.model.fields,field_description:openems.field_openems_systemmessage__text_teaser -msgid "Text Teaser" -msgstr "" - -#. module: openems -#: model:ir.model.fields,field_description:openems.field_openems_openemsconfigupdate__details -msgid "Update Details" -msgstr "" - -#. module: openems -#: model:ir.model.fields,field_description:openems.field_openems_openemsconfigupdate__teaser -msgid "Update Details Teaser" -msgstr "" - -#. module: openems -#: model:ir.model,name:openems.model_res_users -#: model:ir.model.fields,field_description:openems.field_openems_device_user_role__user_id -msgid "User" -msgstr "" - -#. module: openems -#: model:ir.model.constraint,message:openems.constraint_openems_device_user_role_device_user_uniq -msgid "User already exists for this device." -msgstr "" - -#. module: openems -#: model_terms:ir.ui.view,arch_db:openems.openems_systemmessage_tree -msgid "Users" -msgstr "" - -#. module: openems -#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol_item__value -msgid "Value" -msgstr "" - -#. module: openems -#: model:ir.model.fields,field_description:openems.field_openems_setup_protocol_item__view -msgid "View Identifier" -msgstr "" - -#. module: openems -#: model_terms:ir.ui.view,arch_db:openems.report_openems_setup_protocol_template -msgid "Vor- Nachname" -msgstr "" - -#. module: openems -#: model:ir.model.fields.selection,name:openems.selection__openems_device__openems_sum_state_level__warning -msgid "Warning" -msgstr "" - -#. module: openems -#: model:ir.model.fields,field_description:openems.field_openems_device__website_message_ids -msgid "Website Messages" -msgstr "" - -#. module: openems -#: model:ir.model.fields,help:openems.field_openems_device__website_message_ids -msgid "Website communication history" -msgstr "" - -#. module: openems -#: model:mail.template,subject:openems.setup_protocol_email_customer -#: model:mail.template,subject:openems.setup_protocol_email_installer -msgid "Your OpenEMS setup protocol for {{object.openems_device_id.name}}" -msgstr "" diff --git a/odoo/extra-addons/openems/mail/openems/alerting_offline.xml b/odoo/extra-addons/openems/mail/openems/alerting_offline.xml deleted file mode 100644 index 2d2a38d..0000000 --- a/odoo/extra-addons/openems/mail/openems/alerting_offline.xml +++ /dev/null @@ -1,275 +0,0 @@ - - - - - E-Mail Offline-Alerting - - ]]> - {{object.user_id.partner_id.id}} - OpenEMS Alert - Edge is offline - - - - - OpenEMS Alert - Edge is offline - - - - - - - - - - - - - - - -
- - - - - - -
- -
- - - - - - -
- -
- - - - - - - - - - - - - - - - - - - - - - - - -
-

-

- -
-
- - - , - - Ms/Mr , - Customer, -
-
-
Your OpenEMS Edge with number is offline since: -
-
-
- - - - - - - (UTC) - - -
-
- - - - - - - - - - - - -
Info
- OpenEMS-Version - - - - - UNKNOWN -
- Type - - - - - - - -
-
-
Best Regards
-
-
OpenEMS Association e.V.
-
-
- -
-
- -
- -
- - - - - - -
- -
- - - - - - - - - - - - - - - -
-
If you do no longer wish to receive email notifications, you can disable the feature here .
-
-
This is an automatically generated message. Please do not reply to this message!
-
- - - - - - -
- OpenEMS Logo -
-
-

-

- -
-
- -
-
- -
- - - - ]]> -
-
-
-
diff --git a/odoo/extra-addons/openems/mail/openems/alerting_sum_state.xml b/odoo/extra-addons/openems/mail/openems/alerting_sum_state.xml deleted file mode 100644 index 5ac49f6..0000000 --- a/odoo/extra-addons/openems/mail/openems/alerting_sum_state.xml +++ /dev/null @@ -1,268 +0,0 @@ - - - - - E-Mail SumState Alerting - - ]]> - {{object.user_id.partner_id.id}} - OpenEMS Alert - Edge is in {{object.device_id.openems_sum_state_level}} State - - - - - OpenEMS Alert - Edge is in fault - - - - - - - - - - - - - - - -
- - - - - - -
- -
- - - - - - -
- -
- - - - - - - - - - - - - - - - - - - - - -
-

-

- -
-
- - - , - - Ms/Mr , - Customer, -
-
-
Your OpenEMS Edge with number is in a continuous - - - - - - - UNKNOWN - state! -
-
- - - - - - - - - - - - -
Info
- OpenEMS-Version - - - - - UNKNOWN -
- Type - - - - - - - -
-
-
Best Regards
-
-
OpenEMS Association e.V.
-
-
- -
-
- -
- -
- - - - - - -
- -
- - - - - - - - - - - - - - - -
-
If you do no longer wish to receive email notifications, you can disable the feature here .
-
-
This is an automatically generated message. Please do not reply to this message!
-
- - - - - - -
- OpenEMS Logo -
-
-

-

- -
-
- -
-
- -
- - - - ]]> -
-
-
-
diff --git a/odoo/extra-addons/openems/mail/openems/setup_protocol_customer.xml b/odoo/extra-addons/openems/mail/openems/setup_protocol_customer.xml deleted file mode 100644 index 3b1e781..0000000 --- a/odoo/extra-addons/openems/mail/openems/setup_protocol_customer.xml +++ /dev/null @@ -1,170 +0,0 @@ - - - - - E-Mail setup protocol for customer - - ]]> - {{object.customer_id.id}} - Your OpenEMS setup protocol for {{object.openems_device_id.name}} - false - - - - - Your OpenEMS Edge setup protocol - - - - - - - - - - - - - - - -
- - - - - - -
- -
- - - - - - -
- -
- - - - - - - - - - - - - - - - - - -
-

-

- -
-
Welcome to OpenEMS,
-
-
please find your setup protocol for OpenEMS Edge attached.
-
-
Best Regards
-
-
OpenEMS Association e.V.
-
-
- -
-
- -
-
- - - - ]]> -
-
-
-
diff --git a/odoo/extra-addons/openems/mail/openems/setup_protocol_installer.xml b/odoo/extra-addons/openems/mail/openems/setup_protocol_installer.xml deleted file mode 100644 index 13afd9d..0000000 --- a/odoo/extra-addons/openems/mail/openems/setup_protocol_installer.xml +++ /dev/null @@ -1,173 +0,0 @@ - - - - - E-Mail setup protocol for installer - - ]]> - {{object.installer_id.id}} - Your OpenEMS setup protocol for {{object.openems_device_id.name}} - false - - - - - OpenEMS setup protocol - - - - - - - - - - - - - - - -
- - - - - - -
- -
- - - - - - -
- -
- - - - - - - - - - - - - - - - - - -
-

-

- -
-
Dear - , -
-
-
please find the setup protocol for your customer attached. -
-
-
Best Regards
-
-
OpenEMS Association e.V.
-
-
- -
-
- -
-
- - - - ]]> -
-
-
-
diff --git a/odoo/extra-addons/openems/mail/openems/user_registration.xml b/odoo/extra-addons/openems/mail/openems/user_registration.xml deleted file mode 100644 index cfd4183..0000000 --- a/odoo/extra-addons/openems/mail/openems/user_registration.xml +++ /dev/null @@ -1,197 +0,0 @@ - - - - - E-Mail Kunden Registrierung - - ]]> - {{object.id}} - Registrierung erfolgreich - false - - - - - Registrierung erfolgreich - - - - - - - - - - - - - - - -
- - - - - - -
- -
- - - - - - -
- -
- - - - - - - - - - - - - - - - - - - - - - - - -
-

-

- -
-
Guten Tag - , -
-
-
Ihr Zugang zu OpenEMS UI wurde erstellt.
-
-
Sie können sich auf OpenEMS UI einloggen, um auf das Online-Monitoring zuzugreifen.
-
- - - - - - - - - - - - -
Ihre Zugangsdaten:
E-Mail - -
Passwort - -
-
-
Best Regards
-
-
OpenEMS Association e.V.
-
-
- -
-
- -
-
- - - - ]]> -
-
-
-
diff --git a/odoo/extra-addons/openems/migrations/16.0.1.0.1/post-migrate.py b/odoo/extra-addons/openems/migrations/16.0.1.0.1/post-migrate.py deleted file mode 100644 index 1eab6fe..0000000 --- a/odoo/extra-addons/openems/migrations/16.0.1.0.1/post-migrate.py +++ /dev/null @@ -1,9 +0,0 @@ -def migrate(cr, version): - cr.execute(""" - INSERT INTO openems_alerting (device_id, device_name, user_id, user_login, offline_delay, warning_delay, fault_delay, offline_last_notification) - SELECT device_id, dev.name, user_id, usr.login, time_to_wait, 0, 0, last_notification - FROM openems_alerting_migrate AS migrate - LEFT JOIN openems_device AS dev ON dev.id = migrate.device_id - LEFT JOIN res_users AS usr ON usr.id = migrate.user_id - """) - cr.execute('DROP TABLE openems_alerting_migrate') diff --git a/odoo/extra-addons/openems/migrations/16.0.1.0.1/pre-migrate.py b/odoo/extra-addons/openems/migrations/16.0.1.0.1/pre-migrate.py deleted file mode 100644 index 341e4a5..0000000 --- a/odoo/extra-addons/openems/migrations/16.0.1.0.1/pre-migrate.py +++ /dev/null @@ -1,7 +0,0 @@ -def migrate(cr, version): - cr.execute(""" - SELECT device_id, user_id, time_to_wait, last_notification - INTO openems_alerting_migrate - FROM openems_device_user_role - WHERE time_to_wait > 0; - """) diff --git a/odoo/extra-addons/openems/models/__init__.py b/odoo/extra-addons/openems/models/__init__.py deleted file mode 100644 index c4a7e59..0000000 --- a/odoo/extra-addons/openems/models/__init__.py +++ /dev/null @@ -1 +0,0 @@ -from . import device, partner, setup_protocol, user, stock_production_lot diff --git a/odoo/extra-addons/openems/models/device.py b/odoo/extra-addons/openems/models/device.py deleted file mode 100644 index bdbda80..0000000 --- a/odoo/extra-addons/openems/models/device.py +++ /dev/null @@ -1,321 +0,0 @@ -from odoo import api, fields, models, exceptions, _ -from datetime import datetime -from odoo.exceptions import ValidationError -import random -import re -import string - -class Device(models.Model): - _name = "openems.device" - _description = "OpenEMS Edge Device" - _inherit = "mail.thread" - _order = "name_number asc" - _sql_constraints = [ - ("unique_name", "unique(name)", "Name needs to be unique"), - ("unique_stock_production_lot_id", "unique(stock_production_lot_id)", - "Serial number needs to be unique") - ] - - name = fields.Char(required=True) - active = fields.Boolean("Active", default=True, tracking=True) - comment = fields.Char(tracking=True) - internalnote = fields.Text("Internal note", tracking=True) - tag_ids = fields.Many2many("openems.device_tag", string="Tags", tracking=True) - monitoring_url = fields.Char( - "Online-Monitoring", compute="_compute_monitoring_url", store=False - ) - stock_production_lot_id = fields.Many2one("stock.lot") - first_setup_protocol_date = fields.Datetime( - "First Setup Protocol Date", compute="_compute_first_setup_protocol" - ) - manual_setup_date = fields.Datetime("Manual Setup Date") - - @api.depends("setup_protocol_ids", "manual_setup_date") - def _compute_first_setup_protocol(self): - for rec in self: - if rec.manual_setup_date: - rec.first_setup_protocol_date = rec.manual_setup_date - elif len(rec.setup_protocol_ids) > 0: - rec.first_setup_protocol_date = rec.setup_protocol_ids[ - (len(rec.setup_protocol_ids) - 1) - ]["create_date"] - else: - rec.first_setup_protocol_date = None - - @api.depends("name") - def _compute_monitoring_url(self): - # Corrected the parameter key to 'edge_monitoring_url' - base_url = self.env["ir.config_parameter"].sudo().get_param("edge_monitoring_url", default='#') - for rec in self: - if isinstance(rec.name, str) and rec.name: - # Ensuring there is a '/' between base_url and rec.name if it's not already present - separator = '' if base_url.endswith('/') else '/' - rec.monitoring_url = base_url + separator + rec.name + "/live" - else: - rec.monitoring_url = base_url - - producttype = fields.Selection( - [ - ("openems-edge", "OpenEMS Edge"), - ], - "Product type", - tracking=True, - ) - emshardware = fields.Selection([], "EMS Hardware", tracking=True) - oem = fields.Selection( - [ - ("openems", "OpenEMS"), - ], - "OEM Branding", - default="openems", - ) - - # Settings - openems_config = fields.Text("OpenEMS Config Full") - openems_config_components = fields.Text("OpenEMS Config") - openems_version = fields.Char("OpenEMS Version", tracking=True) - - # Security - setup_password = fields.Char( - "Installation Key", - help="Password for commissioning by the installer", - ) - apikey = fields.Char("API-Key", required=True, tracking=True) - - # 'openems_sum_state_level' is updated by OpenEMS Backend - openems_sum_state_level = fields.Selection( - [("ok", "Ok"), ("info", "Info"), ("warning", "Warning"), ("fault", "Fault")], - "OpenEMS State", - ) - # 'openems_is_connected' is updated by OpenEMS Backend - openems_is_connected = fields.Boolean("OpenEMS Is connected") - - # System Status - lastmessage = fields.Datetime("Last message") - lastupdate = fields.Datetime("Last data update") - - # Verknüpfungen - systemmessage_ids = fields.One2many( - "openems.systemmessage", "device_id", string="System Messages" - ) - user_role_ids = fields.One2many( - "openems.device_user_role", "device_id", string="Roles", tracking=True - ) - alerting_settings = fields.One2many( - "openems.alerting", "device_id", string="Alerting", tracking=True - ) - openems_config_update_ids = fields.One2many( - "openems.openemsconfigupdate", "device_id", string="OpenEMS Config Updates" - ) - setup_protocol_ids = fields.One2many( - "openems.setup_protocol", "device_id", "Setup Protocols" - ) - - # Helper fields - name_number = fields.Integer(compute="_compute_name_number", store="True") - - @api.depends("name") - def _compute_name_number(self): - for rec in self: - rec.name_number = int(rec.name[4:]) if rec.name.startswith("edge") else -1 - - def _get_openems_state_number(self, string): - state = 0 - if string == "info": - state = 1 - elif string == "warning": - state = 2 - elif string == "fault": - state = 3 - return state - - def write(self, vals): - """Prohibit to change name field after creation.""" - if 'name' in vals: - for record in self: - if record.id and record.name != vals['name']: - self.env.cr.execute(""" - SELECT EXISTS ( - SELECT 1 FROM openems_device - WHERE name = %s AND id != %s - ) - """, (vals['name'], record.id)) - exists = self.env.cr.fetchone()[0] - if exists: - # This means there's already a device with the intended new name - raise exceptions.UserError( - "The name '{}' is already in use or does not follow the required pattern.".format( - vals['name'])) - - # If you simply want to prevent name changes, the following UserError suffices - raise exceptions.UserError("The name of the device cannot be changed after creation.") - return super(Device, self).write(vals) - - @api.model - def create(self, vals): - - # Generate setup password if not provided - if 'setup_password' not in vals or not vals['setup_password']: - vals['setup_password'] = self._generate_unique_setup_password() - - # Generate API key if not provided - if 'apikey' not in vals or not vals['apikey']: - vals['apikey'] = self._generate_api_key() - - return super(Device, self).create(vals) - - def _generate_unique_setup_password(self): - is_unique = False - setup_password = '' - while not is_unique: - # Generate a random setup password - raw_password = ''.join(random.choices(string.ascii_uppercase + string.digits, k=16)) - setup_password = '-'.join([raw_password[i:i + 4] for i in range(0, len(raw_password), 4)]) - # Check if the generated setup password already exists - existing = self.search_count([('setup_password', '=', setup_password)]) - # If the password does not exist, it is unique, and we can exit the loop - if existing == 0: - is_unique = True - return setup_password - - def _generate_api_key(self): - # Initialize a flag to indicate whether the generated key is unique - is_unique = False - api_key = '' - while not is_unique: - # Generate a random API key - api_key = ''.join(random.choices(string.ascii_letters + string.digits, k=20)) - # Check if the generated API key already exists - existing = self.search_count([('apikey', '=', api_key)]) - # If the key does not exist, it is unique, and we can exit the loop - if existing == 0: - is_unique = True - return api_key - - @api.onchange('setup_password') - def _check_setup_password_format(self): - for record in self: - if not record.setup_password: - continue - if not re.match(r"^[A-Z0-9]{4}-[A-Z0-9]{4}-[A-Z0-9]{4}-[A-Z0-9]{4}$", record.setup_password): - raise ValidationError("The device ID must be formatted as XXXX-XXXX-XXXX-XXXX") - - @api.onchange('apikey') - def _check_api_key_uniqueness(self): - for record in self: - if record.apikey: - # Prepare the domain for searching duplicates - domain = [('apikey', '=', record.apikey)] - # If the record is already saved (has a valid database ID), exclude it from the search - if record.id and isinstance(record.id, (int,)): - domain.append(('id', '!=', record.id)) - # Check if any other records with the same API key exist - existing = self.search_count(domain) - # If there are duplicates, raise a ValidationError - if existing: - raise ValidationError( - _("The API key already exists and must be unique. Please choose a different API key.")) - - -class DeviceTag(models.Model): - _name = "openems.device_tag" - _description = "OpenEMS Edge Device Tag" - name = fields.Char(required=True) - - -class DeviceUserRole(models.Model): - _name = "openems.device_user_role" - _description = "OpenEMS Edge Device User Role" - _sql_constraints = [ - ( - "device_user_uniq", - "unique(device_id, user_id)", - "User already exists for this device.", - ), - ] - device_id = fields.Many2one("openems.device", string="OpenEMS Edge") - user_id = fields.Many2one("res.users", string="User") - role = fields.Selection( - [ - ("admin", "Admin"), - ("installer", "Installer"), - ("owner", "Owner"), - ("guest", "Guest"), - ], - default="guest", - required=True, - ) - - -class OpenemsConfigUpdate(models.Model): - _name = "openems.openemsconfigupdate" - _description = "OpenEMS Edge Device Configuration Update" - _order = "create_date desc" - - device_id = fields.Many2one("openems.device", string="OpenEMS Edge") - teaser = fields.Text("Update Details Teaser") - details = fields.Html("Update Details") - - -class Systemmessage(models.Model): - _name = "openems.systemmessage" - _description = "OpenEMS Edge Systemmessage" - _order = "create_date desc" - - timestamp = fields.Datetime("Creation date") - device_id = fields.Many2one("openems.device", string="OpenEMS Edge") - text = fields.Text("Message") - text_teaser = fields.Char(compute="_compute_text_teaser") - - @api.depends("text") - def _compute_text_teaser(self): - for rec in self: - # get up to 100 characters from first line - rec.text_teaser = rec.text.splitlines()[0][0:100] if rec.text else False - -class Alerting(models.Model): - _name = "openems.alerting" - _description = "OpenEMS Edge AlertingSettings" - _sql_constraints = [ - ( - "device_user_uniq", - "unique(device_id, user_id)", - "User already has Alerting Settings.", - ), - ] - - device_id = fields.Many2one("openems.device", string="OpenEMS Edge") - user_id = fields.Many2one("res.users", string="User") - - offline_delay = fields.Integer(string="Offline Notification", default=1440) - warning_delay = fields.Integer(string="Warning Notification", default=1440) - fault_delay = fields.Integer(string="Fault Notification", default=1440) - - offline_last_notification = fields.Datetime(string="Last Offline notification sent") - sum_state_last_notification = fields.Datetime(string="Last SumState notification sent") - - device_name = fields.Text(compute="_compute_device_name", store="True") - user_login = fields.Text(compute="_compute_user_login", store="True") - - user_role = fields.Selection( - [("admin", "Admin"), ("installer", "Installer"), ("owner", "Owner"), ("guest", "Guest"),], - compute="_compute_user_role", store="False") - - @api.depends("device_id") - def _compute_device_name(self): - for rec in self: - rec.device_name = rec.device_id.name; - - @api.depends("user_id") - def _compute_user_login(self): - for rec in self: - rec.user_login = rec.user_id.login; - - @api.depends("user_id", "device_id") - def _compute_user_role(self): - for rec in self: - user_role: DeviceUserRole = rec.user_id.device_role_ids.search([('device_id','=',rec.device_id.id)]) - if user_role: - return user_role.role - else: - return rec.user_id.global_role diff --git a/odoo/extra-addons/openems/models/partner.py b/odoo/extra-addons/openems/models/partner.py deleted file mode 100644 index 37ab8e5..0000000 --- a/odoo/extra-addons/openems/models/partner.py +++ /dev/null @@ -1,12 +0,0 @@ -from odoo import fields, models - - -class ResPartner(models.Model): - _inherit = "res.partner" - - installer_setup_protocols_ids = fields.One2many( - "openems.setup_protocol", "installer_id", "Installed OpenEMS Edge" - ) - customer_setup_protocols_ids = fields.One2many( - "openems.setup_protocol", "customer_id", "Owner of OpenEMS Edge" - ) diff --git a/odoo/extra-addons/openems/models/setup_protocol.py b/odoo/extra-addons/openems/models/setup_protocol.py deleted file mode 100644 index 548576e..0000000 --- a/odoo/extra-addons/openems/models/setup_protocol.py +++ /dev/null @@ -1,49 +0,0 @@ -from odoo import fields, models - - -class SetupProtocol(models.Model): - _name = "openems.setup_protocol" - _description = "OpenEMS Edge Setup Protocols (IBN)" - _order = "create_date desc" - - customer_id = fields.Many2one("res.partner", "Customer", required=True) - different_location_id = fields.Many2one("res.partner", "Different Location") - installer_id = fields.Many2one("res.partner", "Installer", required=True) - device_id = fields.Many2one("openems.device", "OpenEMS Edge", required=True) - productionlot_ids = fields.One2many( - "openems.setup_protocol_production_lot", "setup_protocol_id", "Serial Numbers" - ) - item_ids = fields.One2many( - "openems.setup_protocol_item", "setup_protocol_id", "Entry Items" - ) - - -class SetupProtocolProductionLot(models.Model): - _name = "openems.setup_protocol_production_lot" - _description = "OpenEMS Edge Setup Protocol Serial Number" - _order = "setup_protocol_id, category, sequence asc" - - sequence = fields.Integer("Sort") - category = fields.Char("Category") - name = fields.Char("Name") - lot_id = fields.Many2one("stock.production.lot", "Serial Number") - setup_protocol_id = fields.Many2one( - "openems.setup_protocol", "Setup Protocol", ondelete="cascade" - ) - - -class SetupProtocolItem(models.Model): - _name = "openems.setup_protocol_item" - _description = "OpenEMS Edge Setup Protocol Entry Item" - _order = "setup_protocol_id, category, sequence asc" - - sequence = fields.Integer("Sort") - category = fields.Char("Category") - name = fields.Char("Name") - value = fields.Char("Value") - setup_protocol_id = fields.Many2one( - "openems.setup_protocol", "Setup Protocol", ondelete="cascade" - ) - view = fields.Char("View Identifier") - field = fields.Char("Field Identifier") - diff --git a/odoo/extra-addons/openems/models/stock_production_lot.py b/odoo/extra-addons/openems/models/stock_production_lot.py deleted file mode 100644 index 37ebb22..0000000 --- a/odoo/extra-addons/openems/models/stock_production_lot.py +++ /dev/null @@ -1,23 +0,0 @@ -from odoo import fields, models, api - - -class ProductionLot(models.Model): - _inherit = "stock.lot" - - device_id = fields.Many2one( - 'openems.device', compute='compute_device_id', inverse='device_inverse') - device_ids = fields.One2many('openems.device', 'stock_production_lot_id') - - @api.depends('device_ids') - def compute_device_id(self): - if len(self.device_ids) > 0: - self.device_id = self.device_ids[0] - - def device_inverse(self): - if len(self.device_ids) > 0: - if len(self.device_id.stock_production_lot_id) > 0: - raise ValueError("A serial number has already been assigned to the device") - - device = self.env['openems.device'].browse(self.device_ids[0].id) - device.stock_production_lot_id = False - self.device_id.stock_production_lot_id = self diff --git a/odoo/extra-addons/openems/models/user.py b/odoo/extra-addons/openems/models/user.py deleted file mode 100644 index 321dd87..0000000 --- a/odoo/extra-addons/openems/models/user.py +++ /dev/null @@ -1,37 +0,0 @@ -from odoo import fields, models - - -class ResUsers(models.Model): - _inherit = "res.users" - - branding_partner_id = fields.Many2one("res.partner", string="Branding Partner") - global_role = fields.Selection( - [ - ("admin", "Admin"), - ("installer", "Installer"), - ("owner", "Owner"), - ("guest", "Guest"), - ], - default="guest", - required=True, - ) - device_role_ids = fields.One2many( - "openems.device_user_role", "user_id", string="Roles" - ) - alerting_settings = fields.One2many( - "openems.alerting", "user_id", string="Alerting" - ) - openems_language = fields.Selection( - [ - ("EN", "English"), - ("DE", "German"), - ("CZ", "Czech"), - ("NL", "Dutch"), - ("ES", "Spanish"), - ("FR", "French"), - ("HU", "Hungarian"), - ("JA", "Japanese"), - ], - default="DE", - required=True, - ) diff --git a/odoo/extra-addons/openems/report/setup_protocol.xml b/odoo/extra-addons/openems/report/setup_protocol.xml deleted file mode 100644 index c9db4ec..0000000 --- a/odoo/extra-addons/openems/report/setup_protocol.xml +++ /dev/null @@ -1,311 +0,0 @@ - - - - OpenEMS Setup Protocol - openems.setup_protocol - qweb-pdf - openems.report_openems_setup_protocol_template - ('IBN-' + object.openems_device_id.name + '-' + object.create_date.strftime('%d.%m.%Y')) - - - diff --git a/odoo/extra-addons/openems/security/ir.model.access.csv b/odoo/extra-addons/openems/security/ir.model.access.csv deleted file mode 100644 index 1ccc0f1..0000000 --- a/odoo/extra-addons/openems/security/ir.model.access.csv +++ /dev/null @@ -1,31 +0,0 @@ -id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink -access_openems_device_portal,access_openems_device_portal,openems.model_openems_device,base.group_portal,1,0,0,0 -access_openems_device_user,access_openems_device_user,openems.model_openems_device,base.group_user,1,0,0,0 -access_openems_device_manager,access_openems_device_manager,openems.model_openems_device,openems.group_openems_manager,1,1,1,0 -access_openems_device_tag_portal,access_openems_device_tag_portal,openems.model_openems_device_tag,base.group_portal,1,0,0,0 -access_openems_device_tag_user,access_openems_device_tag_user,openems.model_openems_device_tag,base.group_user,1,0,0,0 -access_openems_device_tag_manager,access_openems_device_tag_manager,openems.model_openems_device_tag,openems.group_openems_manager,1,1,1,1 -access_openems_device_user_role_portal,access_openems_device_user_role_portal,openems.model_openems_device_user_role,base.group_portal,1,0,0,0 -access_openems_device_user_role_user,access_openems_device_user_role_user,openems.model_openems_device_user_role,base.group_user,1,0,0,0 -access_openems_device_user_role_manager,access_openems_device_user_role_manager,openems.model_openems_device_user_role,openems.group_openems_manager,1,1,1,1 -access_openems_alerting_portal,access_openems_alerting_portal,openems.model_openems_alerting,base.group_portal,1,0,0,0 -access_openems_alerting_user,access_openems_alerting_user,openems.model_openems_alerting,base.group_user,1,0,0,0 -access_openems_alerting_manager,access_openems_alerting_manager,openems.model_openems_alerting,openems.group_openems_manager,1,1,1,1 -access_openems_systemmessage_portal,access_openems_systemmessage_portal,openems.model_openems_systemmessage,base.group_portal,1,0,0,0 -access_openems_systemmessage_user,access_openems_systemmessage_user,openems.model_openems_systemmessage,base.group_user,1,0,0,0 -access_openems_systemmessage_manager,access_openems_systemmessage_manager,openems.model_openems_systemmessage,openems.group_openems_manager,1,1,1,1 -access_openems_openemsconfigupdate_portal,access_openems_openemsconfigupdate_portal,openems.model_openems_openemsconfigupdate,base.group_portal,1,0,0,0 -access_openems_openemsconfigupdate_user,access_openems_openemsconfigupdate_user,openems.model_openems_openemsconfigupdate,base.group_user,1,0,0,0 -access_openems_openemsconfigupdate_manager,access_openems_openemsconfigupdate_manager,openems.model_openems_openemsconfigupdate,openems.group_openems_manager,1,1,1,1 -access_openems_setup_protocol_portal,access_openems_setup_protocol_portal,openems.model_openems_setup_protocol,base.group_portal,1,0,0,0 -access_openems_setup_protocol_user,access_openems_setup_protocol_user,openems.model_openems_setup_protocol,base.group_user,1,0,0,0 -access_openems_setup_protocol_manager,access_openems_setup_protocol_manager,openems.model_openems_setup_protocol,openems.group_openems_manager,1,1,1,1 -access_openems_setup_protocol_production_lot_portal,access_openems_setup_protocol_production_lot_portal,openems.model_openems_setup_protocol_production_lot,base.group_portal,1,0,0,0 -access_openems_setup_protocol_production_lot_user,access_openems_setup_protocol_production_lot_user,openems.model_openems_setup_protocol_production_lot,base.group_user,1,0,0,0 -access_openems_setup_protocol_production_lot_manager,access_openems_setup_protocol_production_lot_manager,openems.model_openems_setup_protocol_production_lot,openems.group_openems_manager,1,1,1,1 -access_openems_setup_protocol_item_portal,access_openems_setup_protocol_item_portal,openems.model_openems_setup_protocol_item,base.group_portal,1,0,0,0 -access_openems_setup_protocol_item_user,access_openems_setup_protocol_item_user,openems.model_openems_setup_protocol_item,base.group_user,1,0,0,0 -access_openems_setup_protocol_item_manager,access_openems_setup_protocol_item_manager,openems.model_openems_setup_protocol_item,openems.group_openems_manager,1,1,1,1 -access_openems_production_lot_portal,access_openems_production_lot_portal,stock.model_stock_lot,base.group_portal,1,0,0,0 -access_openems_production_lot_user,access_openems_production_lot_user,stock.model_stock_lot,base.group_user,1,0,0,0 -access_openems_production_lot_manager,access_openems_production_lot_manager,stock.model_stock_lot,openems.group_openems_manager,1,0,0,0 diff --git a/odoo/extra-addons/openems/security/openems.xml b/odoo/extra-addons/openems/security/openems.xml deleted file mode 100644 index ef87c2f..0000000 --- a/odoo/extra-addons/openems/security/openems.xml +++ /dev/null @@ -1,54 +0,0 @@ - - - - OpenEMS - 30 - - - - Read access - Members of this group have reading access to all devices - - - - - Manager - Members of this group can manage all devices - - - - - - - Website: Show only approved devices to Portal and User - - ['|', ('user_role_ids.user_id','in',[user.id]), ('alerting_settings.user_id','in',[user.id])] - - - - - - - - - Website: Show all devices to readers group - - [(1,'=',1)] - - - - - - - - diff --git a/odoo/extra-addons/openems/setup/.setuptools-odoo-make-default-ignore b/odoo/extra-addons/openems/setup/.setuptools-odoo-make-default-ignore deleted file mode 100644 index 207e615..0000000 --- a/odoo/extra-addons/openems/setup/.setuptools-odoo-make-default-ignore +++ /dev/null @@ -1,2 +0,0 @@ -# addons listed in this file are ignored by -# setuptools-odoo-make-default (one addon per line) diff --git a/odoo/extra-addons/openems/setup/README b/odoo/extra-addons/openems/setup/README deleted file mode 100644 index a63d633..0000000 --- a/odoo/extra-addons/openems/setup/README +++ /dev/null @@ -1,2 +0,0 @@ -To learn more about this directory, please visit -https://pypi.python.org/pypi/setuptools-odoo diff --git a/odoo/extra-addons/openems/static/description/icon.png b/odoo/extra-addons/openems/static/description/icon.png deleted file mode 100644 index ee0aed1a0d5b623df9c4f3ead2a8d92ab7efc315..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 53271 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

`b%zWJVoybJJC+al7(vmUoDSw-d(zU?;>j| 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 - - - - Device: Tree - openems.device - - - - - - - - - - - - - - - - - Device: Search - openems.device - - - - - - - - - - - - - - - - - - - - - Device: Form - openems.device - -

- -
- -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
- - -
- - - - - - Device DeviceUserRole: Tree - openems.device_user_role - - - - - - - - - - Devices - ir.actions.act_window - openems.device - tree,form - - - - - - Device Configuration Updates - openems.openemsconfigupdate - - - - Device Configuration Updates: Tree - openems.openemsconfigupdate - - - - - - - - - - - Device Configuration Updates: Form - openems.openemsconfigupdate - -
- - - - - - - -
-
-
- - - - Systemmessages - openems.systemmessage - - - - Device Systemmessage: Tree - openems.systemmessage - - - - - - - - - - - Device Systemmessage: Form - openems.systemmessage - -
- - - - - - - -
-
-
- - - - - - - - - diff --git a/odoo/extra-addons/openems/views/partner.xml b/odoo/extra-addons/openems/views/partner.xml deleted file mode 100644 index 874530e..0000000 --- a/odoo/extra-addons/openems/views/partner.xml +++ /dev/null @@ -1,28 +0,0 @@ - - - - OpenEMS Partner: Form - res.partner - - - - - - - - - - - - - - - - - - - - - - - diff --git a/odoo/extra-addons/openems/views/setup_protocol.xml b/odoo/extra-addons/openems/views/setup_protocol.xml deleted file mode 100644 index bf2eee2..0000000 --- a/odoo/extra-addons/openems/views/setup_protocol.xml +++ /dev/null @@ -1,82 +0,0 @@ - - - - SetupProtocol: Form - openems.setup_protocol - -
- - -
- - -
- - - diff --git a/odoo/extra-addons/web_m2x_options/static/src/components/form.esm.js b/odoo/extra-addons/web_m2x_options/static/src/components/form.esm.js deleted file mode 100644 index ecb37d2..0000000 --- a/odoo/extra-addons/web_m2x_options/static/src/components/form.esm.js +++ /dev/null @@ -1,404 +0,0 @@ -/** @odoo-module **/ - -import { - Many2ManyTagsField, - Many2ManyTagsFieldColorEditable, -} from "@web/views/fields/many2many_tags/many2many_tags_field"; - -import {Dialog} from "@web/core/dialog/dialog"; -import {FormController} from "@web/views/form/form_controller"; -import {FormViewDialog} from "@web/views/view_dialogs/form_view_dialog"; -import {Many2OneAvatarField} from "@web/views/fields/many2one_avatar/many2one_avatar_field"; -import {Many2OneBarcodeField} from "@web/views/fields/many2one_barcode/many2one_barcode_field"; -import {Many2OneField} from "@web/views/fields/many2one/many2one_field"; -import {ReferenceField} from "@web/views/fields/reference/reference_field"; -import {X2ManyField} from "@web/views/fields/x2many/x2many_field"; -import {isX2Many} from "@web/views/utils"; -import {is_option_set} from "@web_m2x_options/components/relational_utils.esm"; -import {patch} from "@web/core/utils/patch"; -import {sprintf} from "@web/core/utils/strings"; -import {useService} from "@web/core/utils/hooks"; - -const {Component} = owl; - -/** - * Patch Many2ManyTagsField - **/ -patch(Many2ManyTagsField.prototype, "web_m2x_options.Many2ManyTagsField", { - setup() { - this._super(...arguments); - this.actionService = useService("action"); - }, - /** - * @override - */ - getTagProps(record) { - const props = this._super(...arguments); - props.onClick = (ev) => this.onMany2ManyBadgeClick(ev, record); - return props; - }, - async onMany2ManyBadgeClick(event, record) { - var self = this; - if (self.props.open) { - var context = self.context; - var id = record.data.id; - if (self.props.readonly) { - event.preventDefault(); - event.stopPropagation(); - const action = await self.orm.call( - self.props.relation, - "get_formview_action", - [[id]], - {context: context} - ); - self.actionService.doAction(action); - } else { - const view_id = await self.orm.call( - self.props.relation, - "get_formview_id", - [[id]], - {context: context} - ); - - const write_access = await self.orm.call( - self.props.relation, - "check_access_rights", - [], - {operation: "write", raise_exception: false} - ); - var can_write = self.props.canWrite; - self.dialog.add(FormViewDialog, { - resModel: self.props.relation, - resId: id, - context: context, - title: self.env._t("Open: ") + self.string, - viewId: view_id, - mode: !can_write || !write_access ? "readonly" : "edit", - onRecordSaved: () => self.props.value.model.load(), - }); - } - } - }, -}); - -Many2ManyTagsField.props = { - ...Many2ManyTagsField.props, - open: {type: Boolean, optional: true}, - canWrite: {type: Boolean, optional: true}, - nodeOptions: {type: Object, optional: true}, -}; - -const Many2ManyTagsFieldExtractProps = Many2ManyTagsField.extractProps; -Many2ManyTagsField.extractProps = ({attrs, field}) => { - const canOpen = Boolean(attrs.options.open); - const canWrite = attrs.can_write && Boolean(JSON.parse(attrs.can_write)); - return Object.assign(Many2ManyTagsFieldExtractProps({attrs, field}), { - open: canOpen, - canWrite: canWrite, - nodeOptions: attrs.options, - }); -}; - -/** - * Many2ManyTagsFieldColorEditable - **/ -patch( - Many2ManyTagsFieldColorEditable.prototype, - "web_m2x_options.Many2ManyTagsFieldColorEditable", - { - async onBadgeClick(event, record) { - if (this.props.canEditColor && !this.props.open) { - this._super(...arguments); - } - if (this.props.open) { - Many2ManyTagsField.prototype.onMany2ManyBadgeClick.bind(this)( - event, - record - ); - } - }, - } -); - -Many2ManyTagsFieldColorEditable.props = { - ...Many2ManyTagsFieldColorEditable.props, - open: {type: Boolean, optional: true}, - canWrite: {type: Boolean, optional: true}, - nodeOptions: {type: Object, optional: true}, -}; - -/** - * CreateConfirmationDialog - * New customized component for Many2One Field - **/ - -class CreateConfirmationDialog extends Component { - get title() { - return sprintf(this.env._t("New: %s"), this.props.name); - } - - async onCreate() { - await this.props.create(); - this.props.close(); - } - async onCreateEdit() { - await this.props.createEdit(); - this.props.close(); - } -} -CreateConfirmationDialog.components = {Dialog}; -CreateConfirmationDialog.template = - "web_m2x_options.Many2OneField.CreateConfirmationDialog"; - -/** - * Many2OneField - **/ - -patch(Many2OneField.prototype, "web_m2x_options.Many2OneField", { - setup() { - this._super(...arguments); - this.ir_options = Component.env.session.web_m2x_options; - }, - /** - * @override - */ - get Many2XAutocompleteProps() { - const props = this._super(...arguments); - return { - ...props, - searchLimit: this.props.searchLimit, - searchMore: this.props.searchMore, - canCreate: this.props.canCreate, - nodeOptions: this.props.nodeOptions, - }; - }, - - async openConfirmationDialog(request) { - var m2o_dialog_opt = - is_option_set(this.props.nodeOptions.m2o_dialog) || - (_.isUndefined(this.props.nodeOptions.m2o_dialog) && - is_option_set(this.ir_options["web_m2x_options.m2o_dialog"])) || - (_.isUndefined(this.props.nodeOptions.m2o_dialog) && - _.isUndefined(this.ir_options["web_m2x_options.m2o_dialog"])); - if (this.props.canCreate && this.state.isFloating && m2o_dialog_opt) { - return new Promise((resolve, reject) => { - this.addDialog(CreateConfirmationDialog, { - value: request, - name: this.props.string, - create: async () => { - try { - await this.quickCreate(request); - resolve(); - } catch (e) { - reject(e); - } - }, - createEdit: async () => { - try { - await this.quickCreate(request); - await this.props.record.model.load(); - this.openMany2X({ - resId: this.props.value[0], - context: this.user_context, - }); - resolve(); - } catch (e) { - reject(e); - } - }, - }); - }); - } - }, -}); - -const Many2OneFieldExtractProps = Many2OneField.extractProps; -Many2OneField.extractProps = ({attrs, field}) => { - return Object.assign(Many2OneFieldExtractProps({attrs, field}), { - searchLimit: attrs.options.limit, - searchMore: attrs.options.search_more, - nodeOptions: attrs.options, - }); -}; - -Many2OneField.props = { - ...Many2OneField.props, - searchMore: {type: Boolean, optional: true}, - nodeOptions: {type: Object, optional: true}, -}; - -/** - * FIXME: find better way to extend props in Many2OneField - * Override ReferenceField - * Since extracted/added props: nodeOptions and searchMore into Many2OneField props - * and this component inherited props from Many2OneField - * So, must override props here to avoid constraint validateProps (props schema) in owl core - */ - -ReferenceField.props = { - ...ReferenceField.props, - searchMore: {type: Boolean, optional: true}, - nodeOptions: {type: Object, optional: true}, -}; - -/** - * FIXME: find better way to extend props in Many2OneField - * Override Many2OneBarcodeField - * Since extracted/added props: nodeOptions and searchMore into Many2OneField props - * and this component inherited props from Many2OneField - * So, must override props here to avoid constraint validateProps (props schema) in owl core - */ - -Many2OneBarcodeField.props = { - ...Many2OneBarcodeField.props, - searchMore: {type: Boolean, optional: true}, - nodeOptions: {type: Object, optional: true}, -}; - -/** - * FIXME: find better way to extend props in Many2OneField - * Override Many2OneAvatarField - * Since extracted/added props: nodeOptions and searchMore into Many2OneField props - * and this component inherited props from Many2OneField - * So, must override props here to avoid constraint validateProps (props schema) in owl core - */ -Many2OneAvatarField.props = { - ...Many2OneAvatarField.props, - searchMore: {type: Boolean, optional: true}, - nodeOptions: {type: Object, optional: true}, -}; - -/** - * FIXME: find better way to extend props in Many2OneField - * Override mailing_m2o_filter - * Since extracted/added props: nodeOptions and searchMore into Many2OneField props - * and this component inherited props from Many2OneField - * So, must override props here to avoid constraint validateProps (props schema) in owl core - * This component is in module mass_mailing as optional module, - * So need to import dynamic way - */ -try { - (async () => { - // Make sure component mailing_m2o_filter in mass mailing module loaded - const installed_mass_mailing = await odoo.ready( - "@mass_mailing/js/mailing_m2o_filter" - ); - if (installed_mass_mailing) { - const {FieldMany2OneMailingFilter} = await odoo.runtimeImport( - "@mass_mailing/js/mailing_m2o_filter" - ); - FieldMany2OneMailingFilter.props = { - ...FieldMany2OneMailingFilter.props, - searchMore: {type: Boolean, optional: true}, - nodeOptions: {type: Object, optional: true}, - }; - } - })(); -} catch { - console.log( - "Ignore overriding props of component mailing_m2o_filter since the module is not installed" - ); -} - -/** - * X2ManyField - **/ -patch(X2ManyField.prototype, "web_m2x_options.X2ManyField", { - /** - * @override - */ - async openRecord(record) { - var self = this; - var open = this.props.open; - if (open && self.props.readonly) { - var res_id = record.data.id; - const action = await self.env.model.orm.call( - self.props.value.resModel, - "get_formview_action", - [[res_id]] - ); - return self.env.model.actionService.doAction(action); - } - return this._super.apply(this, arguments); - }, -}); - -const X2ManyFieldExtractProps = X2ManyField.extractProps; -X2ManyField.extractProps = ({attrs}) => { - const canOpen = Boolean(attrs.options.open); - return Object.assign(X2ManyFieldExtractProps({attrs}), { - open: canOpen, - }); -}; - -X2ManyField.props = { - ...X2ManyField.props, - open: {type: Boolean, optional: true}, -}; - -/** - * FormController - **/ -patch(FormController.prototype, "web_m2x_options.FormController", { - /** - * @override - */ - setup() { - var self = this; - this._super(...arguments); - - /** Due to problem of 2 onWillStart in native web core - * (see: https://github.com/odoo/odoo/blob/16.0/addons/web/static/src/views/model.js#L142) - * do the trick to override beforeLoadResolver here to customize viewLimit - */ - this.superBeforeLoadResolver = this.beforeLoadResolver; - this.beforeLoadResolver = async () => { - await self._setSubViewLimit(); - self.superBeforeLoadResolver(); - }; - }, - /** - * @override - * add more method to add subview limit on formview - */ - async _setSubViewLimit() { - const ir_options = Component.env.session.web_m2x_options; - - const activeFields = this.archInfo.activeFields, - fields = this.props.fields, - isSmall = this.user; - - var limit = ir_options["web_m2x_options.field_limit_entries"]; - if (!_.isUndefined(limit)) { - limit = parseInt(limit, 10); - } - - for (const fieldName in activeFields) { - const field = fields[fieldName]; - if (!isX2Many(field)) { - // What follows only concerns x2many fields - continue; - } - const fieldInfo = activeFields[fieldName]; - if (fieldInfo.modifiers.invisible === true) { - // No need to fetch the sub view if the field is always invisible - continue; - } - - if (!fieldInfo.FieldComponent.useSubView) { - // The FieldComponent used to render the field doesn't need a sub view - continue; - } - - let viewType = fieldInfo.viewMode || "list,kanban"; - viewType = viewType.replace("tree", "list"); - if (viewType.includes(",")) { - viewType = isSmall ? "kanban" : "list"; - } - fieldInfo.viewMode = viewType; - if (fieldInfo.views[viewType] && limit) { - fieldInfo.views[viewType].limit = limit; - } - } - }, -}); diff --git a/odoo/extra-addons/web_m2x_options/static/src/components/relational_utils.esm.js b/odoo/extra-addons/web_m2x_options/static/src/components/relational_utils.esm.js deleted file mode 100644 index 1fbe39e..0000000 --- a/odoo/extra-addons/web_m2x_options/static/src/components/relational_utils.esm.js +++ /dev/null @@ -1,221 +0,0 @@ -/** @odoo-module **/ - -import {Many2XAutocomplete} from "@web/views/fields/relational_utils"; -import {patch} from "@web/core/utils/patch"; -import {sprintf} from "@web/core/utils/strings"; -const {Component} = owl; - -export function is_option_set(option) { - if (_.isUndefined(option)) return false; - if (typeof option === "string") return option === "true" || option === "True"; - if (typeof option === "boolean") return option; - return false; -} - -patch(Many2XAutocomplete.prototype, "web_m2x_options.Many2XAutocomplete", { - setup() { - this._super(...arguments); - this.ir_options = Component.env.session.web_m2x_options; - }, - - async loadOptionsSource(request) { - if (this.lastProm) { - this.lastProm.abort(false); - } - // Add options limit used to change number of selections record - // returned. - if (!_.isUndefined(this.ir_options["web_m2x_options.limit"])) { - this.props.searchLimit = parseInt( - this.ir_options["web_m2x_options.limit"], - 10 - ); - this.limit = this.props.searchLimit; - } - - if (typeof this.props.nodeOptions.limit === "number") { - this.props.searchLimit = this.props.nodeOptions.limit; - this.limit = this.props.searchLimit; - } - - // Add options field_color and colors to color item(s) depending on field_color value - this.field_color = this.props.nodeOptions.field_color; - this.colors = this.props.nodeOptions.colors; - - this.lastProm = this.orm.call(this.props.resModel, "name_search", [], { - name: request, - operator: "ilike", - args: this.props.getDomain(), - limit: this.props.searchLimit + 1, - context: this.props.context, - }); - const records = await this.lastProm; - - var options = records.map((result) => ({ - value: result[0], - id: result[0], - label: result[1].split("\n")[0], - })); - - // Limit results if there is a custom limit options - if (this.limit) { - options = options.slice(0, this.props.searchLimit); - } - - // Search result value colors - if (this.colors && this.field_color) { - var value_ids = options.map((result) => result.value); - const objects = await this.orm.call( - this.props.resModel, - "search_read", - [], - { - domain: [["id", "in", value_ids]], - fields: [this.field_color], - } - ); - for (var index in objects) { - for (var index_value in options) { - if (options[index_value].id === objects[index].id) { - // Find value in values by comparing ids - var option = options[index_value]; - // Find color with field value as key - var color = - this.colors[objects[index][this.field_color]] || "black"; - option.style = "color:" + color; - break; - } - } - } - } - - // Quick create - // Note: Create should be before `search_more` (reserve native order) - // One more reason: when calling `onInputBlur`, native select the first option (activeSourceOption) - // which triggers m2o_dialog if m2o_dialog=true - var create_enabled = - this.props.quickCreate && !this.props.nodeOptions.no_create; - - var raw_result = _.map(records, function (x) { - return x[1]; - }); - var quick_create = is_option_set(this.props.nodeOptions.create), - quick_create_undef = _.isUndefined(this.props.nodeOptions.create), - m2x_create_undef = _.isUndefined(this.ir_options["web_m2x_options.create"]), - m2x_create = is_option_set(this.ir_options["web_m2x_options.create"]); - var show_create = - (!this.props.nodeOptions && (m2x_create_undef || m2x_create)) || - (this.props.nodeOptions && - (quick_create || - (quick_create_undef && (m2x_create_undef || m2x_create)))); - if ( - create_enabled && - !this.props.nodeOptions.no_quick_create && - request.length > 0 && - !_.contains(raw_result, request) && - show_create - ) { - options.push({ - label: sprintf(this.env._t(`Create "%s"`), request), - classList: "o_m2o_dropdown_option o_m2o_dropdown_option_create", - action: async (params) => { - try { - await this.props.quickCreate(request, params); - } catch { - const context = this.getCreationContext(request); - return this.openMany2X({context}); - } - }, - }); - } - - // Search more... - // Resolution order: - // 1- check if "search_more" is set locally in node's options - // 2- if set locally, apply its value - // 3- if not set locally, check if it's set globally via ir.config_parameter - // 4- if set globally, apply its value - // 5- if not set globally either, check if returned values are more than node's limit - var search_more = false; - if (!_.isUndefined(this.props.nodeOptions.search_more)) { - search_more = is_option_set(this.props.nodeOptions.search_more); - } else if (!_.isUndefined(this.ir_options["web_m2x_options.search_more"])) { - search_more = is_option_set(this.ir_options["web_m2x_options.search_more"]); - } else { - search_more = - !this.props.noSearchMore && this.props.searchLimit < records.length; - } - if (search_more) { - options.push({ - label: this.env._t("Search More..."), - action: this.onSearchMore.bind(this, request), - classList: "o_m2o_dropdown_option o_m2o_dropdown_option_search_more", - }); - } - - // Create and Edit - const canCreateEdit = - "createEdit" in this.activeActions - ? this.activeActions.createEdit - : this.activeActions.create; - if ( - !request.length && - !this.props.value && - (this.props.quickCreate || canCreateEdit) - ) { - options.push({ - label: this.env._t("Start typing..."), - classList: "o_m2o_start_typing", - unselectable: true, - }); - } - - // Create and edit ... - var create_edit = - is_option_set(this.props.nodeOptions.create) || - is_option_set(this.props.nodeOptions.create_edit), - create_edit_undef = - _.isUndefined(this.props.nodeOptions.create) && - _.isUndefined(this.props.nodeOptions.create_edit), - m2x_create_edit_undef = _.isUndefined( - this.ir_options["web_m2x_options.create_edit"] - ), - m2x_create_edit = is_option_set( - this.ir_options["web_m2x_options.create_edit"] - ); - var show_create_edit = - (!this.props.nodeOptions && (m2x_create_edit_undef || m2x_create_edit)) || - (this.props.nodeOptions && - (create_edit || - (create_edit_undef && (m2x_create_edit_undef || m2x_create_edit)))); - if ( - create_enabled && - !this.props.nodeOptions.no_create_edit && - show_create_edit && - request.length && - canCreateEdit - ) { - const context = this.getCreationContext(request); - options.push({ - label: this.env._t("Create and edit..."), - classList: "o_m2o_dropdown_option o_m2o_dropdown_option_create_edit", - action: () => this.openMany2X({context}), - }); - } - - // No records - if (!records.length && !this.activeActions.create) { - options.push({ - label: this.env._t("No records"), - classList: "o_m2o_no_result", - unselectable: true, - }); - } - - return options; - }, -}); - -Many2XAutocomplete.defaultProps = { - ...Many2XAutocomplete.defaultProps, - nodeOptions: {}, -}; diff --git a/odoo/extra-addons/web_m2x_options/tests/__init__.py b/odoo/extra-addons/web_m2x_options/tests/__init__.py deleted file mode 100644 index b472ff3..0000000 --- a/odoo/extra-addons/web_m2x_options/tests/__init__.py +++ /dev/null @@ -1,2 +0,0 @@ -# Copyright 2020 initOS GmbH. -from . import test_ir_config_parameter diff --git a/odoo/extra-addons/web_m2x_options/tests/test_ir_config_parameter.py b/odoo/extra-addons/web_m2x_options/tests/test_ir_config_parameter.py deleted file mode 100644 index eae00c7..0000000 --- a/odoo/extra-addons/web_m2x_options/tests/test_ir_config_parameter.py +++ /dev/null @@ -1,28 +0,0 @@ -# Copyright 2020 initOS GmbH. -# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). - -from odoo.tests import common - - -class TestIrConfigParameter(common.TransactionCase): - @classmethod - def setUpClass(cls): - super(TestIrConfigParameter, cls).setUpClass() - cls.env["ir.config_parameter"].set_param("web_m2x_options.limit", 10) - cls.env["ir.config_parameter"].set_param("web_m2x_options.create_edit", "True") - cls.env["ir.config_parameter"].set_param("web_m2x_options.create", "True") - cls.env["ir.config_parameter"].set_param("web_m2x_options.search_more", "False") - cls.env["ir.config_parameter"].set_param("web_m2x_options.m2o_dialog", "True") - - def test_web_m2x_options_key(self): - web_m2x_options = self.env["ir.config_parameter"].get_web_m2x_options() - self.assertIn("web_m2x_options.limit", web_m2x_options) - self.assertNotIn("web_m2x_options.m2o_dialog_test", web_m2x_options) - - def test_web_m2x_options_value(self): - web_m2x_options = self.env["ir.config_parameter"].get_web_m2x_options() - self.assertEqual(web_m2x_options["web_m2x_options.limit"], "10") - self.assertTrue(bool(web_m2x_options["web_m2x_options.create_edit"])) - self.assertTrue(bool(web_m2x_options["web_m2x_options.create"])) - self.assertEqual(web_m2x_options["web_m2x_options.search_more"], "False") - self.assertTrue(bool(web_m2x_options["web_m2x_options.m2o_dialog"])) diff --git a/odoo/odoo.conf b/odoo/odoo.conf deleted file mode 100644 index 28f70c1..0000000 --- a/odoo/odoo.conf +++ /dev/null @@ -1,37 +0,0 @@ -[options] -addons_path = /mnt/extra-addons -data_dir = /var/lib/odoo -; admin_passwd = admin -; csv_internal_sep = , -; db_maxconn = 64 -; db_name = False -; db_template = template1 -; dbfilter = .* -; debug_mode = False -; email_from = False -; limit_memory_hard = 2684354560 -; limit_memory_soft = 2147483648 -; limit_request = 8192 -; limit_time_cpu = 60 -; limit_time_real = 120 -; list_db = True -; log_db = False -; log_handler = [':INFO'] -; log_level = info -; logfile = None -; longpolling_port = 8072 -; max_cron_threads = 2 -; osv_memory_age_limit = 1.0 -; osv_memory_count_limit = False -; smtp_password = False -; smtp_port = 25 -; smtp_server = localhost -; smtp_ssl = False -; smtp_user = False -; workers = 0 -; xmlrpc = True -; xmlrpc_interface = -; xmlrpc_port = 8069 -; xmlrpcs = True -; xmlrpcs_interface = -; xmlrpcs_port = 8071 diff --git a/odoo/wait-for-psql.py b/odoo/wait-for-psql.py deleted file mode 100644 index a55f440..0000000 --- a/odoo/wait-for-psql.py +++ /dev/null @@ -1,32 +0,0 @@ -#!/usr/bin/env python3 -import argparse -import psycopg2 -import sys -import time - - -if __name__ == '__main__': - arg_parser = argparse.ArgumentParser() - arg_parser.add_argument('--db_host', required=True) - arg_parser.add_argument('--db_port', required=True) - arg_parser.add_argument('--db_user', required=True) - arg_parser.add_argument('--db_password', required=True) - arg_parser.add_argument('--timeout', type=int, default=5) - - args = arg_parser.parse_args() - - start_time = time.time() - while (time.time() - start_time) < args.timeout: - try: - conn = psycopg2.connect(user=args.db_user, host=args.db_host, port=args.db_port, password=args.db_password, dbname='postgres') - error = '' - break - except psycopg2.OperationalError as e: - error = e - else: - conn.close() - time.sleep(1) - - if error: - print("Database connection failure: %s" % error, file=sys.stderr) - sys.exit(1) From f14bb51b231f6fe85e756f3dd976bea2cbf3efd8 Mon Sep 17 00:00:00 2001 From: belloafeez Date: Fri, 2 Aug 2024 11:11:37 +0100 Subject: [PATCH 27/54] updated Signed-off-by: belloafeez --- docker-compose.yml | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/docker-compose.yml b/docker-compose.yml index c7eaeea..2e821be 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -32,14 +32,17 @@ services: - db ports: - "8069:8069" - volumes: - - odoo-web-data:/var/lib/odoo - - ./config:/etc/odoo - - ./addons:/mnt/extra-addons environment: - HOST=db - USER=odoo - PASSWORD=odoo # Replace 'odoo-password' with your actual password + volumes: + - odoo-web-data:/var/lib/odoo + - ./config:/etc/odoo + - ./addons:/mnt/extra-addons + + restart: always # run as a service + db: build: context: ./odoo-database From 51a291f58cb7662a00d0afd91790613db96020e9 Mon Sep 17 00:00:00 2001 From: belloafeez Date: Fri, 2 Aug 2024 11:16:25 +0100 Subject: [PATCH 28/54] updated Signed-off-by: belloafeez --- docker-compose.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docker-compose.yml b/docker-compose.yml index 2e821be..092a3e8 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -42,7 +42,7 @@ services: - ./addons:/mnt/extra-addons restart: always # run as a service - + db: build: context: ./odoo-database @@ -55,6 +55,7 @@ services: - PGDATA=/var/lib/postgresql/data/pgdata volumes: - odoo-db-data:/var/lib/postgresql/data/pgdata + restart: always # run as a service volumes: odoo-web-data: odoo-db-data: From 38f30c8840d542c195d002260ffff657d1af408c Mon Sep 17 00:00:00 2001 From: belloafeez Date: Fri, 2 Aug 2024 11:45:05 +0100 Subject: [PATCH 29/54] updated Signed-off-by: belloafeez --- docker-compose.yml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/docker-compose.yml b/docker-compose.yml index 092a3e8..0ca9c65 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -9,12 +9,12 @@ services: build: context: ./openems-backend image: openems-backend:latest - environment: - DB_HOST: applicationdb.clkigksc2ezs.us-east-1.rds.amazonaws.com # Assumes the PostgreSQL service is named openems-database - DB_PORT: "5432" - DB_NAME: openemsdb - DB_USER: openems - DB_PASSWORD: openemspassword + # environment: + # DB_HOST: applicationdb.clkigksc2ezs.us-east-1.rds.amazonaws.com # Assumes the PostgreSQL service is named openems-database + # DB_PORT: "5432" + # DB_NAME: openemsdb + # DB_USER: openems + # DB_PASSWORD: openemspassword # depends_on: # - openems-database From d5a677505fa149f24fdef3d891eca04c0d685e26 Mon Sep 17 00:00:00 2001 From: belloafeez Date: Fri, 2 Aug 2024 12:08:05 +0100 Subject: [PATCH 30/54] updated Signed-off-by: belloafeez --- docker-compose.yml | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/docker-compose.yml b/docker-compose.yml index 0ca9c65..e68a0bd 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -28,14 +28,14 @@ services: context: ./odoo image: odoo user: root - depends_on: - - db + # depends_on: + # - db ports: - "8069:8069" environment: - - HOST=db - - USER=odoo - - PASSWORD=odoo # Replace 'odoo-password' with your actual password + - HOST=applicationdb.clkigksc2ezs.us-east-1.rds.amazonaws.com + - USER=openems + - PASSWORD=openemspassword # Replace 'odoo-password' with your actual password volumes: - odoo-web-data:/var/lib/odoo - ./config:/etc/odoo @@ -43,19 +43,19 @@ services: restart: always # run as a service - db: - build: - context: ./odoo-database - image: odoo-db - user: root - environment: - - POSTGRES_DB=postgres - - POSTGRES_PASSWORD=odoo # Replace 'odoo-password' with your actual password - - POSTGRES_USER=odoo - - PGDATA=/var/lib/postgresql/data/pgdata - volumes: - - odoo-db-data:/var/lib/postgresql/data/pgdata - restart: always # run as a service + # db: + # build: + # context: ./odoo-database + # image: odoo-db + # user: root + # environment: + # - POSTGRES_DB=postgres + # - POSTGRES_PASSWORD=odoo # Replace 'odoo-password' with your actual password + # - POSTGRES_USER=odoo + # - PGDATA=/var/lib/postgresql/data/pgdata + # volumes: + # - odoo-db-data:/var/lib/postgresql/data/pgdata + # restart: always # run as a service volumes: odoo-web-data: odoo-db-data: From 40c7569e988cc2b8510b3fa293b21025149ddb48 Mon Sep 17 00:00:00 2001 From: belloafeez Date: Sun, 4 Aug 2024 17:04:24 +0100 Subject: [PATCH 31/54] updated Signed-off-by: belloafeez --- docker-compose.yml | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/docker-compose.yml b/docker-compose.yml index e68a0bd..3e1975e 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -33,9 +33,9 @@ services: ports: - "8069:8069" environment: - - HOST=applicationdb.clkigksc2ezs.us-east-1.rds.amazonaws.com - - USER=openems - - PASSWORD=openemspassword # Replace 'odoo-password' with your actual password + - HOST=db + - USER=odoo + - PASSWORD=odoo # Replace 'odoo-password' with your actual password volumes: - odoo-web-data:/var/lib/odoo - ./config:/etc/odoo @@ -43,19 +43,19 @@ services: restart: always # run as a service - # db: - # build: - # context: ./odoo-database - # image: odoo-db - # user: root - # environment: - # - POSTGRES_DB=postgres - # - POSTGRES_PASSWORD=odoo # Replace 'odoo-password' with your actual password - # - POSTGRES_USER=odoo - # - PGDATA=/var/lib/postgresql/data/pgdata - # volumes: - # - odoo-db-data:/var/lib/postgresql/data/pgdata - # restart: always # run as a service + db: + build: + context: ./odoo-database + image: odoo-db + user: root + environment: + - POSTGRES_DB=postgres + - POSTGRES_PASSWORD=odoo # Replace 'odoo-password' with your actual password + - POSTGRES_USER=odoo + - PGDATA=/var/lib/postgresql/data/pgdata + volumes: + - odoo-db-data:/var/lib/postgresql/data/pgdata + restart: always # run as a service volumes: odoo-web-data: odoo-db-data: From 5b38ac9001d6b0f68fd3e0f699bc83b614a679c5 Mon Sep 17 00:00:00 2001 From: belloafeez Date: Mon, 5 Aug 2024 22:02:16 +0100 Subject: [PATCH 32/54] updated Signed-off-by: belloafeez --- .github/workflows/deploy-pipeline.yml | 34 +++++------ .github/workflows/openems-deployment-td.json | 64 +------------------- docker-compose.yml | 36 +++++------ iac/ecs.tf | 63 +------------------ iac/security-group.tf | 8 --- iac/terraform.tfvars | 10 +-- 6 files changed, 42 insertions(+), 173 deletions(-) diff --git a/.github/workflows/deploy-pipeline.yml b/.github/workflows/deploy-pipeline.yml index 14b8abf..0e3a511 100644 --- a/.github/workflows/deploy-pipeline.yml +++ b/.github/workflows/deploy-pipeline.yml @@ -13,7 +13,7 @@ env: IMAGE_NAME_VALUE_2: openems-backend # IMAGE_NAME_VALUE_3: openems-db IMAGE_NAME_VALUE_4: odoo - IMAGE_NAME_VALUE_5: odoo-db + # IMAGE_NAME_VALUE_5: odoo-db IMAGE_NAME_VALUE_6: openems-edge TERRAFORM_ACTION: apply ECS_TD: .github/workflows/openems-deployment-td.json @@ -71,7 +71,7 @@ jobs: - name: Check if ECR repositories exist env: # List your repository names here - REPO_NAMES: '${{ env.IMAGE_NAME_VALUE_1 }},${{ env.IMAGE_NAME_VALUE_2 }},${{ env.IMAGE_NAME_VALUE_4 }},${{ env.IMAGE_NAME_VALUE_5 }},${{ env.IMAGE_NAME_VALUE_6 }}' + REPO_NAMES: '${{ env.IMAGE_NAME_VALUE_1 }},${{ env.IMAGE_NAME_VALUE_2 }},${{ env.IMAGE_NAME_VALUE_4 }},${{ env.IMAGE_NAME_VALUE_6 }}' run: | IFS=',' read -ra REPOS <<< "$REPO_NAMES" for repo in "${REPOS[@]}"; do @@ -89,7 +89,7 @@ jobs: - name: Create ECR repositories env: # List your repository names here - REPO_NAMES: '${{ env.IMAGE_NAME_VALUE_1 }},${{ env.IMAGE_NAME_VALUE_2 }},${{ env.IMAGE_NAME_VALUE_4 }},${{ env.IMAGE_NAME_VALUE_5 }},${{ env.IMAGE_NAME_VALUE_6 }}' + REPO_NAMES: '${{ env.IMAGE_NAME_VALUE_1 }},${{ env.IMAGE_NAME_VALUE_2 }},${{ env.IMAGE_NAME_VALUE_4 }},${{ env.IMAGE_NAME_VALUE_6 }}' run: | IFS=',' read -ra REPOS <<< "$REPO_NAMES" for repo in "${REPOS[@]}"; do @@ -155,12 +155,12 @@ jobs: format: 'sarif' output: 'trivy-results.sarif' - - name: Run Trivy vulnerability scanner - uses: aquasecurity/trivy-action@master - with: - image-ref: 'docker.io/library/${{ env.IMAGE_NAME_VALUE_5 }}:latest' - format: 'sarif' - output: 'trivy-results.sarif' + # - name: Run Trivy vulnerability scanner + # uses: aquasecurity/trivy-action@master + # with: + # image-ref: 'docker.io/library/${{ env.IMAGE_NAME_VALUE_5 }}:latest' + # format: 'sarif' + # output: 'trivy-results.sarif' - name: Run Trivy vulnerability scanner uses: aquasecurity/trivy-action@master @@ -223,19 +223,19 @@ jobs: container-name: openems-deployment-container-odoo image: ${{ secrets.ECR_REGISTRY }}/${{ env.IMAGE_NAME_VALUE_4 }}:latest - - name: Modify Amazon ECS task definition with forth container - id: render-odoo-db-container - uses: aws-actions/amazon-ecs-render-task-definition@v1 - with: - task-definition: ${{ steps.render-odoo-container.outputs.task-definition }} - container-name: openems-deployment-container-odoo-db - image: ${{ secrets.ECR_REGISTRY }}/${{ env.IMAGE_NAME_VALUE_4 }}:latest + # - name: Modify Amazon ECS task definition with forth container + # id: render-odoo-db-container + # uses: aws-actions/amazon-ecs-render-task-definition@v1 + # with: + # task-definition: ${{ steps.render-odoo-container.outputs.task-definition }} + # container-name: openems-deployment-container-odoo-db + # image: ${{ secrets.ECR_REGISTRY }}/${{ env.IMAGE_NAME_VALUE_4 }}:latest - name: Modify Amazon ECS task definition with fifth container id: render-edge-container uses: aws-actions/amazon-ecs-render-task-definition@v1 with: - task-definition: ${{ steps.render-odoo-db-container.outputs.task-definition }} + task-definition: ${{ steps.render-odoo-container.outputs.task-definition }} container-name: openems-deployment-container-edge image: ${{ secrets.ECR_REGISTRY }}/${{ env.IMAGE_NAME_VALUE_6 }}:latest diff --git a/.github/workflows/openems-deployment-td.json b/.github/workflows/openems-deployment-td.json index 6e49c48..5221cbf 100644 --- a/.github/workflows/openems-deployment-td.json +++ b/.github/workflows/openems-deployment-td.json @@ -38,28 +38,6 @@ } ], "essential": false, - "environment": [ - { - "name": "DB_NAME", - "value": "openemsdb" - }, - { - "name": "DB_HOST", - "value": "applicationdb.clkigksc2ezs.us-east-1.rds.amazonaws.com" - }, - { - "name": "DB_PORT", - "value": "5432" - }, - { - "name": "DB_USER", - "value": "openems" - }, - { - "name": "DB_PASSWORD", - "value": "openempassword" - } - ], "mountPoints": [], "volumesFrom": [], "logConfiguration": { @@ -87,11 +65,11 @@ "environment": [ { "name": "USER", - "value": "odoo" + "value": "odoo.clkigksc2ezs.us-east-1.rds.amazonaws.com" }, { "name": "PASSWORD", - "value": "odoo" + "value": "odoodb" }, { "name": "HOST", @@ -110,44 +88,6 @@ }, "systemControls": [] }, - { - "name": "openems-deployment-container-odoo-db", - "image": "470298448112.dkr.ecr.us-east-1.amazonaws.com/odoo-db:latest", - "cpu": 0, - "portMappings": [ - { - "containerPort": 5433, - "hostPort": 5433, - "protocol": "tcp" - } - ], - "essential": false, - "environment": [ - { - "name": "POSTGRES_USER", - "value": "odoo" - }, - { - "name": "POSTGRES_PASSWORD", - "value": "odoo" - }, - { - "name": "POSTGRES_DB", - "value": "postgres" - } - ], - "mountPoints": [], - "volumesFrom": [], - "logConfiguration": { - "logDriver": "awslogs", - "options": { - "awslogs-group": "/ecs/openems-deployment-tds", - "awslogs-region": "us-east-1", - "awslogs-stream-prefix": "ecs" - } - }, - "systemControls": [] - }, { "name": "openems-deployment-container-edge", "image": "470298448112.dkr.ecr.us-east-1.amazonaws.com/openems-edge:latest", diff --git a/docker-compose.yml b/docker-compose.yml index 3e1975e..5fb7b03 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -27,35 +27,31 @@ services: build: context: ./odoo image: odoo - user: root - # depends_on: - # - db ports: - "8069:8069" environment: - - HOST=db - - USER=odoo - - PASSWORD=odoo # Replace 'odoo-password' with your actual password + - HOST=odoo.clkigksc2ezs.us-east-1.rds.amazonaws.com + - USER=odoodb + - PASSWORD=Icui4cyou # Replace 'odoo-password' with your actual password volumes: - odoo-web-data:/var/lib/odoo - ./config:/etc/odoo - ./addons:/mnt/extra-addons - restart: always # run as a service - db: - build: - context: ./odoo-database - image: odoo-db - user: root - environment: - - POSTGRES_DB=postgres - - POSTGRES_PASSWORD=odoo # Replace 'odoo-password' with your actual password - - POSTGRES_USER=odoo - - PGDATA=/var/lib/postgresql/data/pgdata - volumes: - - odoo-db-data:/var/lib/postgresql/data/pgdata - restart: always # run as a service + # db: + # build: + # context: ./odoo-database + # image: odoo-db + # user: root + # environment: + # - POSTGRES_DB=postgres + # - POSTGRES_PASSWORD=odoo # Replace 'odoo-password' with your actual password + # - POSTGRES_USER=odoo + # - PGDATA=/var/lib/postgresql/data/pgdata + # volumes: + # - odoo-db-data:/var/lib/postgresql/data/pgdata + # restart: always # run as a service volumes: odoo-web-data: odoo-db-data: diff --git a/iac/ecs.tf b/iac/ecs.tf index bf8ff0e..8795ccc 100644 --- a/iac/ecs.tf +++ b/iac/ecs.tf @@ -59,29 +59,6 @@ resource "aws_ecs_task_definition" "ecs_task_definition" { image = "${local.secrets.ecr_registry}/${var.image_name_openems_backend}:${var.image_tag}" essential = false - environment = [ - { - name = "DB_HOST", - value = "applicationdb.clkigksc2ezs.us-east-1.rds.amazonaws.com" - }, - { - name = "DB_PORT", - value = "5432" - }, - { - name = "DB_NAME", - value = "openemsdb" - }, - { - name = "DB_USER", - value = "openems" - }, - { - name = "DB_PASSWORD", - value = "openempassword" - } - ] - portMappings = [ { containerPort = 8075 @@ -122,7 +99,7 @@ resource "aws_ecs_task_definition" "ecs_task_definition" { environment = [ { name = "HOST", - value = "db" + value = "odoo.clkigksc2ezs.us-east-1.rds.amazonaws.com" }, # { # name = "DB_PORT", @@ -134,7 +111,7 @@ resource "aws_ecs_task_definition" "ecs_task_definition" { # }, { name = "USER", - value = "odoo" + value = "odoodb" }, { name = "PASSWORD", @@ -149,42 +126,6 @@ resource "aws_ecs_task_definition" "ecs_task_definition" { } ] - logConfiguration = { - logDriver = "awslogs", - options = { - "awslogs-group" = "${aws_cloudwatch_log_group.log_group.name}", - "awslogs-region" = "${var.region}", - "awslogs-stream-prefix" = "ecs" - } - } - }, - { - name = "${var.project_name}-${var.environment}-container-odoo-db" - image = "${local.secrets.ecr_registry}/${var.image_name_odoo_db}:${var.image_tag}" - essential = false - environment = [ - { - name = "POSTGRES_USER", - value = "odoo" - }, - { - name = "POSTGRES_PASSWORD", - value = "odoo" - }, - { - name = "POSTGRES_DB", - value = "postgres" - } - ] - - portMappings = [ - { - containerPort = 5433 - hostPort = 5433 - } - ] - - logConfiguration = { logDriver = "awslogs", options = { diff --git a/iac/security-group.tf b/iac/security-group.tf index c777a55..713e4fd 100644 --- a/iac/security-group.tf +++ b/iac/security-group.tf @@ -4,14 +4,6 @@ resource "aws_security_group" "openems_security_group" { description = "enable LL access on port 80/443" vpc_id = aws_vpc.vpc.id - ingress { - description = "all traffic" - from_port = 0 - to_port = 0 - protocol = "tcp" - cidr_blocks = ["0.0.0.0/0"] - } - ingress { description = "all traffic" from_port = 8075 diff --git a/iac/terraform.tfvars b/iac/terraform.tfvars index d594e64..de4e541 100644 --- a/iac/terraform.tfvars +++ b/iac/terraform.tfvars @@ -28,10 +28,10 @@ secrets_manager_secret_name = "openems-demo-secret" # rds variables engine_type="postgres" -engine_type_version="16.2" +engine_type_version="16.3" multi_az_deployment="false" -database_cluster_name="applicationdb" -master_username="openems" -master_password="openemspassword" -initial_database_name="openemsdb" +database_cluster_name="odoodb" +master_username="odoo" +master_password="Icui4cyou" +initial_database_name="odoodb" instance_class_type="db.t3.micro" \ No newline at end of file From a5c9b7ca5dfaa5319fe0b5e030ad6c8bd6e98a33 Mon Sep 17 00:00:00 2001 From: belloafeez Date: Mon, 5 Aug 2024 22:15:05 +0100 Subject: [PATCH 33/54] updated Signed-off-by: belloafeez --- .github/workflows/destroy-pipeline.yml | 36 ++++++++++---------- .github/workflows/openems-deployment-td.json | 4 +-- docker-compose.yml | 6 ++-- iac/ecs.tf | 4 +-- iac/terraform.tfvars | 2 +- 5 files changed, 26 insertions(+), 26 deletions(-) diff --git a/.github/workflows/destroy-pipeline.yml b/.github/workflows/destroy-pipeline.yml index 1bc6766..d19f77e 100644 --- a/.github/workflows/destroy-pipeline.yml +++ b/.github/workflows/destroy-pipeline.yml @@ -1,4 +1,4 @@ -name: Destroy Pipeline +name: Deploy Pipeline on: workflow_dispatch: @@ -13,7 +13,7 @@ env: IMAGE_NAME_VALUE_2: openems-backend # IMAGE_NAME_VALUE_3: openems-db IMAGE_NAME_VALUE_4: odoo - IMAGE_NAME_VALUE_5: odoo-db + # IMAGE_NAME_VALUE_5: odoo-db IMAGE_NAME_VALUE_6: openems-edge TERRAFORM_ACTION: destroy ECS_TD: .github/workflows/openems-deployment-td.json @@ -71,7 +71,7 @@ jobs: - name: Check if ECR repositories exist env: # List your repository names here - REPO_NAMES: '${{ env.IMAGE_NAME_VALUE_1 }},${{ env.IMAGE_NAME_VALUE_2 }},${{ env.IMAGE_NAME_VALUE_4 }},${{ env.IMAGE_NAME_VALUE_5 }},${{ env.IMAGE_NAME_VALUE_6 }}' + REPO_NAMES: '${{ env.IMAGE_NAME_VALUE_1 }},${{ env.IMAGE_NAME_VALUE_2 }},${{ env.IMAGE_NAME_VALUE_4 }},${{ env.IMAGE_NAME_VALUE_6 }}' run: | IFS=',' read -ra REPOS <<< "$REPO_NAMES" for repo in "${REPOS[@]}"; do @@ -89,7 +89,7 @@ jobs: - name: Create ECR repositories env: # List your repository names here - REPO_NAMES: '${{ env.IMAGE_NAME_VALUE_1 }},${{ env.IMAGE_NAME_VALUE_2 }},${{ env.IMAGE_NAME_VALUE_4 }},${{ env.IMAGE_NAME_VALUE_5 }},${{ env.IMAGE_NAME_VALUE_6 }}' + REPO_NAMES: '${{ env.IMAGE_NAME_VALUE_1 }},${{ env.IMAGE_NAME_VALUE_2 }},${{ env.IMAGE_NAME_VALUE_4 }},${{ env.IMAGE_NAME_VALUE_6 }}' run: | IFS=',' read -ra REPOS <<< "$REPO_NAMES" for repo in "${REPOS[@]}"; do @@ -155,12 +155,12 @@ jobs: format: 'sarif' output: 'trivy-results.sarif' - - name: Run Trivy vulnerability scanner - uses: aquasecurity/trivy-action@master - with: - image-ref: 'docker.io/library/${{ env.IMAGE_NAME_VALUE_5 }}:latest' - format: 'sarif' - output: 'trivy-results.sarif' + # - name: Run Trivy vulnerability scanner + # uses: aquasecurity/trivy-action@master + # with: + # image-ref: 'docker.io/library/${{ env.IMAGE_NAME_VALUE_5 }}:latest' + # format: 'sarif' + # output: 'trivy-results.sarif' - name: Run Trivy vulnerability scanner uses: aquasecurity/trivy-action@master @@ -223,19 +223,19 @@ jobs: container-name: openems-deployment-container-odoo image: ${{ secrets.ECR_REGISTRY }}/${{ env.IMAGE_NAME_VALUE_4 }}:latest - - name: Modify Amazon ECS task definition with forth container - id: render-odoo-db-container - uses: aws-actions/amazon-ecs-render-task-definition@v1 - with: - task-definition: ${{ steps.render-odoo-container.outputs.task-definition }} - container-name: openems-deployment-container-odoo-db - image: ${{ secrets.ECR_REGISTRY }}/${{ env.IMAGE_NAME_VALUE_4 }}:latest + # - name: Modify Amazon ECS task definition with forth container + # id: render-odoo-db-container + # uses: aws-actions/amazon-ecs-render-task-definition@v1 + # with: + # task-definition: ${{ steps.render-odoo-container.outputs.task-definition }} + # container-name: openems-deployment-container-odoo-db + # image: ${{ secrets.ECR_REGISTRY }}/${{ env.IMAGE_NAME_VALUE_4 }}:latest - name: Modify Amazon ECS task definition with fifth container id: render-edge-container uses: aws-actions/amazon-ecs-render-task-definition@v1 with: - task-definition: ${{ steps.render-odoo-db-container.outputs.task-definition }} + task-definition: ${{ steps.render-odoo-container.outputs.task-definition }} container-name: openems-deployment-container-edge image: ${{ secrets.ECR_REGISTRY }}/${{ env.IMAGE_NAME_VALUE_6 }}:latest diff --git a/.github/workflows/openems-deployment-td.json b/.github/workflows/openems-deployment-td.json index 5221cbf..0bd2804 100644 --- a/.github/workflows/openems-deployment-td.json +++ b/.github/workflows/openems-deployment-td.json @@ -65,11 +65,11 @@ "environment": [ { "name": "USER", - "value": "odoo.clkigksc2ezs.us-east-1.rds.amazonaws.com" + "value": "odoodb.clkigksc2ezs.us-east-1.rds.amazonaws.com" }, { "name": "PASSWORD", - "value": "odoodb" + "value": "odoo" }, { "name": "HOST", diff --git a/docker-compose.yml b/docker-compose.yml index 5fb7b03..465a9f9 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -26,12 +26,12 @@ services: odoo16: build: context: ./odoo - image: odoo + image: odoo:latest ports: - "8069:8069" environment: - - HOST=odoo.clkigksc2ezs.us-east-1.rds.amazonaws.com - - USER=odoodb + - HOST=odoodb.clkigksc2ezs.us-east-1.rds.amazonaws.com + - USER=odoo - PASSWORD=Icui4cyou # Replace 'odoo-password' with your actual password volumes: - odoo-web-data:/var/lib/odoo diff --git a/iac/ecs.tf b/iac/ecs.tf index 8795ccc..6b58625 100644 --- a/iac/ecs.tf +++ b/iac/ecs.tf @@ -99,7 +99,7 @@ resource "aws_ecs_task_definition" "ecs_task_definition" { environment = [ { name = "HOST", - value = "odoo.clkigksc2ezs.us-east-1.rds.amazonaws.com" + value = "odoodb.clkigksc2ezs.us-east-1.rds.amazonaws.com" }, # { # name = "DB_PORT", @@ -111,7 +111,7 @@ resource "aws_ecs_task_definition" "ecs_task_definition" { # }, { name = "USER", - value = "odoodb" + value = "odoo" }, { name = "PASSWORD", diff --git a/iac/terraform.tfvars b/iac/terraform.tfvars index de4e541..d55d57e 100644 --- a/iac/terraform.tfvars +++ b/iac/terraform.tfvars @@ -17,7 +17,7 @@ image_name_openems_backend = "openems-backend" image_name_openems_edge = "openems-edge" # image_name_openems_db = "openems-db" image_name_odoo = "odoo" -image_name_odoo_db = "odoo-db" +# image_name_odoo_db = "odoo-db" image_tag = "latest" From 6c2bcd11e9ff56c03f212ac7747b29993b896d20 Mon Sep 17 00:00:00 2001 From: belloafeez Date: Mon, 5 Aug 2024 22:35:32 +0100 Subject: [PATCH 34/54] updated Signed-off-by: belloafeez --- iac/variables.tf | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/iac/variables.tf b/iac/variables.tf index d14b672..6ba6e1b 100644 --- a/iac/variables.tf +++ b/iac/variables.tf @@ -67,10 +67,10 @@ variable "image_name_odoo" { type = string } -variable "image_name_odoo_db" { - description = "the docker image name" - type = string -} +# variable "image_name_odoo_db" { +# description = "the docker image name" +# type = string +# } variable "image_name_openems_edge" { description = "the docker image name" From 7d9e97afbda8fb939c01bd78c3ad98e5a8d45688 Mon Sep 17 00:00:00 2001 From: belloafeez Date: Mon, 5 Aug 2024 22:44:10 +0100 Subject: [PATCH 35/54] updated Signed-off-by: belloafeez --- iac/backend.tf | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/iac/backend.tf b/iac/backend.tf index 9f3fdd3..1ba5fd6 100644 --- a/iac/backend.tf +++ b/iac/backend.tf @@ -1,8 +1,8 @@ terraform { backend "s3" { - bucket = "openems-deployment-tf-state-file" + bucket = "openems-tf-state-file" key = "openems-app/terraform.tfstate" region = "us-east-1" - dynamodb_table = "terraform-state-lock-openems-deployment" + dynamodb_table = "terraform-state-lock-openems" } } From 51accb2b6e847456f1c306c38b44e8b85cfb6640 Mon Sep 17 00:00:00 2001 From: belloafeez Date: Mon, 5 Aug 2024 23:05:42 +0100 Subject: [PATCH 36/54] updated Signed-off-by: belloafeez --- iac/terraform.tfvars | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iac/terraform.tfvars b/iac/terraform.tfvars index d55d57e..c2402b2 100644 --- a/iac/terraform.tfvars +++ b/iac/terraform.tfvars @@ -1,7 +1,7 @@ # environment variables region = "us-east-1" project_name = "openems" -environment = "deployment" +environment = "deployments" # vpc variables vpc_cidr = "10.0.0.0/16" From 598b6286ed5adeafd142ed0802d813d23b82f44e Mon Sep 17 00:00:00 2001 From: belloafeez Date: Wed, 7 Aug 2024 05:50:06 +0100 Subject: [PATCH 37/54] updated Signed-off-by: belloafeez --- iac/terraform.tfvars | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iac/terraform.tfvars b/iac/terraform.tfvars index c2402b2..d55d57e 100644 --- a/iac/terraform.tfvars +++ b/iac/terraform.tfvars @@ -1,7 +1,7 @@ # environment variables region = "us-east-1" project_name = "openems" -environment = "deployments" +environment = "deployment" # vpc variables vpc_cidr = "10.0.0.0/16" From e4589a43d6b6f76a8ae41d986020d40a80955ee9 Mon Sep 17 00:00:00 2001 From: belloafeez Date: Wed, 7 Aug 2024 06:07:38 +0100 Subject: [PATCH 38/54] updated Signed-off-by: belloafeez --- .github/workflows/deploy-pipeline.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/deploy-pipeline.yml b/.github/workflows/deploy-pipeline.yml index 0e3a511..300909b 100644 --- a/.github/workflows/deploy-pipeline.yml +++ b/.github/workflows/deploy-pipeline.yml @@ -125,6 +125,8 @@ jobs: - name: Build an image from Docker Compose run: | + docker-compose verion + docker-compose build - name: Run Trivy vulnerability scanner From 19a049af9baa07870c69f5e4da0d21eef8f33046 Mon Sep 17 00:00:00 2001 From: belloafeez Date: Wed, 7 Aug 2024 06:14:14 +0100 Subject: [PATCH 39/54] updated Signed-off-by: belloafeez --- .github/workflows/deploy-pipeline.yml | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/.github/workflows/deploy-pipeline.yml b/.github/workflows/deploy-pipeline.yml index 300909b..08a958f 100644 --- a/.github/workflows/deploy-pipeline.yml +++ b/.github/workflows/deploy-pipeline.yml @@ -123,10 +123,16 @@ jobs: - name: Login to Amazon ECR uses: aws-actions/amazon-ecr-login@v1 + - name: Install Docker Compose + run: | + curl -L "https://github.com/docker/compose/releases/download/1.29.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose + chmod +x /usr/local/bin/docker-compose + sudo systemctl start docker + + - name: Build an image from Docker Compose run: | docker-compose verion - docker-compose build - name: Run Trivy vulnerability scanner From 79d7f05fd6d2222b921a9f57ddd0ae4d4f0c4c35 Mon Sep 17 00:00:00 2001 From: belloafeez Date: Wed, 7 Aug 2024 06:22:46 +0100 Subject: [PATCH 40/54] updated Signed-off-by: belloafeez --- .github/workflows/deploy-pipeline.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/deploy-pipeline.yml b/.github/workflows/deploy-pipeline.yml index 08a958f..4ebec65 100644 --- a/.github/workflows/deploy-pipeline.yml +++ b/.github/workflows/deploy-pipeline.yml @@ -125,7 +125,7 @@ jobs: - name: Install Docker Compose run: | - curl -L "https://github.com/docker/compose/releases/download/1.29.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose + curl -L "https://github.com/docker/compose/releases/download/2.29.1/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose chmod +x /usr/local/bin/docker-compose sudo systemctl start docker From f1aff1d3653f3688f0fb5d948c29855684e900b1 Mon Sep 17 00:00:00 2001 From: belloafeez Date: Wed, 7 Aug 2024 06:35:06 +0100 Subject: [PATCH 41/54] updated Signed-off-by: belloafeez --- .github/workflows/deploy-pipeline.yml | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/.github/workflows/deploy-pipeline.yml b/.github/workflows/deploy-pipeline.yml index 4ebec65..a36efb5 100644 --- a/.github/workflows/deploy-pipeline.yml +++ b/.github/workflows/deploy-pipeline.yml @@ -123,12 +123,13 @@ jobs: - name: Login to Amazon ECR uses: aws-actions/amazon-ecr-login@v1 + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v2 + - name: Install Docker Compose run: | - curl -L "https://github.com/docker/compose/releases/download/2.29.1/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose + curl -L "https://github.com/docker/compose/releases/download/2.20.3/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose chmod +x /usr/local/bin/docker-compose - sudo systemctl start docker - - name: Build an image from Docker Compose run: | From 709e98644f914531dc338176c68160eb1455c3d1 Mon Sep 17 00:00:00 2001 From: belloafeez Date: Wed, 7 Aug 2024 06:46:34 +0100 Subject: [PATCH 42/54] updated Signed-off-by: belloafeez --- .github/workflows/deploy-pipeline.yml | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/.github/workflows/deploy-pipeline.yml b/.github/workflows/deploy-pipeline.yml index a36efb5..57a0ab3 100644 --- a/.github/workflows/deploy-pipeline.yml +++ b/.github/workflows/deploy-pipeline.yml @@ -123,18 +123,17 @@ jobs: - name: Login to Amazon ECR uses: aws-actions/amazon-ecr-login@v1 - - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v2 + # - name: Set up Docker Buildx + # uses: docker/setup-buildx-action@v2 - - name: Install Docker Compose - run: | - curl -L "https://github.com/docker/compose/releases/download/2.20.3/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose - chmod +x /usr/local/bin/docker-compose + # - name: Install Docker Compose + # run: | + # curl -L "https://github.com/docker/compose/releases/download/2.20.3/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose + # chmod +x /usr/local/bin/docker-compose - name: Build an image from Docker Compose run: | - docker-compose verion - docker-compose build + docker compose build - name: Run Trivy vulnerability scanner uses: aquasecurity/trivy-action@master From ad06cded912bb284a304260639deef99278d8fce Mon Sep 17 00:00:00 2001 From: belloafeez Date: Wed, 7 Aug 2024 07:23:29 +0100 Subject: [PATCH 43/54] updated Signed-off-by: belloafeez --- .github/workflows/openems-deployment-td.json | 1 + iac/ecs.tf | 2 + odoo/Dockerfile | 7 ++- odoo/entrypoint.sh | 49 ++++++++++++++++++++ 4 files changed, 57 insertions(+), 2 deletions(-) create mode 100644 odoo/entrypoint.sh diff --git a/.github/workflows/openems-deployment-td.json b/.github/workflows/openems-deployment-td.json index 0bd2804..5161724 100644 --- a/.github/workflows/openems-deployment-td.json +++ b/.github/workflows/openems-deployment-td.json @@ -76,6 +76,7 @@ "value": "db" } ], + "entrypoint": ["/entrypoint.sh"], "mountPoints": [], "volumesFrom": [], "logConfiguration": { diff --git a/iac/ecs.tf b/iac/ecs.tf index 6b58625..9155fea 100644 --- a/iac/ecs.tf +++ b/iac/ecs.tf @@ -119,6 +119,8 @@ resource "aws_ecs_task_definition" "ecs_task_definition" { } ] + entrypoint = ["/entrypoint.sh"] + portMappings = [ { containerPort = 8069 diff --git a/odoo/Dockerfile b/odoo/Dockerfile index 23bcdbd..6a96346 100644 --- a/odoo/Dockerfile +++ b/odoo/Dockerfile @@ -2,6 +2,9 @@ FROM odoo:16.0 +COPY entrypoint.sh /entrypoint.sh +RUN chmod +x /entrypoint.sh -# Expose port 8069 for Odoo web interface -EXPOSE 8069 \ No newline at end of file + +ENTRYPOINT ["/entrypoint.sh"] +CMD ["odoo"] \ No newline at end of file diff --git a/odoo/entrypoint.sh b/odoo/entrypoint.sh new file mode 100644 index 0000000..f802bcb --- /dev/null +++ b/odoo/entrypoint.sh @@ -0,0 +1,49 @@ +#!/bin/bash + +set -e + +if [ -v PASSWORD_FILE ]; then + PASSWORD="$(< $PASSWORD_FILE)" +fi + +# set the postgres database host, port, user and password according to the environment +# and pass them as arguments to the odoo process if not present in the config file +: ${HOST:=${DB_PORT_5432_TCP_ADDR:='db'}} +: ${PORT:=${DB_PORT_5432_TCP_PORT:=5432}} +: ${USER:=${DB_ENV_POSTGRES_USER:=${POSTGRES_USER:='odoo'}}} +: ${PASSWORD:=${DB_ENV_POSTGRES_PASSWORD:=${POSTGRES_PASSWORD:='odoo'}}} + +DB_ARGS=() +function check_config() { + param="$1" + value="$2" + if grep -q -E "^\s*\b${param}\b\s*=" "$ODOO_RC" ; then + value=$(grep -E "^\s*\b${param}\b\s*=" "$ODOO_RC" |cut -d " " -f3|sed 's/["\n\r]//g') + fi; + DB_ARGS+=("--${param}") + DB_ARGS+=("${value}") +} +check_config "db_host" "$HOST" +check_config "db_port" "$PORT" +check_config "db_user" "$USER" +check_config "db_password" "$PASSWORD" + +case "$1" in + -- | odoo) + shift + if [[ "$1" == "scaffold" ]] ; then + exec odoo "$@" + else + wait-for-psql.py ${DB_ARGS[@]} --timeout=30 + exec odoo "$@" "${DB_ARGS[@]}" + fi + ;; + -*) + wait-for-psql.py ${DB_ARGS[@]} --timeout=30 + exec odoo "$@" "${DB_ARGS[@]}" + ;; + *) + exec "$@" +esac + +exit 1 From ca0480a3512e96eaa9cb95e73a86d831d6b562d8 Mon Sep 17 00:00:00 2001 From: belloafeez Date: Wed, 7 Aug 2024 07:44:28 +0100 Subject: [PATCH 44/54] updated Signed-off-by: belloafeez --- .github/workflows/openems-deployment-td.json | 13 ++++++++----- docker-compose.yml | 1 + iac/ecs.tf | 15 +++++++++------ odoo/Dockerfile | 10 ++++++---- odoo/{entrypoint.sh => entrypoint.nh} | 4 ++-- 5 files changed, 26 insertions(+), 17 deletions(-) rename odoo/{entrypoint.sh => entrypoint.nh} (92%) diff --git a/.github/workflows/openems-deployment-td.json b/.github/workflows/openems-deployment-td.json index 5161724..2242599 100644 --- a/.github/workflows/openems-deployment-td.json +++ b/.github/workflows/openems-deployment-td.json @@ -64,19 +64,22 @@ "essential": false, "environment": [ { - "name": "USER", + "name": "HOST", "value": "odoodb.clkigksc2ezs.us-east-1.rds.amazonaws.com" }, { - "name": "PASSWORD", + "name": "USER", "value": "odoo" }, { - "name": "HOST", - "value": "db" + "name": "PORT", + "value": "5432" + }, + { + "name": "PASSWORD", + "value": "Icui4cyou" } ], - "entrypoint": ["/entrypoint.sh"], "mountPoints": [], "volumesFrom": [], "logConfiguration": { diff --git a/docker-compose.yml b/docker-compose.yml index 465a9f9..c5ef63f 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -32,6 +32,7 @@ services: environment: - HOST=odoodb.clkigksc2ezs.us-east-1.rds.amazonaws.com - USER=odoo + - Port=5432 - PASSWORD=Icui4cyou # Replace 'odoo-password' with your actual password volumes: - odoo-web-data:/var/lib/odoo diff --git a/iac/ecs.tf b/iac/ecs.tf index 9155fea..4e3adb4 100644 --- a/iac/ecs.tf +++ b/iac/ecs.tf @@ -101,10 +101,7 @@ resource "aws_ecs_task_definition" "ecs_task_definition" { name = "HOST", value = "odoodb.clkigksc2ezs.us-east-1.rds.amazonaws.com" }, - # { - # name = "DB_PORT", - # value = "5432" - # }, + # { # name = "DB_NAME", # value = "openemsdb" @@ -113,13 +110,19 @@ resource "aws_ecs_task_definition" "ecs_task_definition" { name = "USER", value = "odoo" }, + + { + name = "PORT", + value = "5432" + }, + { name = "PASSWORD", - value = "odoo" + value = "Icui4cyou" } ] - entrypoint = ["/entrypoint.sh"] + # entrypoint = ["/entrypoint.sh"] portMappings = [ { diff --git a/odoo/Dockerfile b/odoo/Dockerfile index 6a96346..7d946e2 100644 --- a/odoo/Dockerfile +++ b/odoo/Dockerfile @@ -1,10 +1,12 @@ # Use Odoo 16.0 as the base image FROM odoo:16.0 +EXPOSE 8069 -COPY entrypoint.sh /entrypoint.sh -RUN chmod +x /entrypoint.sh +# COPY entrypoint.sh /entrypoint.sh +# RUN chmod +x /entrypoint.sh -ENTRYPOINT ["/entrypoint.sh"] -CMD ["odoo"] \ No newline at end of file + +# ENTRYPOINT ["/entrypoint.sh"] +# CMD ["odoo"] \ No newline at end of file diff --git a/odoo/entrypoint.sh b/odoo/entrypoint.nh similarity index 92% rename from odoo/entrypoint.sh rename to odoo/entrypoint.nh index f802bcb..c2d755f 100644 --- a/odoo/entrypoint.sh +++ b/odoo/entrypoint.nh @@ -8,10 +8,10 @@ fi # set the postgres database host, port, user and password according to the environment # and pass them as arguments to the odoo process if not present in the config file -: ${HOST:=${DB_PORT_5432_TCP_ADDR:='db'}} +: ${HOST:=${DB_PORT_5432_TCP_ADDR:='odoodb.clkigksc2ezs.us-east-1.rds.amazonaws.com'}} : ${PORT:=${DB_PORT_5432_TCP_PORT:=5432}} : ${USER:=${DB_ENV_POSTGRES_USER:=${POSTGRES_USER:='odoo'}}} -: ${PASSWORD:=${DB_ENV_POSTGRES_PASSWORD:=${POSTGRES_PASSWORD:='odoo'}}} +: ${PASSWORD:=${DB_ENV_POSTGRES_PASSWORD:=${POSTGRES_PASSWORD:='Icui4cyou'}}} DB_ARGS=() function check_config() { From 312b3811078bd4e6ca6f5f319baca87f4d61a56d Mon Sep 17 00:00:00 2001 From: belloafeez Date: Wed, 7 Aug 2024 07:49:26 +0100 Subject: [PATCH 45/54] updated Signed-off-by: belloafeez --- docker-compose.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docker-compose.yml b/docker-compose.yml index c5ef63f..3c66b0e 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -32,7 +32,7 @@ services: environment: - HOST=odoodb.clkigksc2ezs.us-east-1.rds.amazonaws.com - USER=odoo - - Port=5432 + - PORT=5432 - PASSWORD=Icui4cyou # Replace 'odoo-password' with your actual password volumes: - odoo-web-data:/var/lib/odoo From 908756d40de4c14240bd20094e137db04f4fdfac Mon Sep 17 00:00:00 2001 From: belloafeez Date: Wed, 7 Aug 2024 07:55:37 +0100 Subject: [PATCH 46/54] updated Signed-off-by: belloafeez --- .github/workflows/openems-deployment-td.json | 2 +- iac/ecs.tf | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/openems-deployment-td.json b/.github/workflows/openems-deployment-td.json index 2242599..0f2f7b4 100644 --- a/.github/workflows/openems-deployment-td.json +++ b/.github/workflows/openems-deployment-td.json @@ -61,7 +61,7 @@ "protocol": "tcp" } ], - "essential": false, + "essential": true, "environment": [ { "name": "HOST", diff --git a/iac/ecs.tf b/iac/ecs.tf index 4e3adb4..40fcb10 100644 --- a/iac/ecs.tf +++ b/iac/ecs.tf @@ -94,7 +94,7 @@ resource "aws_ecs_task_definition" "ecs_task_definition" { { name = "${var.project_name}-${var.environment}-container-odoo" image = "${local.secrets.ecr_registry}/${var.image_name_odoo}:${var.image_tag}" - essential = false + essential = true environment = [ { From cd808d77a89e15fbc116d6cc5a292a9c164c8ea5 Mon Sep 17 00:00:00 2001 From: belloafeez Date: Wed, 7 Aug 2024 08:14:57 +0100 Subject: [PATCH 47/54] updated Signed-off-by: belloafeez --- .github/workflows/destroy-pipeline.yml | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/.github/workflows/destroy-pipeline.yml b/.github/workflows/destroy-pipeline.yml index d19f77e..ae167cd 100644 --- a/.github/workflows/destroy-pipeline.yml +++ b/.github/workflows/destroy-pipeline.yml @@ -123,9 +123,17 @@ jobs: - name: Login to Amazon ECR uses: aws-actions/amazon-ecr-login@v1 + # - name: Set up Docker Buildx + # uses: docker/setup-buildx-action@v2 + + # - name: Install Docker Compose + # run: | + # curl -L "https://github.com/docker/compose/releases/download/2.20.3/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose + # chmod +x /usr/local/bin/docker-compose + - name: Build an image from Docker Compose run: | - docker-compose build + docker compose build - name: Run Trivy vulnerability scanner uses: aquasecurity/trivy-action@master From 682b3ea957096f8e3a8aec760944ff7ad2f9188b Mon Sep 17 00:00:00 2001 From: belloafeez Date: Wed, 7 Aug 2024 08:24:35 +0100 Subject: [PATCH 48/54] updated Signed-off-by: belloafeez --- .github/workflows/destroy-pipeline.yml | 204 +------------------------ 1 file changed, 3 insertions(+), 201 deletions(-) diff --git a/.github/workflows/destroy-pipeline.yml b/.github/workflows/destroy-pipeline.yml index ae167cd..e739542 100644 --- a/.github/workflows/destroy-pipeline.yml +++ b/.github/workflows/destroy-pipeline.yml @@ -1,4 +1,4 @@ -name: Deploy Pipeline +name: Destroy Pipeline on: workflow_dispatch: @@ -34,8 +34,8 @@ jobs: aws-secret-access-key: ${{ env.AWS_SECRET_ACCESS_KEY }} aws-region: ${{ env.AWS_REGION }} - # Build AWS infrastructure - deploy_aws_infrastructure: + # Destroy AWS infrastructure + destroy_aws_infrastructure: name: Build AWS infrastructure needs: configure_aws_credentials runs-on: ubuntu-latest @@ -55,201 +55,3 @@ jobs: - name: Run Terraform apply/destroy working-directory: ./iac run: terraform ${{ env.TERRAFORM_ACTION }} -auto-approve - - # Create ECR repository - create_ecr_repository: - name: Create ECR repository - needs: - - deploy_aws_infrastructure - - configure_aws_credentials - if: needs.deploy_aws_infrastructure.output.terraform_action != 'destroy' - runs-on: ubuntu-latest - steps: - - name: Checkout repository - uses: actions/checkout@v4 - - - name: Check if ECR repositories exist - env: - # List your repository names here - REPO_NAMES: '${{ env.IMAGE_NAME_VALUE_1 }},${{ env.IMAGE_NAME_VALUE_2 }},${{ env.IMAGE_NAME_VALUE_4 }},${{ env.IMAGE_NAME_VALUE_6 }}' - run: | - IFS=',' read -ra REPOS <<< "$REPO_NAMES" - for repo in "${REPOS[@]}"; do - echo "Checking repository: $repo" - result=$(aws ecr describe-repositories --repository-names "$repo" 2>/dev/null | jq -r '.repositories[0]?.repositoryName // empty') - if [[ -z "$result" ]]; then - echo "Repository $repo does not exist." - else - echo "Repository $repo exists." - echo "repo_name_$repo=$result" >> $GITHUB_ENV - fi - done - continue-on-error: true - - - name: Create ECR repositories - env: - # List your repository names here - REPO_NAMES: '${{ env.IMAGE_NAME_VALUE_1 }},${{ env.IMAGE_NAME_VALUE_2 }},${{ env.IMAGE_NAME_VALUE_4 }},${{ env.IMAGE_NAME_VALUE_6 }}' - run: | - IFS=',' read -ra REPOS <<< "$REPO_NAMES" - for repo in "${REPOS[@]}"; do - echo "Creating repository: $repo" - if ! aws ecr describe-repositories --repository-names "$repo" 2>/dev/null; then - aws ecr create-repository --repository-name "$repo" - echo "Repository $repo created." - else - echo "Repository $repo already exists." - fi - done - # aws ecr put-registry-scanning-configuration \ - # --scan-type ENHANCED \ - # --rules '["scanFrequency" : "SCAN_ON_PUSH"]' \ - # --region ${{ env.AWS_REGION }} - - # Build Docker Image - - build_scan_push: - name: Build, Scan and push Docker image to ECR - needs: - - configure_aws_credentials - - deploy_aws_infrastructure - - create_ecr_repository - if: needs.deploy_aws_infrastructure.output.terraform_action != 'destroy' - runs-on: ubuntu-latest - steps: - - name: Checkout repository - uses: actions/checkout@v4 - - - name: Login to Amazon ECR - uses: aws-actions/amazon-ecr-login@v1 - - # - name: Set up Docker Buildx - # uses: docker/setup-buildx-action@v2 - - # - name: Install Docker Compose - # run: | - # curl -L "https://github.com/docker/compose/releases/download/2.20.3/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose - # chmod +x /usr/local/bin/docker-compose - - - name: Build an image from Docker Compose - run: | - docker compose build - - - name: Run Trivy vulnerability scanner - uses: aquasecurity/trivy-action@master - with: - image-ref: 'docker.io/library/${{ env.IMAGE_NAME_VALUE_1 }}:latest' - format: 'sarif' - output: 'trivy-results.sarif' - - - name: Run Trivy vulnerability scanner - uses: aquasecurity/trivy-action@master - with: - image-ref: 'docker.io/library/${{ env.IMAGE_NAME_VALUE_2 }}:latest' - format: 'sarif' - output: 'trivy-results.sarif' - - # - name: Run Trivy vulnerability scanner - # uses: aquasecurity/trivy-action@master - # with: - # image-ref: 'docker.io/library/${{ env.IMAGE_NAME_VALUE_3 }}:latest' - # format: 'sarif' - # output: 'trivy-results.sarif' - - - name: Run Trivy vulnerability scanner - uses: aquasecurity/trivy-action@master - with: - image-ref: 'docker.io/library/${{ env.IMAGE_NAME_VALUE_4 }}:latest' - format: 'sarif' - output: 'trivy-results.sarif' - - # - name: Run Trivy vulnerability scanner - # uses: aquasecurity/trivy-action@master - # with: - # image-ref: 'docker.io/library/${{ env.IMAGE_NAME_VALUE_5 }}:latest' - # format: 'sarif' - # output: 'trivy-results.sarif' - - - name: Run Trivy vulnerability scanner - uses: aquasecurity/trivy-action@master - with: - image-ref: 'docker.io/library/${{ env.IMAGE_NAME_VALUE_6 }}:latest' - format: 'sarif' - output: 'trivy-results.sarif' - - # - name: Upload Trivy scan results to GitHub Security tab - # uses: github/codeql-action/upload-sarif@v2 - # with: - # sarif_file: 'trivy-results.sarif' - - - name: Grant execute permission to the script - run: chmod +x ./push-to-ecr.sh - - - name: Retag Docker image and Push Docker Image to Amazon ECR - run: ./push-to-ecr.sh - - create_td_revision_restart_ecs: - name: Create new task definition revision and Restart ECS - needs: - - configure_aws_credentials - - deploy_aws_infrastructure - - create_ecr_repository - - build_scan_push - if: needs.deploy_aws_infrastructure.output.terraform_action != 'destroy' - runs-on: ubuntu-latest - steps: - - name: Checkout Repository - uses: actions/checkout@v4 - - - name: Render Amazon ECS task definition for first container - id: render-ui-container - uses: aws-actions/amazon-ecs-render-task-definition@v1 - with: - task-definition: ${{ env.ECS_TD }} - container-name: openems-deployment-container-ui - image: ${{ secrets.ECR_REGISTRY }}/${{ env.IMAGE_NAME_VALUE_1 }}:latest - - - name: Modify Amazon ECS task definition with first container - id: render-backend-container - uses: aws-actions/amazon-ecs-render-task-definition@v1 - with: - task-definition: ${{ steps.render-ui-container.outputs.task-definition }} - container-name: openems-deployment-container-backend - image: ${{ secrets.ECR_REGISTRY }}/${{ env.IMAGE_NAME_VALUE_2 }}:latest - - # - name: Modify Amazon ECS task definition with second container - # id: render-backend-db-container - # uses: aws-actions/amazon-ecs-render-task-definition@v1 - # with: - # task-definition: ${{ steps.render-backend-container.outputs.task-definition }} - - - name: Modify Amazon ECS task definition with third container - id: render-odoo-container - uses: aws-actions/amazon-ecs-render-task-definition@v1 - with: - task-definition: ${{ steps.render-backend-container.outputs.task-definition }} - container-name: openems-deployment-container-odoo - image: ${{ secrets.ECR_REGISTRY }}/${{ env.IMAGE_NAME_VALUE_4 }}:latest - - # - name: Modify Amazon ECS task definition with forth container - # id: render-odoo-db-container - # uses: aws-actions/amazon-ecs-render-task-definition@v1 - # with: - # task-definition: ${{ steps.render-odoo-container.outputs.task-definition }} - # container-name: openems-deployment-container-odoo-db - # image: ${{ secrets.ECR_REGISTRY }}/${{ env.IMAGE_NAME_VALUE_4 }}:latest - - - name: Modify Amazon ECS task definition with fifth container - id: render-edge-container - uses: aws-actions/amazon-ecs-render-task-definition@v1 - with: - task-definition: ${{ steps.render-odoo-container.outputs.task-definition }} - container-name: openems-deployment-container-edge - image: ${{ secrets.ECR_REGISTRY }}/${{ env.IMAGE_NAME_VALUE_6 }}:latest - - - name: Deploy to Amazon ECS service - uses: aws-actions/amazon-ecs-deploy-task-definition@v1 - with: - task-definition: ${{ steps.render-backend-container.outputs.task-definition }} - service: ${{ env.ECS_SERVICE }} - cluster: ${{ env.ECS_CLUSTER }} From c040df6b6c6b966ffde5328d19b9eac1339a6bb9 Mon Sep 17 00:00:00 2001 From: belloafeez Date: Sat, 10 Aug 2024 08:32:40 +0100 Subject: [PATCH 49/54] updated Signed-off-by: belloafeez --- docker-compose.yml | 2 ++ iac/security-group.tf | 46 ++++++++++++++++++++++++++++++++++++------- 2 files changed, 41 insertions(+), 7 deletions(-) diff --git a/docker-compose.yml b/docker-compose.yml index 3c66b0e..c1d9a02 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -9,6 +9,8 @@ services: build: context: ./openems-backend image: openems-backend:latest + ports: + - "8075:8075" # environment: # DB_HOST: applicationdb.clkigksc2ezs.us-east-1.rds.amazonaws.com # Assumes the PostgreSQL service is named openems-database # DB_PORT: "5432" diff --git a/iac/security-group.tf b/iac/security-group.tf index 713e4fd..9edbfc2 100644 --- a/iac/security-group.tf +++ b/iac/security-group.tf @@ -1,7 +1,7 @@ # create security group for the application load balancer resource "aws_security_group" "openems_security_group" { name = "${var.project_name}-${var.environment}-openems-sg" - description = "enable LL access on port 80/443" + description = "enable access on ports" vpc_id = aws_vpc.vpc.id ingress { @@ -14,8 +14,16 @@ resource "aws_security_group" "openems_security_group" { ingress { description = "all traffic" - from_port = 8069 - to_port = 8069 + from_port = 8089 + to_port = 8089 + protocol = "tcp" + cidr_blocks = ["0.0.0.0/0"] + } + + ingress { + description = "all traffic" + from_port = 8082 + to_port = 8082 protocol = "tcp" cidr_blocks = ["0.0.0.0/0"] } @@ -28,6 +36,22 @@ resource "aws_security_group" "openems_security_group" { cidr_blocks = ["0.0.0.0/0"] } + ingress { + description = "all traffic" + from_port = 8069 + to_port = 8069 + protocol = "tcp" + cidr_blocks = ["0.0.0.0/0"] + } + + ingress { + description = "all traffic" + from_port = 8079 + to_port = 8079 + protocol = "tcp" + cidr_blocks = ["0.0.0.0/0"] + } + ingress { description = "all traffic" from_port = 8087 @@ -36,6 +60,14 @@ resource "aws_security_group" "openems_security_group" { cidr_blocks = ["0.0.0.0/0"] } +ingress { + description = "all traffic" + from_port = 8080 + to_port = 8080 + protocol = "tcp" + cidr_blocks = ["0.0.0.0/0"] + } + egress { from_port = 0 to_port = 0 @@ -51,13 +83,13 @@ resource "aws_security_group" "openems_security_group" { # create security group for the database resource "aws_security_group" "database_security_group" { name = "${var.project_name}-${var.environment}-database-sg" - description = "enable MySQL/Aurora access on port 3306 via app server sg" + description = "enable Postgres access on port 5432 via openems server sg" vpc_id = aws_vpc.vpc.id ingress { - description = "mysql/aurora access" - from_port = 3306 - to_port = 3306 + description = "postgres/aurora access" + from_port = 5432 + to_port = 5432 protocol = "tcp" security_groups = [aws_security_group.openems_security_group.id] } From 0f244d7edf44dabf48b848ef314f38e0ccff5fd7 Mon Sep 17 00:00:00 2001 From: belloafeez Date: Mon, 2 Sep 2024 16:50:29 +0100 Subject: [PATCH 50/54] updated Signed-off-by: belloafeez --- odoo/Dockerfile | 3 ++- odoo/{entrypoint.nh => entrypoint.sh} | 0 2 files changed, 2 insertions(+), 1 deletion(-) rename odoo/{entrypoint.nh => entrypoint.sh} (100%) diff --git a/odoo/Dockerfile b/odoo/Dockerfile index 7d946e2..d91080d 100644 --- a/odoo/Dockerfile +++ b/odoo/Dockerfile @@ -1,5 +1,6 @@ # Use Odoo 16.0 as the base image -FROM odoo:16.0 + +FROM 470298448112.dkr.ecr.us-east-1.amazonaws.com/odoo16.00:latest EXPOSE 8069 diff --git a/odoo/entrypoint.nh b/odoo/entrypoint.sh similarity index 100% rename from odoo/entrypoint.nh rename to odoo/entrypoint.sh From bea93fdeee35432da238f87bfbdcf0b6b3031824 Mon Sep 17 00:00:00 2001 From: belloafeez Date: Mon, 2 Sep 2024 17:37:47 +0100 Subject: [PATCH 51/54] updated Signed-off-by: belloafeez --- odoo/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/odoo/Dockerfile b/odoo/Dockerfile index d91080d..c4bda0d 100644 --- a/odoo/Dockerfile +++ b/odoo/Dockerfile @@ -1,6 +1,6 @@ # Use Odoo 16.0 as the base image +FROM odoo:16.0 -FROM 470298448112.dkr.ecr.us-east-1.amazonaws.com/odoo16.00:latest EXPOSE 8069 From dc03488d92e90fb1288ba0f4a1f22ef688e0f775 Mon Sep 17 00:00:00 2001 From: belloafeez Date: Mon, 2 Sep 2024 18:06:03 +0100 Subject: [PATCH 52/54] updated Signed-off-by: belloafeez --- iac/security-group.tf | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/iac/security-group.tf b/iac/security-group.tf index 9edbfc2..4b60975 100644 --- a/iac/security-group.tf +++ b/iac/security-group.tf @@ -6,64 +6,64 @@ resource "aws_security_group" "openems_security_group" { ingress { description = "all traffic" - from_port = 8075 - to_port = 8075 + from_port = 8082 + to_port = 8082 protocol = "tcp" cidr_blocks = ["0.0.0.0/0"] } ingress { description = "all traffic" - from_port = 8089 - to_port = 8089 + from_port = 8069 + to_port = 8069 protocol = "tcp" cidr_blocks = ["0.0.0.0/0"] } ingress { description = "all traffic" - from_port = 8082 - to_port = 8082 + from_port = 8086 + to_port = 8086 protocol = "tcp" cidr_blocks = ["0.0.0.0/0"] } ingress { description = "all traffic" - from_port = 8086 - to_port = 8086 + from_port = 8089 + to_port = 8089 protocol = "tcp" cidr_blocks = ["0.0.0.0/0"] } ingress { description = "all traffic" - from_port = 8069 - to_port = 8069 + from_port = 8080 + to_port = 8080 protocol = "tcp" cidr_blocks = ["0.0.0.0/0"] } ingress { description = "all traffic" - from_port = 8079 - to_port = 8079 + from_port = 8087 + to_port = 8087 protocol = "tcp" cidr_blocks = ["0.0.0.0/0"] } ingress { description = "all traffic" - from_port = 8087 - to_port = 8087 + from_port = 8075 + to_port = 8075 protocol = "tcp" cidr_blocks = ["0.0.0.0/0"] } ingress { description = "all traffic" - from_port = 8080 - to_port = 8080 + from_port = 8079 + to_port = 8079 protocol = "tcp" cidr_blocks = ["0.0.0.0/0"] } From c55222125c15d13480a0c0e9007681c794264bc0 Mon Sep 17 00:00:00 2001 From: Aidan Barnes <66229298+aidan-barnes-axm@users.noreply.github.com> Date: Sun, 23 Nov 2025 08:46:02 -0500 Subject: [PATCH 53/54] Update terraform.tfvars Signed-off-by: Aidan Barnes <66229298+aidan-barnes-axm@users.noreply.github.com> --- iac/terraform.tfvars | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/iac/terraform.tfvars b/iac/terraform.tfvars index d55d57e..d08f86b 100644 --- a/iac/terraform.tfvars +++ b/iac/terraform.tfvars @@ -28,10 +28,10 @@ secrets_manager_secret_name = "openems-demo-secret" # rds variables engine_type="postgres" -engine_type_version="16.3" +engine_type_version="18.1" multi_az_deployment="false" database_cluster_name="odoodb" master_username="odoo" master_password="Icui4cyou" initial_database_name="odoodb" -instance_class_type="db.t3.micro" \ No newline at end of file +instance_class_type="db.t3.micro" From c59821c9814dcc49d1d4e2bfd32f9f475b938fa9 Mon Sep 17 00:00:00 2001 From: Aidan Barnes <66229298+aidan-barnes-axm@users.noreply.github.com> Date: Sun, 23 Nov 2025 09:46:13 -0500 Subject: [PATCH 54/54] Update Dockerfile to use Temurin instead of OpenJDK OpenJDK images announced as deprecated on Docker hub :https://hub.docker.com/_/openjdk Signed-off-by: Aidan Barnes <66229298+aidan-barnes-axm@users.noreply.github.com> --- openems-edge/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openems-edge/Dockerfile b/openems-edge/Dockerfile index 3f341ed..b4086f6 100644 --- a/openems-edge/Dockerfile +++ b/openems-edge/Dockerfile @@ -1,5 +1,5 @@ # Use an official Java runtime as a parent image -FROM openjdk:17 +FROM eclipse-temurin:17 # Set the working directory in the container WORKDIR /usr/lib/openems