Esempio n. 1
0
def migrate(env, version):
    openupgrade.rename_xmlids(env.cr, _xmlid_renames)
    openupgrade.rename_fields(env, _field_renames)
    openupgrade.add_fields(env, _field_adds)
    # Fix image of fleet.vehicle.model.brand after renaming column to image_128
    openupgrade.logged_query(
        env.cr,
        """
        UPDATE ir_attachment
        SET res_field = 'image_128'
        WHERE res_field = 'image_medium' and res_model = 'fleet.vehicle.model.brand'
        """,
    )
Esempio n. 2
0
def set_calendar_event_res_model(env):
    """This pre-creates before ORM related computation the field `res_model`,
    for avoiding an error when writing back the value on virtual records
    created by recurring events. No need of writing any possible value, as
    this is a new feature not available in v10.
    """
    openupgrade.add_fields(
        env,
        [
            ('res_model', 'calendar.event', 'calendar_event', 'char', False,
             'calendar'),
        ],
    )
Esempio n. 3
0
def migrate(env, version):
    openupgrade.rename_tables(env.cr, _table_renames)
    openupgrade.rename_fields(env, _field_renames)
    openupgrade.rename_columns(env.cr, _column_renames)
    openupgrade.copy_columns(env.cr, _column_copies)
    openupgrade.rename_xmlids(env.cr, _xmlid_renames)
    openupgrade.update_module_moved_fields(
        env.cr, "sale.order", ["campaign_id", "medium_id", "source_id"], "sale_crm", "sale"
    )
    openupgrade.add_fields(
        env, [("company_id", "utm.campaign", False, "many2one", False, "sale")],
    )
    nullify_invoiced_target_when_not_used(env)
Esempio n. 4
0
def migrate(env, version):
    openupgrade.rename_columns(
        env.cr, {'pos_config': [('iface_tax_included', None)]})
    openupgrade.add_fields(env, [
        ('customer_facing_display_html', 'pos.config', 'pos_config', 'html',
         False, 'point_of_sale'),
    ])
    openupgrade.set_xml_ids_noupdate_value(
        env, 'point_of_sale', [
            'barcode_rule_cashier',
            'barcode_rule_client',
            'barcode_rule_discount',
            'barcode_rule_price_two_dec',
        ], True)
Esempio n. 5
0
def migrate(env, version):
    delete_quants_for_consumable(env)
    remove_company_for_quants_in_vendor_customer(env)
    fix_act_window(env)
    openupgrade.update_module_moved_fields(
        env.cr,
        'stock.move',
        ['has_tracking'],
        'mrp',
        'stock',
    )
    openupgrade.update_module_moved_fields(
        env.cr,
        'stock.move',
        ['quantity_done'],
        'mrp',
        'stock',
    )
    openupgrade.rename_fields(env, [
        ('stock.quant', 'stock_quant', 'qty', 'quantity'),
    ])
    openupgrade.copy_columns(
        env.cr,
        {
            'stock_picking': [
                ('state', None, None),
            ],
        },
    )
    openupgrade.map_values(
        env.cr,
        openupgrade.get_legacy_name('state'),
        'state',
        [('partially_available', 'assigned')],
        table='stock_picking',
    )
    openupgrade.add_fields(
        env,
        [
            ('reference', 'stock.move', 'stock_move', 'char', False, 'stock'),
            ('scheduled_date', 'stock.picking', 'stock_picking', 'date', False,
             'stock'),
        ],
    )
    openupgrade.set_xml_ids_noupdate_value(env, 'stock', [
        'barcode_rule_location',
        'barcode_rule_lot',
        'barcode_rule_package',
        'barcode_rule_weight_three_dec',
    ], True)
Esempio n. 6
0
def move_lunch_order_line_to_lunch_order(env):
    openupgrade.add_fields(env, _field_adds)
    openupgrade.logged_query(
        env.cr, """
        UPDATE lunch_order lo
        SET
            category_id = lol.category_id,
            product_id = lol.product_id,
            supplier_id = lol.supplier,
            price = lol.price,
            note = lol.note,
            state = lol.state
        FROM lunch_order_line lol
        WHERE lo.id = lol.order_id
        """)
