mirror of
https://github.com/bringout/oca-technical.git
synced 2026-04-18 09:12:03 +02:00
Initial commit: OCA Technical packages (595 packages)
This commit is contained in:
commit
2cc02aac6e
24950 changed files with 2318079 additions and 0 deletions
|
|
@ -0,0 +1,131 @@
|
|||
# Copyright 2014-2016 Therp BV <http://therp.nl>
|
||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
|
||||
# pylint: disable=consider-merging-classes-inherited
|
||||
from odoo import _, api, fields, models
|
||||
from odoo.exceptions import UserError
|
||||
|
||||
from odoo.addons.base.models.ir_model import MODULE_UNINSTALL_FLAG
|
||||
|
||||
from ..identifier_adapter import IdentifierAdapter
|
||||
|
||||
|
||||
class CleanupPurgeLineField(models.TransientModel):
|
||||
_inherit = "cleanup.purge.line"
|
||||
_name = "cleanup.purge.line.field"
|
||||
_description = "Purge fields"
|
||||
|
||||
wizard_id = fields.Many2one(
|
||||
"cleanup.purge.wizard.field", "Purge Wizard", readonly=True
|
||||
)
|
||||
field_id = fields.Many2one(
|
||||
comodel_name="ir.model.fields",
|
||||
string="Field",
|
||||
)
|
||||
model_id = fields.Many2one(
|
||||
comodel_name="ir.model",
|
||||
related="field_id.model_id",
|
||||
string="Model",
|
||||
store=True,
|
||||
)
|
||||
model_name = fields.Char(
|
||||
related="model_id.model",
|
||||
string="Model Technical Name",
|
||||
store=True,
|
||||
)
|
||||
|
||||
def purge(self):
|
||||
"""
|
||||
Unlink fields upon manual confirmation.
|
||||
"""
|
||||
context_flags = {
|
||||
MODULE_UNINSTALL_FLAG: True,
|
||||
"purge": True,
|
||||
}
|
||||
if self:
|
||||
objs = self
|
||||
else:
|
||||
objs = self.env["cleanup.purge.line.action"].browse(
|
||||
self._context.get("active_ids")
|
||||
)
|
||||
to_unlink = objs.filtered(lambda x: not x.purged and x.field_id)
|
||||
self.logger.info("Purging field entries:")
|
||||
for rec in to_unlink:
|
||||
self.logger.info(" - %s.%s", rec.model_name, rec.field_id.name)
|
||||
field_id = rec.with_context(**context_flags).field_id
|
||||
model = self.env[rec.model_name]
|
||||
table_name = model._table
|
||||
column_name = field_id.name
|
||||
force_drop = False
|
||||
# FIX: on unlink, odoo will not DROP the SQL column even if exists if the
|
||||
# store attribute is set to False.
|
||||
if not field_id.store and model._auto:
|
||||
force_drop = True
|
||||
# Odoo will internally drop the SQL column
|
||||
field_id.unlink()
|
||||
if force_drop:
|
||||
self._drop_column(table_name, column_name)
|
||||
rec.purged = True
|
||||
return True
|
||||
|
||||
def _drop_column(self, table, column):
|
||||
# Use code from `purge_columns.py::purge()`
|
||||
# Check whether the column actually still exists.
|
||||
# Inheritance such as stock.picking.in from stock.picking
|
||||
# can lead to double attempts at removal
|
||||
self.env.cr.execute(
|
||||
"SELECT count(attname) FROM pg_attribute "
|
||||
"WHERE attrelid = "
|
||||
"( SELECT oid FROM pg_class WHERE relname = %s ) "
|
||||
"AND attname = %s",
|
||||
(table, column),
|
||||
)
|
||||
if not self.env.cr.fetchone()[0]:
|
||||
return
|
||||
self.logger.info("Dropping column %s from table %s", column, table)
|
||||
self.env.cr.execute(
|
||||
"ALTER TABLE %s DROP COLUMN %s",
|
||||
(IdentifierAdapter(table), IdentifierAdapter(column)),
|
||||
)
|
||||
# we need this commit because the ORM will deadlock if
|
||||
# we still have a pending transaction
|
||||
self.env.cr.commit() # pylint: disable=invalid-commit
|
||||
|
||||
|
||||
class CleanupPurgeWizardField(models.TransientModel):
|
||||
_inherit = "cleanup.purge.wizard"
|
||||
_name = "cleanup.purge.wizard.field"
|
||||
_description = "Purge fields"
|
||||
|
||||
@api.model
|
||||
def find(self):
|
||||
"""
|
||||
Search for fields not technically mapped to a model.
|
||||
"""
|
||||
res = []
|
||||
ignored_fields = models.MAGIC_COLUMNS + [
|
||||
"display_name",
|
||||
models.BaseModel.CONCURRENCY_CHECK_FIELD,
|
||||
]
|
||||
domain = [("state", "=", "base")]
|
||||
for field_id in self.env["ir.model.fields"].search(domain):
|
||||
if field_id.name in ignored_fields:
|
||||
continue
|
||||
model = self.env[field_id.model_id.model]
|
||||
if field_id.name not in model._fields.keys():
|
||||
res.append(
|
||||
(
|
||||
0,
|
||||
0,
|
||||
{
|
||||
"name": field_id.name,
|
||||
"field_id": field_id.id,
|
||||
},
|
||||
)
|
||||
)
|
||||
if not res:
|
||||
raise UserError(_("No orphaned fields found"))
|
||||
return res
|
||||
|
||||
purge_line_ids = fields.One2many(
|
||||
"cleanup.purge.line.field", "wizard_id", "Fields to purge"
|
||||
)
|
||||
Loading…
Add table
Add a link
Reference in a new issue