Compare commits

..

4 Commits

11 changed files with 270 additions and 31 deletions

View File

@@ -14,7 +14,7 @@ readonly FILESTORE_SUBPATH="var/lib/odoo/filestore"
check_required_commands() {
local missing=()
for cmd in docker compose sudo rsync; do
for cmd in docker compose sudo rsync yq; do
if ! command -v "$cmd" &>/dev/null; then
missing+=("$cmd")
fi
@@ -100,7 +100,83 @@ exec_python_script_in_odoo_shell() {
run_compose --debug run "$service_name" shell -d "$db_name" --no-http --stop-after-init < "$python_script"
}
# Classifies missing modules into 4 categories based on the known_changes.yaml
# files from each traversed version (from ORIGIN_VERSION+1 to FINAL_VERSION).
# The following global arrays are populated:
# addons_obsolete : modules that became obsolete
# addons_core : modules merged into Odoo Core
# addons_renamed : renamed modules (format "old_name -> new_name")
# addons_truly_missing : modules that are genuinely missing
#
# Prerequisites: ORIGIN_VERSION and FINAL_VERSION must be exported.
classify_missing_addons() {
local missing_addons_raw="$1"
addons_obsolete=()
addons_core=()
addons_renamed=()
addons_truly_missing=()
# Convert the string into an array (one entry per line)
local -a missing=()
while IFS= read -r line; do
[[ -n "$line" ]] && missing+=("$line")
done <<< "$missing_addons_raw"
if [[ ${#missing[@]} -eq 0 ]]; then
return 0
fi
# Build lookup tables from all known_changes.yaml files in traversed versions
local -A known_obsolete=()
local -A known_core=()
local -A known_renamed=()
local versions_path="${PROJECT_ROOT}/versions"
local v
for v in $(seq $((ORIGIN_VERSION + 1)) "$FINAL_VERSION"); do
local yaml_file="${versions_path}/${v}.0/known_changes.yaml"
[[ -f "$yaml_file" ]] || continue
local mod
while IFS= read -r mod; do
[[ -n "$mod" && "$mod" != "null" ]] && known_obsolete["$mod"]=1
done < <(yq '.obsolete[]?' "$yaml_file" 2>/dev/null)
while IFS= read -r mod; do
[[ -n "$mod" && "$mod" != "null" ]] && known_core["$mod"]=1
done < <(yq '.merged_in_core[]?' "$yaml_file" 2>/dev/null)
local count
count=$(yq '.renamed | length' "$yaml_file" 2>/dev/null)
if [[ "$count" =~ ^[0-9]+$ && "$count" -gt 0 ]]; then
local i
for ((i = 0; i < count; i++)); do
local old new
old=$(yq ".renamed[$i].old" "$yaml_file" 2>/dev/null)
new=$(yq ".renamed[$i].new" "$yaml_file" 2>/dev/null)
[[ -n "$old" && "$old" != "null" ]] && known_renamed["$old"]="$new"
done
fi
done
# Classify each missing module
local mod
for mod in "${missing[@]}"; do
if [[ -n "${known_obsolete[$mod]:-}" ]]; then
addons_obsolete+=("$mod")
elif [[ -n "${known_core[$mod]:-}" ]]; then
addons_core+=("$mod")
elif [[ -n "${known_renamed[$mod]:-}" ]]; then
addons_renamed+=("${mod} -> ${known_renamed[$mod]}")
else
addons_truly_missing+=("$mod")
fi
done
}
export PROJECT_ROOT DATASTORE_PATH FILESTORE_SUBPATH
export -f log_info log_warn log_error log_step confirm_or_exit
export -f check_required_commands
export -f query_postgres_container copy_database copy_filestore run_compose exec_python_script_in_odoo_shell
export -f classify_missing_addons

View File

@@ -60,9 +60,23 @@ echo "Retrieve missing addons..."
missing_addons=$(query_postgres_container "$SQL_MISSING_ADDONS" "$DB_NAME")
log_step "ADD-ONS CHECK"
echo "Installed add-ons not available in final Odoo version:"
echo "$missing_addons"
confirm_or_exit "Do you accept to migrate with these add-ons still installed?"
classify_missing_addons "$missing_addons"
if [[ ${#addons_obsolete[@]} -gt 0 ]]; then
log_info "Obsolete modules (${#addons_obsolete[@]}): ${addons_obsolete[*]}"
fi
if [[ ${#addons_core[@]} -gt 0 ]]; then
log_info "Merged into Odoo Core (${#addons_core[@]}): ${addons_core[*]}"
fi
if [[ ${#addons_renamed[@]} -gt 0 ]]; then
log_info "Renamed modules (${#addons_renamed[@]}): ${addons_renamed[*]}"
fi
if [[ ${#addons_truly_missing[@]} -gt 0 ]]; then
log_warn "Truly missing modules (${#addons_truly_missing[@]}): ${addons_truly_missing[*]}"
confirm_or_exit "Do you accept to migrate with these add-ons truly missing?"
else
log_info "No truly missing modules — all accounted for."
fi
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
PYTHON_SCRIPT="${SCRIPT_DIR}/lib/python/check_views.py"

View File

@@ -31,8 +31,10 @@ fi
check_required_commands
readonly ORIGIN_VERSION="$1"
readonly FINAL_VERSION="$2"
export ORIGIN_VERSION="$1"
readonly ORIGIN_VERSION
export FINAL_VERSION="$2"
readonly FINAL_VERSION
readonly ORIGIN_DB_NAME="$3"
readonly ORIGIN_SERVICE_NAME="$4"

View File

@@ -0,0 +1,10 @@
# Modules that became obsolete in version 13.0
obsolete: []
# Modules merged into Odoo Core in version 13.0
merged_in_core: []
# Modules renamed in version 13.0
renamed: []
# - old: old_name
# new: new_name

View File

@@ -0,0 +1,10 @@
# Modules that became obsolete in version 14.0
obsolete: []
# Modules merged into Odoo Core in version 14.0
merged_in_core: []
# Modules renamed in version 14.0
renamed: []
# - old: old_name
# new: new_name

View File

@@ -0,0 +1,10 @@
# Modules that became obsolete in version 15.0
obsolete: []
# Modules merged into Odoo Core in version 15.0
merged_in_core: []
# Modules renamed in version 15.0
renamed: []
# - old: old_name
# new: new_name

View File

@@ -0,0 +1,10 @@
# Modules that became obsolete in version 16.0
obsolete: []
# Modules merged into Odoo Core in version 16.0
merged_in_core: []
# Modules renamed in version 16.0
renamed: []
# - old: old_name
# new: new_name

View File

@@ -0,0 +1,10 @@
# Modules that became obsolete in version 17.0
obsolete: []
# Modules merged into Odoo Core in version 17.0
merged_in_core: []
# Modules renamed in version 17.0
renamed: []
# - old: old_name
# new: new_name

View File

@@ -0,0 +1,10 @@
# Modules that became obsolete in version 18.0
obsolete: []
# Modules merged into Odoo Core in version 18.0
merged_in_core: []
# Modules renamed in version 18.0
renamed: []
# - old: old_name
# new: new_name

View File

@@ -6,7 +6,16 @@ echo "Post migration to 18.0..."
# ============================================================================
# BANK-PAYMENT -> BANK-PAYMENT-ALTERNATIVE DATA MIGRATION
# Source PR: https://github.com/OCA/bank-payment-alternative/pull/42
#
# Only executed if account_payment_mode table exists (module was installed).
# ============================================================================
# Check if account_payment_mode table exists (meaning the module was installed before migration)
BANK_PAYMENT_TABLE_EXISTS=$(query_postgres_container "SELECT COUNT(*) FROM information_schema.tables WHERE table_name = 'account_payment_mode';" ou18 2>/dev/null | grep -E '^\s*[0-9]+' | tr -d ' ' || echo "0")
if [ "$BANK_PAYMENT_TABLE_EXISTS" -gt 0 ]; then
echo "Table account_payment_mode exists, proceeding with bank-payment data migration..."
BANK_PAYMENT_POST_SQL=$(cat <<'EOF'
DO $$
DECLARE
@@ -55,17 +64,20 @@ BEGIN
) RETURNING id INTO new_line_id;
IF mode_rec.bank_account_link = 'variable' THEN
IF EXISTS (SELECT FROM information_schema.tables
WHERE table_name = 'account_journal_account_payment_method_line_rel') THEN
FOR journal_rec IN
SELECT rel.journal_id
FROM account_payment_mode_variable_journal_rel rel
WHERE rel.payment_mode_id = mode_rec.id
LOOP
INSERT INTO account_payment_method_line_journal_rel
INSERT INTO account_journal_account_payment_method_line_rel
(account_payment_method_line_id, account_journal_id)
VALUES (new_line_id, journal_rec.journal_id)
ON CONFLICT DO NOTHING;
END LOOP;
END IF;
END IF;
RAISE NOTICE 'Migrated payment mode % -> payment method line %', mode_rec.id, new_line_id;
END LOOP;
@@ -157,4 +169,8 @@ EOF
echo "Executing bank-payment batch migration..."
query_postgres_container "$BANK_PAYMENT_BATCH_SQL" ou18 || exit 1
else
echo "Table account_payment_mode not found, skipping bank-payment migration."
fi
echo "Post migration to 18.0 completed!"

View File

@@ -14,7 +14,16 @@ copy_database ou17 ou18 ou18 || exit 1
# This renaming MUST be done BEFORE OpenUpgrade runs, so that the migration
# scripts in the new modules (account_payment_base_oca, account_payment_batch_oca)
# can properly migrate the data.
#
# Only executed if account_payment_mode module was installed before migration.
# ============================================================================
# Check if account_payment_mode module is installed
BANK_PAYMENT_INSTALLED=$(query_postgres_container "SELECT COUNT(*) FROM ir_module_module WHERE name = 'account_payment_mode' AND state = 'installed';" ou18 2>/dev/null | grep -E '^\s*[0-9]+' | tr -d ' ' || echo "0")
if [ "$BANK_PAYMENT_INSTALLED" -gt 0 ]; then
echo "Module account_payment_mode is installed, proceeding with bank-payment migration..."
BANK_PAYMENT_RENAME_SQL=$(cat <<'EOF'
DO $$
DECLARE
@@ -83,6 +92,68 @@ EOF
echo "Executing bank-payment pre-migration..."
query_postgres_container "$BANK_PAYMENT_PRE_SQL" ou18 || exit 1
else
echo "Module account_payment_mode not installed, skipping bank-payment migration."
fi
# ============================================================================
# FIX: Rename company-dependent columns before OpenUpgrade runs
# In Odoo 18, company-dependent fields are stored as JSONB columns.
# The ORM's _auto_init() tries to convert existing VARCHAR columns to JSONB,
# which fails if the data is not valid JSON.
# Solution: Rename the columns so Odoo creates new JSONB columns, then
# OpenUpgrade's convert_company_dependent() will migrate the data from ir.property.
#
# See: https://github.com/OCA/OpenUpgrade/issues/5449
# ============================================================================
COMPANY_DEPENDENT_FIX_SQL=$(cat <<'EOF'
DO $$
BEGIN
-- res.partner.barcode (base module)
IF EXISTS (SELECT 1 FROM information_schema.columns
WHERE table_name = 'res_partner' AND column_name = 'barcode') THEN
ALTER TABLE res_partner RENAME COLUMN barcode TO openupgrade_legacy_18_0_barcode;
RAISE NOTICE 'Renamed res_partner.barcode for company-dependent conversion';
END IF;
END $$;
EOF
)
echo "Fixing company-dependent columns for Odoo 18..."
query_postgres_container "$COMPANY_DEPENDENT_FIX_SQL" ou18 || exit 1
# ============================================================================
# CLEAN: Reset l10n_fr_secure_sequence_number field from table pos_order
# In Odoo 18, several checks are done concerning the pos order, for instance
# that there is no missing number in the order sequence. BUT, if add-on l10n_fr_pos_cert
# has been installer AFTER the creation of some pos orders, then the l10n_fr_secure_sequence_number
# is not filled correctly for all the pos order, and v18 checks fails.
# Solution: reset all the l10n_fr_secure_sequence_number values so that there
# is no missing sequence.
# ============================================================================
RESET_SECURE_SEQUENCE_NUMBER_SQL=$(cat <<'EOF'
DO $$
BEGIN
-- res.partner.barcode (base module)
IF EXISTS (SELECT 1 FROM information_schema.columns
WHERE table_name = 'pos_order' AND column_name = 'l10n_fr_secure_sequence_number') THEN
UPDATE pos_order t
SET l10n_fr_secure_sequence_number = r.num
FROM (
SELECT id,
ROW_NUMBER() OVER (ORDER BY date_order ASC) AS num
FROM pos_order
) r
WHERE t.id = r.id;
END IF;
END $$;
EOF
)
echo "Reset l10n_fr_secure_sequence_number values to avoid missing sequence value for Odoo 18..."
query_postgres_container "$RESET_SECURE_SEQUENCE_NUMBER_SQL" ou18 || exit 1
# Execute SQL pre-migration commands
PRE_MIGRATE_SQL=$(cat <<'EOF'
UPDATE account_analytic_plan SET default_applicability=NULL WHERE default_applicability='optional';