def _move_history_state_field(env):
    field_spec = [(
        "product_state_id",
        "product.state.history",
        "product_state_history",
        "many2one",
        "integer",
        "product_state_history",
    )]
    openupgrade.add_fields(env, field_spec)
    query = """
        UPDATE product_state_history psh
            SET product_state_id =
            (SELECT id FROM product_state WHERE code = psh.product_state)
    """
    env.cr.execute(query)
Esempio n. 8
0
def precompute_pol_product_uom_qty(env):
    """when computing product_uom_qty in _compute_product_uom_qty(),
    we need to avoid the UserError in _compute_quantity()"""
    openupgrade.add_fields(
        env,
        [
            ('product_uom_qty', 'purchase.order.line', 'purchase_order_line',
             'float', 'double precision', 'purchase'),
        ],
    )
    # On first place, assign the same value when UoM has not changed
    openupgrade.logged_query(
        env.cr,
        """
        UPDATE purchase_order_line
        SET product_uom_qty = product_qty""",
    )
    # Then, only auto-switch UoM of lines when they are in draft
    openupgrade.logged_query(
        env.cr,
        """
        UPDATE purchase_order_line upd_pol
        SET product_uom = pt.uom_id
        FROM purchase_order_line pol
        JOIN product_product pp ON pol.product_id = pp.id
        JOIN product_template pt ON pp.product_tmpl_id = pt.id
        JOIN uom_uom uu ON pol.product_uom = uu.id
        JOIN uom_uom uu2 ON pt.uom_id = uu2.id
        WHERE uu.category_id != uu2.category_id
            AND pol.state = 'draft'
            AND upd_pol.id = pol.id""",
    )
    # Lastly, perform conversion when different UoMs, ignoring incompatible
    # UoM categories
    openupgrade.logged_query(
        env.cr,
        """
        UPDATE purchase_order_line upd_pol
        SET product_uom_qty = pol.product_qty / uu.factor * uu2.factor
        FROM purchase_order_line pol
        JOIN product_product pp ON pol.product_id = pp.id
        JOIN product_template pt ON pp.product_tmpl_id = pt.id
        JOIN uom_uom uu on uu.id = pol.product_uom
        JOIN uom_uom uu2 on uu2.id = pt.uom_id
        WHERE upd_pol.id = pol.id
            AND pol.product_uom != pt.uom_id""",
    )
def update_procurement_field_from_sale(env):
    """Connecting new sale_id field of procurement_group with respective
    sale orders (considering procurement_group_id of sale order).
    """
    if not openupgrade.column_exists(env.cr, 'procurement_group', 'sale_id'):
        openupgrade.add_fields(env, [
            ('sale_id', 'procurement.group', 'procurement_group', 'many2one',
             False, 'sale_stock'),
        ])
    openupgrade.logged_query(
        env.cr,
        """
        UPDATE procurement_group pg
        SET sale_id = so.id
        FROM sale_order so
        WHERE so.procurement_group_id = pg.id""",
    )
Esempio n. 10
0
def migrate(env, version):
    openupgrade.add_fields(
        env,
        [("amount_sp", "account.move", False, "float", False,
          "l10n_it_split_payment")],
    )
    openupgrade.logged_query(
        env.cr,
        """
        update account_move
        set
            amount_sp = inv.amount_sp
        from account_invoice inv
        where
            account_move.id = inv.move_id;
    """,
    )
Esempio n. 11
0
def set_calendar_event_res_model(env):
    """This pre-creates before ORM related computation the field `res_model`,
    for avoiding an error when writing back the value on virtual records
    created by recurring events. No need of writing any possible value, as
    this is a new feature not available in v10.

    If the OCA module `mail_activity_calendar` was installed in
    previous version this field would already exist, thus no need to
    pre-create it.
    """
    if not openupgrade.column_exists(env.cr, 'calendar_event', 'res_model'):
        openupgrade.add_fields(
            env, [
                ('res_model', 'calendar.event', 'calendar_event', 'char',
                 False, 'calendar'),
            ],
        )
