From c2723d9d053029cd2b1b1010fcef27a5f036831b Mon Sep 17 00:00:00 2001 From: mgw <1392924357@qq.com> Date: Fri, 28 Jun 2024 09:19:09 +0800 Subject: [PATCH 1/2] =?UTF-8?q?=E5=A4=84=E7=90=86unlink=E4=BC=A0=E5=8F=82?= =?UTF-8?q?=E9=97=AE=E9=A2=982?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- jikimo_hide_options/models/models.py | 224 ++++++++++++--------------- 1 file changed, 97 insertions(+), 127 deletions(-) diff --git a/jikimo_hide_options/models/models.py b/jikimo_hide_options/models/models.py index f798fd48..c06acc45 100644 --- a/jikimo_hide_options/models/models.py +++ b/jikimo_hide_options/models/models.py @@ -200,7 +200,7 @@ def _create(self, data_list): @api.model -def unlink(self, ids): +def unlink(self, *args): """ unlink() Deletes the records in ``self``. @@ -210,148 +210,118 @@ def unlink(self, ids): """ if not self: return True - if not ids: - return True self.check_access_rights('unlink') self.check_access_rule('unlink') from odoo.addons.base.models.ir_model import MODULE_UNINSTALL_FLAG - for record_id in ids: - record = self.browse(record_id) - for func in record._ondelete_methods: - # func._ondelete is True if it should be called during uninstallation - if func._ondelete or not record._context.get(MODULE_UNINSTALL_FLAG): - func(record) + for func in self._ondelete_methods: + # func._ondelete is True if it should be called during uninstallation + if func._ondelete or not self._context.get(MODULE_UNINSTALL_FLAG): + func(self) - # TOFIX: this avoids an infinite loop when trying to recompute a - # field, which triggers the recomputation of another field using the - # same compute function, which then triggers again the computation - # of those two fields - for field in record._fields.values(): - record.env.remove_to_compute(field, record) + # TOFIX: this avoids an infinite loop when trying to recompute a + # field, which triggers the recomputation of another field using the + # same compute function, which then triggers again the computation + # of those two fields + for field in self._fields.values(): + self.env.remove_to_compute(field, self) - record.env.flush_all() + self.env.flush_all() - cr = record._cr - Data = record.env['ir.model.data'].sudo().with_context({}) - Defaults = record.env['ir.default'].sudo() - Property = record.env['ir.property'].sudo() - Attachment = record.env['ir.attachment'].sudo() - ir_property_unlink = Property - ir_model_data_unlink = Data - ir_attachment_unlink = Attachment + cr = self._cr + Data = self.env['ir.model.data'].sudo().with_context({}) + Defaults = self.env['ir.default'].sudo() + Property = self.env['ir.property'].sudo() + Attachment = self.env['ir.attachment'].sudo() + ir_property_unlink = Property + ir_model_data_unlink = Data + ir_attachment_unlink = Attachment - # mark fields that depend on 'record' to recompute them after 'record' has - # been deleted (like updating a sum of lines after deleting one line) - with record.env.protecting(record._fields.values(), record): - record.modified(record._fields, before=True) - for sub_ids in cr.split_for_in_conditions(record.ids): - records = record.browse(sub_ids) + # mark fields that depend on 'self' to recompute them after 'self' has + # been deleted (like updating a sum of lines after deleting one line) + with self.env.protecting(self._fields.values(), self): + self.modified(self._fields, before=True) + for sub_ids in cr.split_for_in_conditions(self.ids): + records = self.browse(sub_ids) - # Check if the records are used as default properties. - refs = [f'{record._name},{id_}' for id_ in sub_ids] - if Property.search( - [('res_id', '=', False), ('value_reference', 'in', refs)], - limit=1): - raise UserError( - _('Unable to delete this document because it is used as a default property')) + # Check if the records are used as default properties. + refs = [f'{self._name},{id_}' for id_ in sub_ids] + if Property.search( + [('res_id', '=', False), ('value_reference', 'in', refs)], + limit=1): + raise UserError( + _('Unable to delete this document because it is used as a default property')) - # Delete the records' properties. - ir_property_unlink |= Property.search([('res_id', 'in', refs)]) + # Delete the records' properties. + ir_property_unlink |= Property.search([('res_id', 'in', refs)]) - query = f'DELETE FROM "{record._table}" WHERE id IN %s' - cr.execute(query, (sub_ids,)) + query = f'DELETE FROM "{self._table}" WHERE id IN %s' + cr.execute(query, (sub_ids,)) - # Removing the ir_model_data reference if the record being deleted - # is a record created by xml/csv file, as these are not connected - # with real database foreign keys, and would be dangling references. - # - # Note: the following steps are performed as superuser to avoid - # access rights restrictions, and with no context to avoid possible - # side-effects during admin calls. - data = Data.search( - [('model', '=', record._name), ('res_id', 'in', sub_ids)]) - ir_model_data_unlink |= data + # Removing the ir_model_data reference if the record being deleted + # is a record created by xml/csv file, as these are not connected + # with real database foreign keys, and would be dangling references. + # + # Note: the following steps are performed as superuser to avoid + # access rights restrictions, and with no context to avoid possible + # side-effects during admin calls. + data = Data.search( + [('model', '=', self._name), ('res_id', 'in', sub_ids)]) + ir_model_data_unlink |= data - # For the same reason, remove the defaults having some of the - # records as value - Defaults.discard_records(records) + # For the same reason, remove the defaults having some of the + # records as value + Defaults.discard_records(records) - # For the same reason, remove the relevant records in ir_attachment - # (the search is performed with sql as the search method of - # ir_attachment is overridden to hide attachments of deleted - # records) - query = 'SELECT id FROM ir_attachment WHERE res_model=%s AND res_id IN %s' - cr.execute(query, (record._name, sub_ids)) - ir_attachment_unlink |= Attachment.browse( - row[0] for row in cr.fetchall()) + # For the same reason, remove the relevant records in ir_attachment + # (the search is performed with sql as the search method of + # ir_attachment is overridden to hide attachments of deleted + # records) + query = 'SELECT id FROM ir_attachment WHERE res_model=%s AND res_id IN %s' + cr.execute(query, (self._name, sub_ids)) + ir_attachment_unlink |= Attachment.browse( + row[0] for row in cr.fetchall()) - # invalidate the *whole* cache, since the orm does not handle all - # changes made in the database, like cascading delete! - record.env.invalidate_all(flush=False) - if ir_property_unlink: - ir_property_unlink.unlink() - if ir_model_data_unlink: - ir_model_data_unlink.unlink() - if ir_attachment_unlink: - ir_attachment_unlink.unlink() - # DLE P93: flush after the unlink, for recompute fields depending on - # the modified of the unlink - record.env.flush_all() - # auditing: deletions are infrequent and leave no trace in the database - _unlink.info('User #%s deleted %s records with IDs: %r', record._uid, - record._name, record.ids) - # This is used to restrict the access right to unlink a record - current_model_id = record.env['ir.model'].sudo().search( - [('model', '=', record._name)]).id - # access_right_rec = record.env['access.right'].sudo().search_read( - # [('model_id', '=', current_model_id)], ['model_id', 'is_delete', - # 'groups_id']) - # if access_right_rec and not record.env.is_admin(): - # for rec in access_right_rec: - # group_name = record.env['ir.model.data'].sudo().search([ - # ('model', '=', 'res.groups'), - # ('res_id', '=', rec['groups_id'][0]) - # ]).name - # module_name = record.env['ir.model.data'].sudo().search([ - # ('model', '=', 'res.groups'), - # ('res_id', '=', rec['groups_id'][0]) - # ]).module - # group = module_name + "." + group_name - # if record.env.user.has_group(group): - # if rec['is_delete']: - # raise UserError(_('You are restricted from performing this' - # ' operation. Please contact the' - # ' administrator.')) - # 检查 'access.right' 模型是否存在于环境中 - if 'access.right' in record.env: - # current_model_id = record.env['ir.model'].sudo().search([('model', '=', record._name)]).id - access_right_rec = record.env['access.right'].sudo().search_read( - [('model_id', '=', current_model_id)], ['model_id', 'is_delete', 'groups_id'] - ) - - if access_right_rec and not record.env.is_admin(): - for rec in access_right_rec: - group_data = record.env['ir.model.data'].sudo().search_read( - [('model', '=', 'res.groups'), ('res_id', '=', rec['groups_id'][0])], - ['name', 'module'] - ) - - if group_data: - group_name = group_data[0]['name'] - module_name = group_data[0]['module'] - group_xml_id = f"{module_name}.{group_name}" - - if record.env.user.has_group(group_xml_id) and rec['is_delete']: - raise UserError( - _('You are restricted from performing this operation. Please contact the administrator.')) - else: - # 如果 'access.right' 模型不存在,可以在这里定义备选逻辑 - pass - - return True + # invalidate the *whole* cache, since the orm does not handle all + # changes made in the database, like cascading delete! + self.env.invalidate_all(flush=False) + if ir_property_unlink: + ir_property_unlink.unlink() + if ir_model_data_unlink: + ir_model_data_unlink.unlink() + if ir_attachment_unlink: + ir_attachment_unlink.unlink() + # DLE P93: flush after the unlink, for recompute fields depending on + # the modified of the unlink + self.env.flush_all() + # auditing: deletions are infrequent and leave no trace in the database + _unlink.info('User #%s deleted %s records with IDs: %r', self._uid, + self._name, self.ids) + # This is used to restrict the access right to unlink a record + current_model_id = self.env['ir.model'].sudo().search( + [('model', '=', self._name)]).id + access_right_rec = self.env['access.right'].sudo().search_read( + [('model_id', '=', current_model_id)], ['model_id', 'is_delete', + 'groups_id']) + if access_right_rec and not self.env.is_admin(): + for rec in access_right_rec: + group_name = self.env['ir.model.data'].sudo().search([ + ('model', '=', 'res.groups'), + ('res_id', '=', rec['groups_id'][0]) + ]).name + module_name = self.env['ir.model.data'].sudo().search([ + ('model', '=', 'res.groups'), + ('res_id', '=', rec['groups_id'][0]) + ]).module + group = module_name + "." + group_name + if self.env.user.has_group(group): + if rec['is_delete']: + raise UserError(_('You are restricted from performing this' + ' operation. Please contact the' + ' administrator.')) + return True BaseModel._create = _create -BaseModel.unlink = unlink +BaseModel.unlink = unlink \ No newline at end of file From c8de75ceaebfa91bf159f774e814e42187a5840f Mon Sep 17 00:00:00 2001 From: mgw <1392924357@qq.com> Date: Fri, 28 Jun 2024 09:51:31 +0800 Subject: [PATCH 2/2] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E9=9A=90=E8=97=8F?= =?UTF-8?q?=E9=A1=B9=E7=9B=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- jikimo_hide_options/models/models.py | 2 +- sf_machine_connect/views/compensation.xml | 12 ++--- sf_machine_connect/views/ftp_button.xml | 2 +- sf_machine_connect/wizard/up_select.xml | 2 +- sf_manufacturing/models/mrp_production.py | 8 --- sf_manufacturing/models/mrp_workorder.py | 53 +++++++++---------- sf_manufacturing/models/stock.py | 2 +- sf_manufacturing/views/mrp_workorder_view.xml | 12 ++--- sf_mrs_connect/controllers/controllers.py | 6 +-- sf_plan/models/custom_plan.py | 24 ++++----- sf_plan/views/view.xml | 2 +- 11 files changed, 57 insertions(+), 68 deletions(-) diff --git a/jikimo_hide_options/models/models.py b/jikimo_hide_options/models/models.py index c06acc45..84aee828 100644 --- a/jikimo_hide_options/models/models.py +++ b/jikimo_hide_options/models/models.py @@ -200,7 +200,7 @@ def _create(self, data_list): @api.model -def unlink(self, *args): +def unlink(self): """ unlink() Deletes the records in ``self``. diff --git a/sf_machine_connect/views/compensation.xml b/sf_machine_connect/views/compensation.xml index 7668d818..55036c8d 100644 --- a/sf_machine_connect/views/compensation.xml +++ b/sf_machine_connect/views/compensation.xml @@ -20,12 +20,12 @@ -