Skip to content
Snippets Groups Projects
post-migrate.py 5.86 KiB
Newer Older
##############################################################################
#
#    Accounting Periods, for Odoo
#    Copyright © 2024 XCG Consulting <https://xcg-consulting.fr/>
#
#    This program is free software: you can redistribute it and/or modify
#    it under the terms of the GNU Affero General Public License as
#    published by the Free Software Foundation, either version 3 of the
#    License, or (at your option) any later version.
#
#    This program is distributed in the hope that it will be useful,
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#    GNU Affero General Public License for more details.
#
#    You should have received a copy of the GNU Affero General Public License
#    along with this program.  If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################
import json

from odoo.tools.sql import SQL, column_exists, create_column, set_not_null, table_exists


def migrate(cr, version):
    # Migrate table data from <15.0
    if table_exists(cr, "account_fiscalyear"):
        dict_migrated_fiscal_years = {}
        # Migrate fiscal years (account.fiscalyear to account.fiscal_year)
        cr.execute(
            SQL(
                "SELECT id, name, company_id, date_start, date_stop, create_date, "
                "create_uid, write_date, write_uid from account_fiscalyear"
            )
        )
        fiscalyears = {}
        for (
            id,
            name,
            company_id,
            date_start,
            date_stop,
            create_date,
            create_uid,
            write_date,
            write_uid,
        ) in cr.fetchall():
            fiscalyears[id] = SQL(
                "INSERT INTO account_fiscal_year (name, company_id, date_from, date_to,"
                "create_date, create_uid, write_date, write_uid) VALUES "
                "(%s, %s, %s, %s, %s, %s, %s, %s) RETURNING id",
                name,
                company_id,
                date_start,
                date_stop,
                create_date,
                create_uid,
                write_date,
                write_uid,
            )
        for id, query in fiscalyears.items():
            cr.execute(query)
            dict_migrated_fiscal_years[id] = cr.fetchall()[0][0]
        # Migrate analytic_id in fiscal year if it exists
        if column_exists(cr, "account_fiscalyear", "analytic_id"):
            # create the column to avoid losing the value when dropping data
            if not column_exists(cr, "account_fiscal_year", "analytic_id"):
                create_column(cr, "account_fiscal_year", "analytic_id", "int4")
            cr.execute(SQL("SELECT id, analytic_id FROM account_fiscalyear"))
            update_data = [row for row in cr.fetchall()]
            for id, analytic_id in update_data:
                cr.execute(
                    SQL(
                        "UPDATE account_fiscal_year SET analytic_id = %s WHERE id = %s",
                        analytic_id,
                        dict_migrated_fiscal_years[id],
                    )
                )
        # clean up the now useless table
        cr.execute(SQL("DROP TABLE %s;", SQL.identifier("account_fiscalyear")))

        # search the date range type to use for periods (from this module data)
        cr.execute(
            SQL(
                "SELECT res_id from ir_model_data WHERE name='period_type' AND "
                "module='account_period'"
            )
        )
        date_range_type_id = cr.fetchall()[0][0]
        # search for installed languages
        cr.execute(SQL("SELECT code from res_lang WHERE active"))
        languages_code = [row[0] for row in cr.fetchall()]
        cr.execute(
            SQL(
                "SELECT id, company_id, code, name, date_start, date_stop, create_date"
                ", create_uid, write_date, write_uid, fiscalyear_id FROM account_period"
                " WHERE date_range_id is null;"
            )
        )
        creation = {}
        for row in cr.fetchall():
            jsonb_name = json.dumps({lang: row[2] for lang in languages_code})
            jsonb_type_name = json.dumps({})
            creation[row[0]] = (
                SQL(
                    "INSERT INTO date_range (company_id, type_id, date_start, date_end,"
                    " create_date, create_uid, write_date, write_uid, name, type_name, "
                    "active) VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, TRUE) "
                    "RETURNING id",
                    row[1],
                    date_range_type_id,
                    row[4],
                    row[5],
                    row[6],
                    row[7],
                    row[8],
                    row[9],
                    jsonb_name,
                    jsonb_type_name,
                ),
                row[10],
            )

        update_query = (
            "UPDATE account_period SET date_range_id = %s, fiscal_year_id = %s "
            "WHERE id = %s"
        )
        for period_id, (query, fiscalyear_id) in creation.items():
            cr.execute(query)
            created_date_range_id = cr.fetchall()[0][0]
            cr.execute(
                SQL(
                    update_query,
                    created_date_range_id,
                    dict_migrated_fiscal_years[fiscalyear_id],
                    period_id,
                )
            )
        for column in ("date_range_id", "fiscal_year_id"):
            set_not_null(cr, "account_period", column)
        # clean up the period table
        for column in (
            "fiscalyear_id",
            "date_start",
            "date_stop",
            "company_id",
            "name",
            "code",
        ):
            cr.execute(
                SQL("ALTER TABLE account_period DROP COLUMN %s", SQL.identifier(column))
            )