Esempio n. 12
0
def migrate(env, version):
    copy_global_rules(env)
    delete_quants_for_consumable(env)
    drop_slow_constraint(env)
    fix_act_window(env)
    openupgrade.update_module_moved_fields(
        env.cr,
        'stock.move',
        ['has_tracking'],
        'mrp',
        'stock',
    )
    openupgrade.update_module_moved_fields(
        env.cr,
        'stock.move',
        ['quantity_done'],
        'mrp',
        'stock',
    )
    openupgrade.rename_fields(env, [
        ('stock.quant', 'stock_quant', 'qty', 'quantity'),
    ])
    openupgrade.copy_columns(
        env.cr,
        {
            'stock_picking': [
                ('state', None, None),
            ],
        },
    )
    openupgrade.map_values(
        env.cr,
        openupgrade.get_legacy_name('state'),
        'state',
        [('partially_available', 'assigned')],
        table='stock_picking',
    )
    openupgrade.add_fields(
        env,
        [
            ('reference', 'stock.move', 'stock_move', 'char', False, 'stock'),
            ('scheduled_date', 'stock.picking', 'stock_picking', 'date', False,
             'stock'),
        ],
    )
Esempio n. 13
0
def move_mailing_campaign_to_utm_campaign(env):
    openupgrade.add_fields(env, [
        ("user_id", "utm.campaign", "utm_campaign", "integer", False, "utm"),
        ("stage_id", "utm.campaign", "utm_campaign", "integer", False, "utm"),
        ("color", "utm.campaign", "utm_campaign", "integer", False, "utm"),
    ])
    openupgrade.logged_query(
        env.cr, """
        UPDATE utm_campaign uc
        SET user_id = mmc.user_id, stage_id = mmc.stage_id, color = mmc.color
        FROM mail_mass_mailing_campaign mmc
        WHERE mmc.campaign_id = uc.id""")
    openupgrade.logged_query(
        env.cr, """
        UPDATE utm_tag_rel utr
        SET campaign_id = mmc.campaign_id
        FROM mail_mass_mailing_campaign mmc
        WHERE mmc.id = utr.campaign_id""")
Esempio n. 14
0
def update_stock_move_field_from_procurement_order(env):
    """Filling the values of new sale_order_id field of stock_move
    with respective values of old procurement_order
    """
    if not openupgrade.column_exists(env.cr, 'stock_move', 'sale_line_id'):
        openupgrade.add_fields(env, [
            ('sale_line_id', 'stock.move', 'stock_move', 'many2one', False,
             'sale_stock'),
        ])
    openupgrade.logged_query(
        env.cr,
        """
        UPDATE stock_move sm
        SET sale_line_id = po.sale_line_id
        FROM procurement_order po
        WHERE sm.procurement_id = po.id
            AND po.sale_line_id IS NOT NULL""",
    )
Esempio n. 15
0
def migrate(env, version):
    openupgrade.rename_columns(env.cr, _column_renames)
    openupgrade.copy_columns(env.cr, _column_copies)
    openupgrade.rename_fields(env, _field_renames)
    openupgrade.logged_query(
        env.cr, "ALTER TABLE slide_slide ADD COLUMN category_id int4")
    openupgrade.rename_tables(
        env.cr, [("rel_channel_groups", "res_groups_slide_channel_rel")])
    openupgrade.set_xml_ids_noupdate_value(
        env,
        "website_slides",
        [
            "rule_slide_channel_global",
            "rule_slide_slide_global",
        ],
        False,
    )
    openupgrade.add_fields(env, [("user_id", "slide.channel", "slide_channel",
                                  "many2one", False, "website_slides")])
