``account_factoring`` (depends on ``account_payment_partner`` + ``account_payment_mode``) is replaced by ``account_factoring_oca`` (depends on ``account_payment_base_oca`` + ``account_payment_base_oca_sale``) in v18. Both modules share rigorously identical stored fields on ``account_journal``, ``account_move`` and ``res_partner``, so a rename (not an uninstall) preserves the 4910 invoice factor statuses, 311 partner credit limits and journal factor config; OpenUpgrade then treats ``account_factoring_oca`` as already installed and adopts the existing columns via ORM ``_auto_init``. Redirects dependencies pointing to the old name, drops the obsolete ``account_payment_partner``/``account_payment_mode`` dependencies and inserts the new OCA equivalents. Must run AFTER the bank-payment renaming block which creates ``account_payment_base_oca`` in the DB. The orphaned ``base.module_account_factoring`` xmlid is renamed so OpenUpgrade can rediscover the physical ``account_factoring`` addon dir without conflicting on ``(base, module_account_factoring)``.
271 lines
12 KiB
Bash
Executable File
271 lines
12 KiB
Bash
Executable File
#!/bin/bash
|
|
set -euo pipefail
|
|
|
|
echo "Prepare migration to 18.0..."
|
|
|
|
# Copy database
|
|
copy_database ou17 ou18 ou18 || exit 1
|
|
|
|
# ============================================================================
|
|
# REMOVE contract_payment_mode (depends on obsolete account_payment_partner)
|
|
#
|
|
# contract_payment_mode v18 still depends on account_payment_partner (deleted
|
|
# by the bank-payment renaming below) and uses the obsolete account.payment.mode
|
|
# model. No v18 replacement exists — account_payment_base_oca provides no
|
|
# contract integration. Only 2 contracts had payment_mode_id set, and the
|
|
# migration to the new payment.method.line model is not supported.
|
|
#
|
|
# MUST run BEFORE the bank-payment renaming and BEFORE OpenUpgrade's
|
|
# button_upgrade() which would otherwise crash on the missing dependency.
|
|
#
|
|
# We DELETE the module entirely (like the bank-payment merged_modules pattern)
|
|
# rather than marking it 'to remove', because Odoo's "Transient module states
|
|
# were reset" in load_modules() converts 'to remove' -> 'installed', causing
|
|
# button_upgrade() to re-parse the missing account_payment_partner dependency
|
|
# and abort the registry load. Deleting the row + ir_model_data + dependencies
|
|
# ensures OpenUpgrade's update_list() rediscovers the physical addon as a fresh
|
|
# 'uninstalled' module that button_upgrade() never touches.
|
|
# ============================================================================
|
|
contract_payment_mode_sql=$(cat <<'EOF'
|
|
DO $$
|
|
DECLARE
|
|
mod_id INTEGER;
|
|
BEGIN
|
|
SELECT id INTO mod_id FROM ir_module_module WHERE name = 'contract_payment_mode';
|
|
IF mod_id IS NOT NULL THEN
|
|
DELETE FROM ir_module_module_dependency WHERE module_id = mod_id;
|
|
DELETE FROM ir_model_data WHERE module = 'contract_payment_mode';
|
|
DELETE FROM ir_module_module WHERE id = mod_id;
|
|
|
|
-- Rename the module's own external ID (base.module_contract_payment_mode)
|
|
-- so update_list() can rediscover the physical contract_payment_mode addon
|
|
-- (which still exists in v18 addons path) without conflicting on
|
|
-- (base, module_contract_payment_mode). The orphaned xmlid pointed to
|
|
-- the deleted ir.module.module row and has no other references.
|
|
UPDATE ir_model_data
|
|
SET name = 'module_contract_payment_mode_removed'
|
|
WHERE module = 'base' AND name = 'module_contract_payment_mode';
|
|
|
|
RAISE NOTICE 'Removed contract_payment_mode module (depends on obsolete account_payment_partner)';
|
|
ELSE
|
|
RAISE NOTICE 'contract_payment_mode not found, skipping';
|
|
END IF;
|
|
END $$;
|
|
EOF
|
|
)
|
|
echo "Removing contract_payment_mode module..."
|
|
query_postgres_container "$contract_payment_mode_sql" ou18 || exit 1
|
|
|
|
# ============================================================================
|
|
# BANK-PAYMENT -> BANK-PAYMENT-ALTERNATIVE MODULE RENAMING
|
|
# Migration from OCA/bank-payment to OCA/bank-payment-alternative
|
|
# Source PR: https://github.com/OCA/bank-payment-alternative/pull/42
|
|
#
|
|
# 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
|
|
renamed_modules TEXT[][] := ARRAY[
|
|
['account_payment_mode', 'account_payment_base_oca'],
|
|
['account_banking_pain_base', 'account_payment_sepa_base'],
|
|
['account_banking_sepa_credit_transfer', 'account_payment_sepa_credit_transfer'],
|
|
['account_payment_order', 'account_payment_batch_oca']
|
|
];
|
|
merged_modules TEXT[][] := ARRAY[
|
|
['account_payment_partner', 'account_payment_base_oca']
|
|
];
|
|
old_name TEXT;
|
|
new_name TEXT;
|
|
old_module_id INTEGER;
|
|
deleted_count INTEGER;
|
|
BEGIN
|
|
FOR i IN 1..array_length(renamed_modules, 1) LOOP
|
|
old_name := renamed_modules[i][1];
|
|
new_name := renamed_modules[i][2];
|
|
|
|
SELECT id INTO old_module_id FROM ir_module_module WHERE name = old_name;
|
|
IF old_module_id IS NOT NULL THEN
|
|
RAISE NOTICE 'Renaming module: % -> %', old_name, new_name;
|
|
UPDATE ir_module_module SET name = new_name WHERE name = old_name;
|
|
UPDATE ir_model_data SET module = new_name WHERE module = old_name;
|
|
UPDATE ir_module_module_dependency SET name = new_name WHERE name = old_name;
|
|
END IF;
|
|
END LOOP;
|
|
|
|
FOR i IN 1..array_length(merged_modules, 1) LOOP
|
|
old_name := merged_modules[i][1];
|
|
new_name := merged_modules[i][2];
|
|
|
|
SELECT id INTO old_module_id FROM ir_module_module WHERE name = old_name;
|
|
IF old_module_id IS NOT NULL THEN
|
|
RAISE NOTICE 'Merging module: % -> %', old_name, new_name;
|
|
|
|
DELETE FROM ir_model_data
|
|
WHERE module = old_name
|
|
AND name IN (SELECT name FROM ir_model_data WHERE module = new_name);
|
|
GET DIAGNOSTICS deleted_count = ROW_COUNT;
|
|
IF deleted_count > 0 THEN
|
|
RAISE NOTICE ' Deleted % duplicate ir_model_data records', deleted_count;
|
|
END IF;
|
|
|
|
UPDATE ir_model_data SET module = new_name WHERE module = old_name;
|
|
UPDATE ir_module_module_dependency SET name = new_name WHERE name = old_name;
|
|
UPDATE ir_module_module SET state = 'uninstalled' WHERE name = old_name;
|
|
DELETE FROM ir_module_module WHERE name = old_name;
|
|
END IF;
|
|
END LOOP;
|
|
END $$;
|
|
EOF
|
|
)
|
|
echo "Executing bank-payment module renaming..."
|
|
query_postgres_container "$BANK_PAYMENT_RENAME_SQL" ou18 || exit 1
|
|
|
|
BANK_PAYMENT_PRE_SQL=$(cat <<'EOF'
|
|
UPDATE ir_model_data
|
|
SET noupdate = false
|
|
WHERE module = 'account_payment_base_oca'
|
|
AND name = 'view_account_invoice_report_search';
|
|
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
|
|
|
|
# ============================================================================
|
|
# ACCOUNT_FACTORING -> ACCOUNT_FACTORING_OCA MODULE RENAMING
|
|
#
|
|
# account_factoring (depends on account_payment_partner + account_payment_mode)
|
|
# is replaced by account_factoring_oca (depends on account_payment_base_oca
|
|
# + account_payment_base_oca_sale) in v18.
|
|
#
|
|
# Both modules have rigorously identical stored fields:
|
|
# - account_journal: is_factor, factor_fee, factor_holdback_percent,
|
|
# factor_partner_id, factor_fee_account_id, factor_holdback_account_id,
|
|
# factor_limit_holdback_account_id, factor_tax_id, factor_validation
|
|
# - account_move: factor_transfer_id, factor_payment_id,
|
|
# payment_state_with_factor
|
|
# - res_partner: factor_credit_limit
|
|
#
|
|
# Renaming (not uninstalling) preserves the 4910 invoice factor statuses,
|
|
# 311 partner credit limits, and journal factor config. OpenUpgrade will
|
|
# treat account_factoring_oca as already installed and adopt the existing
|
|
# columns via ORM _auto_init.
|
|
#
|
|
# MUST run AFTER the bank-payment renaming block above, which creates
|
|
# account_payment_base_oca in the DB.
|
|
# ============================================================================
|
|
ACCOUNT_FACTORING_RENAME_SQL=$(cat <<'EOF'
|
|
DO $$
|
|
DECLARE
|
|
factor_module_id INTEGER;
|
|
BEGIN
|
|
SELECT id INTO factor_module_id FROM ir_module_module WHERE name = 'account_factoring';
|
|
IF factor_module_id IS NOT NULL THEN
|
|
-- Rename the module itself
|
|
UPDATE ir_module_module SET name = 'account_factoring_oca' WHERE name = 'account_factoring';
|
|
UPDATE ir_model_data SET module = 'account_factoring_oca' WHERE module = 'account_factoring';
|
|
|
|
-- Rename the module's own external ID (base.module_account_factoring)
|
|
-- so OpenUpgrade can rediscover the physical account_factoring addon dir
|
|
-- (which still exists in v18 addons path) without conflicting on
|
|
-- (base, module_account_factoring) — that xmlid now points to the
|
|
-- renamed module under its new name.
|
|
UPDATE ir_model_data
|
|
SET name = 'module_account_factoring_oca'
|
|
WHERE module = 'base' AND name = 'module_account_factoring';
|
|
|
|
-- Redirect dependencies pointing TO the old name
|
|
UPDATE ir_module_module_dependency SET name = 'account_factoring_oca' WHERE name = 'account_factoring';
|
|
|
|
-- Replace obsolete dependencies (account_payment_partner + account_payment_mode
|
|
-- no longer exist in v18 addons) with the new OCA equivalents
|
|
DELETE FROM ir_module_module_dependency
|
|
WHERE module_id = factor_module_id
|
|
AND name IN ('account_payment_partner', 'account_payment_mode');
|
|
|
|
INSERT INTO ir_module_module_dependency (name, module_id)
|
|
SELECT 'account_payment_base_oca', factor_module_id
|
|
WHERE NOT EXISTS (
|
|
SELECT 1 FROM ir_module_module_dependency
|
|
WHERE module_id = factor_module_id AND name = 'account_payment_base_oca'
|
|
);
|
|
|
|
INSERT INTO ir_module_module_dependency (name, module_id)
|
|
SELECT 'account_payment_base_oca_sale', factor_module_id
|
|
WHERE NOT EXISTS (
|
|
SELECT 1 FROM ir_module_module_dependency
|
|
WHERE module_id = factor_module_id AND name = 'account_payment_base_oca_sale'
|
|
);
|
|
|
|
RAISE NOTICE 'Renamed account_factoring -> account_factoring_oca (data preserved)';
|
|
ELSE
|
|
RAISE NOTICE 'account_factoring not found, skipping rename';
|
|
END IF;
|
|
END $$;
|
|
EOF
|
|
)
|
|
echo "Executing account_factoring -> account_factoring_oca renaming..."
|
|
query_postgres_container "$ACCOUNT_FACTORING_RENAME_SQL" ou18 || exit 1
|
|
|
|
# ============================================================================
|
|
# 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
|
|
|
|
# Execute SQL pre-migration commands
|
|
PRE_MIGRATE_SQL=$(cat <<'EOF'
|
|
UPDATE account_analytic_plan SET default_applicability=NULL WHERE default_applicability='optional';
|
|
DELETE FROM ir_ui_view WHERE model = 'res.config.settings';
|
|
|
|
EOF
|
|
)
|
|
echo "SQL command = $PRE_MIGRATE_SQL"
|
|
query_postgres_container "$PRE_MIGRATE_SQL" ou18 || exit 1
|
|
|
|
# NOTE: Missing generic PCG account xml-ids expected by l10n_fr_account (e.g.
|
|
# account.<company>_pcg_607_account / _pcg_707_account) are recreated generically
|
|
# by the ORM post-migration script
|
|
# versions/18.0/scripts/l10n_fr_account/18.0.2.2/post-migration-0k-fix-property-account-xmlids.py
|
|
# which runs at stage "post" of l10n_fr_account, before the native "end" script
|
|
# end-migrate_update_taxes.py that would otherwise crash on the missing xml-id.
|
|
|
|
# Copy filestores
|
|
copy_filestore ou17 ou17 ou18 ou18 || exit 1
|
|
|
|
echo "Ready for migration to 18.0!"
|