bank-payment/account_payment_order/migrations/14.0.2.0.0/post-migration.py
2023-05-19 10:19:51 +02:00

179 lines
6.6 KiB
Python

# Copyright 2022 Tecnativa - Pedro M. Baeza
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
import logging
from openupgradelib import openupgrade
_logger = logging.getLogger(__name__)
def _insert_account_payments(env):
openupgrade.logged_query(
env.cr, "ALTER TABLE account_payment ADD old_bank_payment_line_id INT4"
)
# Create an account.payment record for each bank.payment.line
openupgrade.logged_query(
env.cr,
"""
INSERT INTO account_payment (
create_date, create_uid, write_date, write_uid, old_bank_payment_line_name,
payment_order_id, partner_id, amount, currency_id,
payment_method_id, old_bank_payment_line_id, payment_type,
partner_type,
destination_account_id, payment_reference, move_id
)
SELECT
bpl.create_date, bpl.create_uid, bpl.write_date, bpl.write_uid, bpl.name,
bpl.order_id, bpl.partner_id, bpl.amount_currency, 1,
apm.payment_method_id, bpl.id, apo.payment_type,
CASE WHEN apo.payment_type = 'inbound' THEN 'customer' ELSE 'supplier' END,
aml.account_id, bpl.communication, aml.move_id
FROM bank_payment_line bpl
JOIN account_payment_order apo ON apo.id = bpl.order_id
JOIN account_payment_mode apm ON apm.id = apo.payment_mode_id
LEFT JOIN account_move_line aml ON aml.bank_payment_line_id = bpl.id
WHERE apo.state not in ('uploaded', 'done') or aml.move_id is not null
""",
)
# As the information is asymmetric: N payment lines > 1 bank payment line, but there
# are some related non-stored fields to payment lines, we need a second query to
# update some of the fields
openupgrade.logged_query(
env.cr,
"""
UPDATE account_payment ap
SET currency_id = apl.currency_id,
partner_bank_id = apl.partner_bank_id
FROM account_payment_line apl
WHERE apl.bank_line_id = ap.old_bank_payment_line_id
""",
)
def _create_hooks(env):
"""Avoid errors due to locked dates, overriding involved methods."""
def _check_fiscalyear_lock_date(self):
return True
def _check_tax_lock_date(self):
return True
def _check_reconciliation(self):
return True
# create hooks
_check_fiscalyear_lock_date._original_method = type(
env["account.move"]
)._check_fiscalyear_lock_date
type(env["account.move"])._check_fiscalyear_lock_date = _check_fiscalyear_lock_date
_check_tax_lock_date._original_method = type(
env["account.move.line"]
)._check_tax_lock_date
type(env["account.move.line"])._check_tax_lock_date = _check_tax_lock_date
_check_reconciliation._original_method = type(
env["account.move.line"]
)._check_reconciliation
type(env["account.move.line"])._check_reconciliation = _check_reconciliation
def create_moves_from_orphan_account_payments(env):
"""Recreate missing journal entries on the newly created account payments."""
env.cr.execute(
"""
SELECT ap.id, MIN(apl.date), MIN(bpl.company_id), MIN(apo.name),
MIN(apo.journal_id), MIN(apl.currency_id), MIN(apo.state), MIN(apo.id)
FROM bank_payment_line bpl
JOIN account_payment ap ON ap.old_bank_payment_line_id = bpl.id
JOIN account_payment_order apo ON apo.id = bpl.order_id
JOIN account_payment_line apl ON apl.bank_line_id = bpl.id
LEFT JOIN account_move_line aml ON aml.bank_payment_line_id = bpl.id
WHERE aml.move_id IS NULL
GROUP BY ap.id
"""
)
deprecated_acc_by_company = {}
for row in env.cr.fetchall():
payment = (
env["account.payment"]
.with_context(
check_move_validity=False,
tracking_disable=True,
)
.browse(row[0])
)
move = env["account.move"].create(
{
"name": "/",
"date": row[1],
"payment_id": payment.id,
"move_type": "entry",
"company_id": row[2],
"ref": row[3],
"journal_id": row[4],
"currency_id": row[5],
"state": "draft" if row[6] in {"open", "generated"} else "cancel",
"payment_order_id": row[7],
}
)
payment.move_id = move
# Avoid deprecated account warning
if payment.company_id not in deprecated_acc_by_company:
deprecated_accounts = env["account.account"].search(
[("deprecated", "=", True), ("company_id", "=", payment.company_id.id)]
)
deprecated_acc_by_company[payment.company_id] = deprecated_accounts
deprecated_accounts.deprecated = False
try:
payment._synchronize_to_moves(["date"]) # no more changed fields needed
except Exception as e:
_logger.error("Failed for payment with id %s: %s", payment.id, e)
raise
# Restore deprecated accounts
for deprecated_accounts in deprecated_acc_by_company.values():
deprecated_accounts.deprecated = True
def _delete_hooks(env):
"""Restore the locking dates original methods."""
type(env["account.move"])._check_fiscalyear_lock_date = type(
env["account.move"]
)._check_fiscalyear_lock_date._original_method
type(env["account.move.line"])._check_tax_lock_date = type(
env["account.move.line"]
)._check_tax_lock_date._original_method
type(env["account.move.line"])._check_reconciliation = type(
env["account.move.line"]
)._check_reconciliation._original_method
def _insert_payment_line_payment_link(env):
openupgrade.logged_query(
env.cr,
"""
INSERT INTO account_payment_account_payment_line_rel
(account_payment_id, account_payment_line_id)
SELECT ap.id, apl.id
FROM account_payment_line apl
JOIN account_payment ap ON ap.old_bank_payment_line_id = apl.bank_line_id
""",
)
@openupgrade.migrate()
def migrate(env, version):
openupgrade.logged_query(
env.cr, "ALTER TABLE account_payment ALTER move_id DROP NOT NULL"
)
_insert_account_payments(env)
_create_hooks(env)
create_moves_from_orphan_account_payments(env)
openupgrade.logged_query(
env.cr, "ALTER TABLE account_payment ALTER move_id SET NOT NULL"
)
_delete_hooks(env)
_insert_payment_line_payment_link(env)
openupgrade.delete_records_safely_by_xml_id(
env, ["account_payment_order.bank_payment_line_company_rule"]
)