Esempio n. 16
0
def fill_cron_action_server_pre(env):
    """Prefill the column with a fixed value for avoiding the not null error,
    but wait until post for filling correctly the field and related record.
    """
    openupgrade.add_fields(
        env,
        [
            ('ir_actions_server_id', 'ir.cron', 'ir_cron', 'many2one', False,
             'base'),
        ],
    )
    env.cr.execute("SELECT MIN(id) FROM ir_act_server")
    row = env.cr.fetchone()
    server_action_id = row and row[0] or 1
    # Write in the ir.cron record the parent ir.actions.server ID
    env.cr.execute(
        "UPDATE ir_cron SET ir_actions_server_id = %s",
        (server_action_id, ),
    )
Esempio n. 17
0
def insert_missing_product_template_attribute_value(env):
    """Given this situation in v12:

    - Template T with attribute A and values A1, and A2.
    - Generated variants V1 and V2 for attribute values A1 and A2 respectively.
    - Generated product.template.attribute.value for T/A1 and T/A2.
    - V2 is used in a quotation.
    - Remove A2 attribute value from the template. Result:
      * V2 is archived
      * product.template.attribute.value T/A2 is removed.

    On v13, the record is not removed, but marked with ptav_active = False. That's
    because there's a field in product.product called combination_indices that
    stores the ID of such line and serves for quick search/indexing on it.

    From the current data status we find on v12 for these cases, we need to
    reintroduce missing product.template.attribute.value records with
    ptav_active = False for not having later unique constraint errors and
    proper DB integrity.

    This is also the second step for amending the situation described in
    ``insert_missing_product_template_attribute_line`` method.
    """
    openupgrade.add_fields(env, [(
        "ptav_active", "product.template.attribute.value",
        "product_template_attribute_value", "boolean", False, "product", True,
    )])
    openupgrade.logged_query(
        env.cr,
        """
        INSERT INTO product_template_attribute_value
            (ptav_active, product_attribute_value_id, product_tmpl_id)
        SELECT
            False, pavppr.product_attribute_value_id, pp.product_tmpl_id
        FROM product_attribute_value_product_product_rel pavppr
        JOIN product_product pp ON pp.id = pavppr.product_product_id
        LEFT JOIN product_template_attribute_value ptav
            ON ptav.product_attribute_value_id = pavppr.product_attribute_value_id
            AND ptav.product_tmpl_id = pp.product_tmpl_id
        WHERE ptav.id IS NULL
        GROUP BY pavppr.product_attribute_value_id, pp.product_tmpl_id""",
    )
Esempio n. 18
0
def migrate(env, version):
    openupgrade.copy_columns(env.cr, column_copies)
    # account_tax_cash_basis was merged with account, so there is no module
    # entry anymore to check if it was installed. Check one of its columns
    # instead.
    if openupgrade.column_exists(env.cr, 'account_tax', 'use_cash_basis'):
        openupgrade.rename_columns(
            env.cr, {'account_tax': [('use_cash_basis', None)]})
    openupgrade.delete_record_translations(env.cr, 'account', [
        'mail_template_data_notification_email_account_invoice',
        'email_template_edi_invoice'
    ])
    openupgrade.rename_xmlids(env.cr, _portal_xmlid_renames)
    openupgrade.rename_xmlids(env.cr, _portal_sale_xmlid_renames)
    openupgrade.add_fields(
        env, [
            ('price_total', 'account.invoice.line', 'account_invoice_line',
             'monetary', False, 'account'),
            ('tax_base_amount', 'account.move.line', 'account_move_line',
             'monetary', False, 'account'),
        ]
    )
Esempio n. 19
0
def migrate(env, version):
    cr = env.cr
    if not openupgrade.column_exists(cr, 'res_company', 'nomenclature_id'):
        openupgrade.add_fields(
            env, [
                ('nomenclature_id', 'res.company', 'res_company', 'many2one',
                 'int4', 'barcodes'),
            ],
        )

        # done here instead of post-migration to avoid the post-init-hook
        if openupgrade.table_exists(cr, 'stock_picking_type'):
            cr.execute(
                """
                UPDATE res_company rc
                SET nomenclature_id = spt.barcode_nomenclature_id
                FROM stock_picking_type spt
                LEFT JOIN stock_warehouse sw ON spt.warehouse_id = sw.id
                WHERE sw.company_id = rc.id
                    AND spt.barcode_nomenclature_id IS NOT NULL
                """
            )
Esempio n. 20
0
def migrate(env, version):
    cr = env.cr
    if openupgrade.table_exists(cr, "muk_dms_file"):
        openupgrade.rename_models(cr, _model_renames)
        for table in _table_renames:
            if openupgrade.table_exists(cr, table[0]):
                openupgrade.rename_tables(cr, [table])
        for field in _field_renames:
            if openupgrade.table_exists(
                    cr, field[1]) and openupgrade.column_exists(
                        cr, field[1], field[2]):
                openupgrade.rename_fields(env, [field])
        if not openupgrade.table_exists(cr, "dms_storage"):
            openupgrade.rename_models(cr,
                                      [("muk_dms.settings", "dms.storage")])
            openupgrade.rename_tables(cr,
                                      [("muk_dms_settings", "dms_storage")])
            openupgrade.rename_fields(env, [("dms.directory", "dms_directory",
                                             "settings", "root_storage_id")])
        openupgrade.add_fields(env, _field_add)
        for key in _config_parameters:
            env["ir.config_parameter"].search([
                ("key", "=", key)
            ]).write({"key": _config_parameters[key]})
Esempio n. 21
0
def insert_missing_product_template_attribute_line(env):
    """Given this situation in v12:

    - Template T with attribute A and values A1, and A2, and attribute B with value B1.
    - Generated variants V1 and V2 for attribute values A1/B1 and A2/B2 respectively.
    - Generated product.template.attribute.line records for T/A and T/B.
    - V2 is used in a quotation.
    - Remove B attribute from the template. Result:
      * V2 is archived
      * product.template.attribute.line T/B is removed.

    On v13, the record is not removed, but marked with active = False.

    From the current data status we find on v12 for these cases, we need to
    reintroduce missing product.template.attribute.line records with
    active = False needed later on next steps for DB integrity.
    """
    openupgrade.add_fields(env, [(
        "active", "product.template.attribute.line",
        "product_template_attribute_line", "boolean", False, "product", True,
    )])
    openupgrade.logged_query(
        env.cr,
        """
        INSERT INTO product_template_attribute_line
            (active, product_tmpl_id, attribute_id)
        SELECT False, pp.product_tmpl_id, pav.attribute_id
        FROM product_attribute_value_product_product_rel pavppr
        JOIN product_product pp ON pp.id = pavppr.product_product_id
        JOIN product_attribute_value pav ON pav.id = pavppr.product_attribute_value_id
        LEFT JOIN product_template_attribute_line ptal
            ON ptal.product_tmpl_id = pp.product_tmpl_id
                AND ptal.attribute_id = pav.attribute_id
        WHERE ptal.id IS NULL
        GROUP BY pav.attribute_id, pp.product_tmpl_id""",
    )
Esempio n. 22
0
def populate_computed_fields(env):
    """Pre-add columns for not computing these related and computed fields
    through ORM, and populate their values after with SQL querys for being
    faster.
    """
    cr = env.cr
    openupgrade.logged_query(
        cr,
        "ALTER TABLE bank_payment_line ADD partner_id int4",
    )
    openupgrade.logged_query(
        cr,
        "ALTER TABLE bank_payment_line ADD state varchar",
    )
    openupgrade.add_fields(env, [
        ('company_currency_id', 'account.payment.order',
         'account_payment_order', 'many2one', False, 'account_payment_order'),
        ('payment_type', 'account.payment.line', 'account_payment_line',
         'selection', False, 'account_payment_order'),
        ('payment_type', 'bank.payment.line', 'bank_payment_line', 'selection',
         False, 'account_payment_order'),
        ('amount_company_currency', 'bank.payment.line', 'bank_payment_line',
         'monetary', False, 'account_payment_order'),
    ])
    openupgrade.logged_query(
        cr,
        """
        UPDATE account_payment_order apo
        SET company_currency_id = rc.currency_id
        FROM res_company rc
        WHERE rc.id = apo.company_id""",
    )
    openupgrade.logged_query(
        cr,
        """
        UPDATE bank_payment_line bpl
        SET partner_id = apl.partner_id
        FROM account_payment_line apl
        WHERE apl.bank_line_id = bpl.id""",
    )
    openupgrade.logged_query(
        cr,
        """
        WITH currency_rate as (%s)
        UPDATE bank_payment_line bpl
        SET amount_company_currency = (
            bpl.amount_currency / COALESCE(cr.rate, 1.0)
        )
        FROM bank_payment_line bpl2
        INNER JOIN account_payment_line apl ON apl.bank_line_id = bpl2.id
        INNER JOIN account_move_line aml ON aml.id = apl.move_line_id
        LEFT JOIN currency_rate cr ON (
            cr.currency_id = apl.currency_id
            AND cr.company_id = bpl2.company_id
            AND cr.date_start <= COALESCE(apl.date, aml.date_maturity)
            AND (cr.date_end is null
                OR cr.date_end > COALESCE(apl.date, aml.date_maturity))
        )
        WHERE bpl2.id = bpl.id
        """,
        (AsIs(env['res.currency']._select_companies_rates()), ),
    )
Esempio n. 23
0
def add_utm_stage_fields(env):
    openupgrade.add_fields(env, [
        ("sequence", "utm.stage", "utm_stage", "integer", False, "utm"),
    ])
Esempio n. 24
0
def add_res_lang_url_code(env):
    """Add field and filled it with same logic as core (iso_code or code)."""
    openupgrade.add_fields(
        env, [("url_code", "res.lang", "res_lang", "char", False, "base")])
    openupgrade.logged_query(
        env.cr, "UPDATE res_lang SET url_code = COALESCE(iso_code, code)")
Esempio n. 25
0
def create_ir_actions_server(env):
    """Fill delegate field action_server_id by creating the related
    ir.actions.server most of the field values will go in ir.actions.server.

    Fill also m2m table for server actions to run.
    """
    openupgrade.add_fields(
        env,
        [
            ('action_server_id', 'base.automation', 'base_automation',
             'many2one', False, 'base_automation'),
        ],
    )
    default_vals = {
        'code': IrActionsServer.DEFAULT_PYTHON_CODE,
        'state': 'multi',
        'type': 'ir.actions.server',
        'usage': 'base_automation',
        'binding_type': 'action',
    }
    env.cr.execute("""
        SELECT ba.id, ba.create_uid, ba.create_date, ba.write_uid,
            ba.write_date, ba.name, ba.sequence, ba.model_id, ba.kind,
            ba.filter_id, ba.filter_pre_id, im.model
        FROM base_automation AS BA,
            ir_model AS im
        WHERE
            im.id = ba.model_id
    """)
    for act in env.cr.dictfetchall():
        vals = default_vals.copy()
        vals.update({
            'create_uid': act['create_uid'],
            'create_date': act['create_date'],
            'write_uid': act['write_uid'],
            'write_date': act['write_date'],
            'name': act['name'],
            'model_id': act['model_id'],
            'model_name': act['model'],
            'sequence': act['sequence'],
        })
        for old_field, new_field in [
            ('filter_id', 'filter_domain'),
            ('filter_pre_id', 'filter_pre_domain'),
        ]:
            if act.get(old_field):
                f = env['ir.filters'].browse(act[old_field])
                vals[new_field] = f.domain
        openupgrade.logged_query(
            env.cr,
            """
            INSERT INTO ir_act_server
              (create_uid, create_date, write_uid, write_date, binding_type,
               code, state, type, usage, name, model_id, model_name, sequence)
            VALUES (
              %(create_uid)s, %(create_date)s, %(write_uid)s, %(write_date)s,
              %(binding_type)s, %(code)s, %(state)s, %(type)s, %(usage)s,
              %(name)s, %(model_id)s, %(model_name)s, %(sequence)s
            )
            RETURNING id""",
            vals,
        )
        srv_act_id = env.cr.fetchone()[0]
        # Transfer server actions to run
        openupgrade.logged_query(
            env.cr,
            """
            INSERT INTO rel_server_actions
                (server_id, action_id)
            SELECT
                %s, ir_act_server_id
            FROM base_action_rule_ir_act_server_rel
            WHERE base_action_rule_id = %s
            """,
            (srv_act_id, act['id']),
        )
        # Write in the base.automation record the parent ir.actions.server ID
        # and possible filters
        set_query = "action_server_id = %s"
        params = [srv_act_id]
        for field in ['filter_domain', 'filter_pre_domain']:
            if vals.get(field):
                set_query += ', %s = %%s' % field
                params.append(vals[field])
        params.append(act['id'])
        query = 'UPDATE base_automation SET %s WHERE id = %%s' % set_query
        openupgrade.logged_query(env.cr, query, tuple(params))
Esempio n. 26
0
def fill_product_pricelist_item_active_default(env):
    """Faster way to fill this new field"""
    openupgrade.add_fields(env, [(
        "active", "product.pricelist.item",
        "product_pricelist_item", "boolean", False, "product", True,
    )])
def migrate_mass_editing(env):
    """ Migrates mass.editing to ir.actions.server """
    # Remove FK (mass_editing_id)
    openupgrade.remove_tables_fks(env.cr, ["mass_editing_line"])
    # Add legacy mass_editing_id column to server_actions
    openupgrade.logged_query(
        env.cr,
        sql.SQL("""
        ALTER TABLE ir_act_server
        ADD COLUMN {} int4
        """).format(
            sql.Identifier(openupgrade.get_legacy_name("mass_editing_id")), ),
    )
    # Optional migration for server_action_domain
    # We create the domain column if it's missing, in case the module hasn't
    # been installed yet. By doing so, we make sure the domain is available
    # if the module is installed after.
    openupgrade.logged_query(
        env.cr,
        """
        ALTER TABLE ir_act_server
        ADD COLUMN IF NOT EXISTS domain varchar
        """,
    )
    # Create ir.actions.server for each mass.editing
    openupgrade.logged_query(
        env.cr,
        sql.SQL("""
        INSERT INTO ir_act_server (
            {},
            name,
            type,
            usage,
            binding_type,
            activity_user_type,
            state,
            model_id,
            model_name,
            domain
        )
        SELECT
            me.id,
            COALESCE(me.action_name, me.name),
            'ir.actions.server',
            'ir_actions_server',
            'action',
            'specific',
            'mass_edit',
            me.model_id,
            mo.model,
            me.domain
        FROM mass_editing me
        LEFT JOIN ir_model mo ON (me.model_id = mo.id)
        """).format(
            sql.Identifier(openupgrade.get_legacy_name("mass_editing_id"))),
    )
    # Migrate mass.editing.line
    openupgrade.add_fields(
        env,
        [
            (
                "server_action_id",
                "mass.editing.line",
                "mass_editing_line",
                "integer",
                False,
                "mass_editing",
            ),
        ],
    )
    openupgrade.logged_query(
        env.cr,
        sql.SQL(
            """
        UPDATE mass_editing_line l
        SET server_action_id = sa.id
        FROM ir_act_server sa
        WHERE l.mass_editing_id = sa.{}
        """, ).format(
                sql.Identifier(
                    openupgrade.get_legacy_name("mass_editing_id"))),
    )
    # Delete fields that no longer exist (ondelete didn't exist before)
    openupgrade.logged_query(
        env.cr,
        """
        DELETE FROM mass_editing_line
        WHERE field_id IS NULL
        OR field_id NOT IN (SELECT id FROM ir_model_fields)
        """,
    )