From bcb60425b230181e4c707aaca838f4e0c1f66d09 Mon Sep 17 00:00:00 2001
From: yuxianghui <3437689193@qq.com>
Date: Wed, 26 Jun 2024 17:07:09 +0800
Subject: [PATCH 1/4] =?UTF-8?q?1=E3=80=81=E5=AE=8C=E6=88=90=20=E5=86=85?=
=?UTF-8?q?=E9=83=A8=E8=B0=83=E6=8B=A8=E5=8D=95=E4=BC=98=E5=8C=96=E9=A1=B9?=
=?UTF-8?q?=20=E9=9C=80=E6=B1=82=EF=BC=9B2=E3=80=81=E8=A7=A3=E5=86=B3=20?=
=?UTF-8?q?=20=E4=B8=8D=E5=90=8C=E5=BA=8F=E5=88=97=E5=8F=B7=E8=B0=83?=
=?UTF-8?q?=E6=8B=A8=E5=8D=95=E9=80=89=E6=8B=A9=E5=90=8C=E4=B8=80=E4=B8=AA?=
=?UTF-8?q?=E8=B4=A7=E4=BD=8D=E5=8F=AF=E4=BB=A5=E7=A1=AE=E8=AE=A4=E6=88=90?=
=?UTF-8?q?=E5=8A=9F=20bug=EF=BC=9B3=E3=80=81=E6=94=B6=E8=B4=A7=E5=85=A5?=
=?UTF-8?q?=E5=BA=93=E6=97=B6=E6=89=AB=E6=8F=8F=E5=BD=95=E5=85=A5Rfid?=
=?UTF-8?q?=E6=96=B9=E6=B3=95=E6=B7=BB=E5=8A=A0=E6=97=A5=E5=BF=97?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
sf_warehouse/models/model.py | 30 +++++++++++++++----
.../views/change_stock_move_views.xml | 15 ++++++----
2 files changed, 34 insertions(+), 11 deletions(-)
diff --git a/sf_warehouse/models/model.py b/sf_warehouse/models/model.py
index c429a5eb..ee212b2a 100644
--- a/sf_warehouse/models/model.py
+++ b/sf_warehouse/models/model.py
@@ -557,8 +557,10 @@ class SfStockMoveLine(models.Model):
_name = 'stock.move.line'
_inherit = ['stock.move.line', 'printing.utils']
+ stock_lot_name = fields.Char('序列号名称', related='lot_id.name')
current_location_id = fields.Many2one(
- 'sf.shelf.location', string='当前货位', compute='_compute_current_location_id', store=True)
+ 'sf.shelf.location', string='当前货位', compute='_compute_current_location_id', store=True, readonly=False,
+ domain="[('product_id', '=', product_id),'|',('product_sn_id.name', '=', stock_lot_name),('product_sn_ids.lot_id.name','=',stock_lot_name)]")
# location_dest_id = fields.Many2one('stock.location', string='目标库位')
location_dest_id_product_type = fields.Many2many(related='location_dest_id.product_type')
location_dest_id_value = fields.Integer(compute='_compute_location_dest_id_value', store=True)
@@ -856,7 +858,9 @@ class SfStockMoveLine(models.Model):
def compute_destination_location_id(self):
for record in self:
obj = self.env['sf.shelf.location'].search([('name', '=',
- self.destination_location_id.name)])
+ record.destination_location_id.name)])
+ if obj and obj.product_id and obj.product_id != record.product_id:
+ raise ValidationError('目标货位【%s】已被【%s】产品占用!' % (obj.code, obj.product_id))
if record.lot_id:
if record.product_id.tracking == 'serial':
shelf_location_obj = self.env['sf.shelf.location'].search(
@@ -869,7 +873,7 @@ class SfStockMoveLine(models.Model):
if obj:
obj.product_sn_id = record.lot_id.id
elif record.product_id.tracking == 'lot':
- self.put_shelf_location(record)
+ record.put_shelf_location(record)
if not obj.product_id:
obj.product_id = record.product_id.id
else:
@@ -980,15 +984,26 @@ class SfStockPicking(models.Model):
# 调用入库方法进行入库刀货位
line.compute_destination_location_id()
else:
- # 对除刀柄之外的刀具物料进行 目标货位必填校验
+ # 对除刀柄之外的刀具物料入库到刀具房进行 目标货位必填校验
if self.location_dest_id.name == '刀具房' and line.product_id.cutting_tool_material_id.name not in (
'刀柄', False):
raise ValidationError('请选择【%s】产品的目标货位!' % line.product_id.name)
+ if line.current_location_id:
+ # 对货位的批次产品进行出货
+ line.put_shelf_location(line)
+
if line.current_location_id:
+ # 按序列号管理的产品
if line.current_location_id.product_sn_id:
line.current_location_id.product_sn_id = False
# line.current_location_id.location_status = '空闲'
line.current_location_id.product_num = 0
+ line.current_location_id.product_id = False
+ else:
+ # 对除刀柄之外的刀具物料从刀具房出库进行 当前货位必填校验
+ if self.location_id.name == '刀具房' and line.product_id.cutting_tool_material_id.name not in (
+ '刀柄', False):
+ raise ValidationError('请选择【%s】产品的当前货位!' % line.product_id.name)
# 对入库作业的刀柄和托盘进行Rfid绑定校验
for move in self.move_ids:
@@ -1115,6 +1130,7 @@ class CustomStockMove(models.Model):
采购入库扫码绑定Rfid码
"""
for record in self:
+ logging.info('Rfid:%s' % barcode)
if record:
lot = self.env['stock.lot'].sudo().search([('rfid', '=', barcode)])
if lot:
@@ -1126,7 +1142,9 @@ class CustomStockMove(models.Model):
'该Rfid【%s】已经被序列号为【%s】的【%s】物料所占用!' % (barcode, lot.name, material))
if '刀柄' in (record.product_id.cutting_tool_material_id.name or '') or '托盘' in (
record.product_id.fixture_material_id.name or ''):
+ logging.info('开始录入Rfid:%s' % record.move_line_nosuggest_ids)
for move_line_nosuggest_id in record.move_line_nosuggest_ids:
+ logging.info('录入的记录%s , Rfid:%s' % (move_line_nosuggest_id, move_line_nosuggest_id.rfid))
if move_line_nosuggest_id.rfid:
if move_line_nosuggest_id.rfid == barcode:
if record.product_id.cutting_tool_material_id.name:
@@ -1135,7 +1153,9 @@ class CustomStockMove(models.Model):
raise ValidationError('该托盘的Rfid已经录入,请勿重复录入!!!')
else:
line_id = int(re.sub(r"\D", "", str(move_line_nosuggest_id.id)))
- self.env['stock.move.line'].sudo().search([('id', '=', line_id)]).write({'rfid': barcode})
+ res = self.env['stock.move.line'].sudo().search([('id', '=', line_id)]).write(
+ {'rfid': barcode})
+ logging.info('Rfid是否录入:%s' % res)
move_line_nosuggest_id.rfid = barcode
break
else:
diff --git a/sf_warehouse/views/change_stock_move_views.xml b/sf_warehouse/views/change_stock_move_views.xml
index a77b916c..29d09926 100644
--- a/sf_warehouse/views/change_stock_move_views.xml
+++ b/sf_warehouse/views/change_stock_move_views.xml
@@ -7,16 +7,18 @@
-
+
+
-
-
-
-
-
+
+
+
+
+
@@ -55,6 +57,7 @@
+
From 70ffbafac4696449a243d37296a9ba34f9cf024a Mon Sep 17 00:00:00 2001
From: hy <1298386937@qq.com>
Date: Thu, 27 Jun 2024 09:57:12 +0800
Subject: [PATCH 2/4] =?UTF-8?q?=E7=94=98=E7=89=B9=E4=BF=AE=E6=94=B9?=
=?UTF-8?q?=E8=83=8C=E6=99=AF=E9=A2=9C=E8=89=B2=E5=92=8C=E4=B8=8D=E5=8F=AF?=
=?UTF-8?q?=E6=8B=96=E6=8B=BD=E6=A8=A1=E5=9D=97?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
web_gantt/static/src/js/gantt_row.js | 31 +++++++++++++++++++++---
web_gantt/static/src/scss/web_gantt.scss | 4 +++
2 files changed, 31 insertions(+), 4 deletions(-)
diff --git a/web_gantt/static/src/js/gantt_row.js b/web_gantt/static/src/js/gantt_row.js
index 420e3ad5..fb7ffab7 100644
--- a/web_gantt/static/src/js/gantt_row.js
+++ b/web_gantt/static/src/js/gantt_row.js
@@ -592,8 +592,23 @@ var GanttRow = Widget.extend({
});
pill.decorations = pillDecorations;
- if (self.colorField) {
- pill._color = self._getColor(pill[self.colorField]);
+ // let isDelay = false
+ // if(pill.state != 'processing' && pill.state != 'finished') { // 判断待加工
+ // isDelay = pill.order_deadline.isBefore(new Date())
+ // }
+ pill.exState = ''
+ if (self.colorField){
+ // console.log(self.colorField, self, pill, '颜色')
+ // pill._color = self._getColor(pill[self.colorField]);
+ // 设置pill背景颜色2 修改时间2024年6月25日17:09:43
+ let isDelay = false
+ if(pill.state != 'processing' && pill.state != 'finished') { // 判断待加工
+ isDelay = pill.order_deadline.isBefore(new Date())
+ }
+ if(isDelay) {
+ pill.disableDragdrop = true
+ }
+ pill._color = self._getColor2(isDelay ? 'delay' : pill.state);
}
if (self.progressField) {
@@ -613,6 +628,13 @@ var GanttRow = Widget.extend({
}
return 0;
},
+ _getColor2 (state) {
+ return {
+ 'finished': 'ccc',
+ 'delay': 9,
+ 'processing': 13 // 绿色
+ }[state]
+ },
/**
* Get context to evaluate decoration
*
@@ -867,10 +889,11 @@ var GanttRow = Widget.extend({
if ($pill.hasClass('ui-draggable-dragging')) {
return;
}
-
var self = this;
var pill = _.findWhere(this.pills, { id: $pill.data('id') });
-
+ if(pill.state == 'finished'){ // 已完成状态不能拖拽
+ return;
+ }
// DRAGGABLE
if (this.options.canEdit && !pill.disableStartResize && !pill.disableStopResize && !this.isGroup) {
diff --git a/web_gantt/static/src/scss/web_gantt.scss b/web_gantt/static/src/scss/web_gantt.scss
index 7dbca3e3..bc48bee5 100644
--- a/web_gantt/static/src/scss/web_gantt.scss
+++ b/web_gantt/static/src/scss/web_gantt.scss
@@ -754,3 +754,7 @@
left: -0.5 * $o-connector-creator-bullet-diameter;
}
}
+
+.o_gantt_view .o_gantt_row_nogroup .o_gantt_pill.o_gantt_color_ccc {
+ background-color: #ccc;
+}
\ No newline at end of file
From 05f2cb553d48a264634dc7119efa38ba045ce665 Mon Sep 17 00:00:00 2001
From: yuxianghui <3437689193@qq.com>
Date: Thu, 27 Jun 2024 17:21:37 +0800
Subject: [PATCH 3/4] =?UTF-8?q?1=E3=80=81=E5=AE=8C=E6=88=90=20=E9=87=87?=
=?UTF-8?q?=E8=B4=AD/=E9=87=87=E8=B4=AD=E6=80=BB=E7=9B=91=E5=B2=97?=
=?UTF-8?q?=E4=BD=8D=E6=9D=83=E9=99=90=E5=A2=9E=E5=8A=A0=20=E9=9C=80?=
=?UTF-8?q?=E6=B1=82=EF=BC=9B2=E3=80=81=E5=AE=8C=E6=88=90=20=E5=88=80?=
=?UTF-8?q?=E5=85=B7=E5=87=BA=E5=85=A5=E5=BA=93=E5=88=97=E8=A1=A8=E7=BC=BA?=
=?UTF-8?q?=E5=B0=91=E5=8D=95=E6=8D=AE=E8=B7=B3=E8=BD=AC=20=E9=9C=80?=
=?UTF-8?q?=E6=B1=82=EF=BC=9B3=E3=80=81=E5=AE=8C=E6=88=90=20=20=E8=AE=BE?=
=?UTF-8?q?=E5=A4=87=E8=AF=A6=E6=83=85=E7=9A=84=E6=9C=BA=E5=86=85=E8=A3=85?=
=?UTF-8?q?=E5=88=80=E6=97=B6=E9=97=B4=E6=AF=94=E5=BD=93=E5=89=8D=E6=97=B6?=
=?UTF-8?q?=E9=97=B4=E8=BF=98=E6=99=9A=20=20bug=EF=BC=9B?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
sf_sale/models/sale_order.py | 5 +++++
sf_sale/security/group_security.xml | 4 ++--
sf_sale/views/purchase_order_view.xml | 7 +++++++
sf_tool_management/models/base.py | 6 ++----
sf_tool_management/models/maintenance_equipment.py | 3 ++-
sf_tool_management/models/tool_material_search.py | 5 ++---
sf_tool_management/views/tool_material_search.xml | 1 +
7 files changed, 21 insertions(+), 10 deletions(-)
diff --git a/sf_sale/models/sale_order.py b/sf_sale/models/sale_order.py
index 6508132d..f47f8c8d 100644
--- a/sf_sale/models/sale_order.py
+++ b/sf_sale/models/sale_order.py
@@ -171,6 +171,11 @@ class ProductTemplate(models.Model):
class RePurchaseOrder(models.Model):
_inherit = 'purchase.order'
+ mrp_production_count = fields.Integer(
+ "Count of MO Source",
+ compute='_compute_mrp_production_count',
+ groups='mrp.group_mrp_user,sf_base.group_purchase,sf_base.group_purchase_director')
+
remark = fields.Text('备注')
user_id = fields.Many2one(
'res.users', string='买家', index=True, tracking=True,
diff --git a/sf_sale/security/group_security.xml b/sf_sale/security/group_security.xml
index 5f23b5bb..97b6d05d 100644
--- a/sf_sale/security/group_security.xml
+++ b/sf_sale/security/group_security.xml
@@ -54,7 +54,7 @@
销售经理查看自己的订单
- ['|',('user_id','=',user.id),('create_uid', '=',user.id)]
+ ['|','|',('user_id','=',user.id),('user_id', '=', False),('create_uid', '=',user.id)]
@@ -74,7 +74,7 @@
采购岗查看自己的订单
- ['|',('user_id','=',user.id),('create_uid', '=',user.id)]
+ ['|','|',('user_id','=',user.id),('user_id', '=', False),('create_uid', '=',user.id)]
diff --git a/sf_sale/views/purchase_order_view.xml b/sf_sale/views/purchase_order_view.xml
index 85f5b1c8..eda8e59d 100644
--- a/sf_sale/views/purchase_order_view.xml
+++ b/sf_sale/views/purchase_order_view.xml
@@ -79,6 +79,13 @@
sf_base.group_purchase,sf_base.group_purchase_director
+
+
+ mrp.group_mrp_user,sf_base.group_purchase,sf_base.group_purchase_director
+
+
+
{'readonly': [('state', 'in', ['purchase'])]}
diff --git a/sf_tool_management/models/base.py b/sf_tool_management/models/base.py
index 61156536..182141cf 100644
--- a/sf_tool_management/models/base.py
+++ b/sf_tool_management/models/base.py
@@ -944,13 +944,11 @@ class FunctionalToolDismantle(models.Model):
functional_tool_assembly = self.functional_tool_id.functional_tool_name_id
if self.scrap_boolean:
# 刀柄报废 入库到Scrap
- lot.create_stock_quant(location, location_dest_scrap_ids[-1], functional_tool_assembly.id, code,
- functional_tool_assembly, functional_tool_assembly.tool_groups_id)
+ lot.create_stock_quant(location, location_dest_scrap_ids[-1], False, code, False, False)
lot.tool_material_status = '报废'
else:
# 刀柄不报废 入库到刀具房
- lot.create_stock_quant(location, location_dest, functional_tool_assembly.id, code,
- functional_tool_assembly, functional_tool_assembly.tool_groups_id)
+ lot.create_stock_quant(location, location_dest, False, code, False, False)
lot.tool_material_status = '可用'
# ==============功能刀具[报废]拆解================
diff --git a/sf_tool_management/models/maintenance_equipment.py b/sf_tool_management/models/maintenance_equipment.py
index d308f1f1..48bc531f 100644
--- a/sf_tool_management/models/maintenance_equipment.py
+++ b/sf_tool_management/models/maintenance_equipment.py
@@ -3,6 +3,7 @@ import requests
import logging
from odoo import models, api, fields
from odoo.exceptions import ValidationError
+from datetime import datetime, timedelta
from odoo.addons.sf_base.commons.common import Common
@@ -101,7 +102,7 @@ class SfMaintenanceEquipment(models.Model):
tool_install_time = {'Nomal': '正常', 'Warning': '报警'}
equipment_tool_id.write({
'functional_tool_name_id': functional_tool_id.id,
- 'tool_install_time': time
+ 'tool_install_time': time - timedelta(hours=8)
})
if functional_tool_id.current_location != '机内刀库':
# 对功能刀具进行移动到生产线
diff --git a/sf_tool_management/models/tool_material_search.py b/sf_tool_management/models/tool_material_search.py
index af8833fb..ededd64f 100644
--- a/sf_tool_management/models/tool_material_search.py
+++ b/sf_tool_management/models/tool_material_search.py
@@ -25,7 +25,8 @@ class ToolMaterial(models.Model):
have_been_used_num = fields.Integer('在用数量', compute='_compute_number', store=True)
scrap_num = fields.Integer('报废数量', compute='_compute_number', store=True)
- barcode_ids = fields.One2many('stock.lot', 'tool_material_search_id', string='序列号', readonly=True)
+ barcode_ids = fields.One2many('stock.lot', 'tool_material_search_id', string='序列号', readonly=True,
+ domain=[('tool_material_status', '!=', '未入库')])
@api.depends('product_id.stock_quant_ids.quantity')
def _compute_number(self):
@@ -46,8 +47,6 @@ class ToolMaterial(models.Model):
record.scrap_num = scrap_num
record.number = usable_num + have_been_used_num + scrap_num
-
-
@api.model
def _read_group_cutting_tool_material_id(self, categories, domain, order):
cutting_tool_material_id = categories._search([], order=order, access_rights_uid=SUPERUSER_ID)
diff --git a/sf_tool_management/views/tool_material_search.xml b/sf_tool_management/views/tool_material_search.xml
index 8a740676..ef6209f3 100644
--- a/sf_tool_management/views/tool_material_search.xml
+++ b/sf_tool_management/views/tool_material_search.xml
@@ -63,6 +63,7 @@
+
From 37f030c2db0be3a9bc71bdea7426ed37ec9f5408 Mon Sep 17 00:00:00 2001
From: mgw <1392924357@qq.com>
Date: Thu, 27 Jun 2024 17:31:03 +0800
Subject: [PATCH 4/4] =?UTF-8?q?=E5=A4=84=E7=90=86unlink()=E5=8F=82?=
=?UTF-8?q?=E6=95=B0=E9=97=AE=E9=A2=98?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
jikimo_hide_options/models/models.py | 240 ++++++++++++++-------------
1 file changed, 122 insertions(+), 118 deletions(-)
diff --git a/jikimo_hide_options/models/models.py b/jikimo_hide_options/models/models.py
index 72046dca..f798fd48 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):
+def unlink(self, ids):
""" unlink()
Deletes the records in ``self``.
@@ -210,143 +210,147 @@ def unlink(self):
"""
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 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)
+ 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)
- # 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)
+ # 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)
- self.env.flush_all()
+ record.env.flush_all()
- 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
+ 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
- # 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)
+ # 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)
- # 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'))
+ # 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'))
- # 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 "{self._table}" WHERE id IN %s'
- cr.execute(query, (sub_ids,))
+ query = f'DELETE FROM "{record._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', '=', self._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', '=', record._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, (self._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, (record._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!
- 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.'))
- # 检查 'access.right' 模型是否存在于环境中
- if 'access.right' in self.env:
- # 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']
- )
+ # 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 self.env.is_admin():
- for rec in access_right_rec:
- group_data = self.env['ir.model.data'].sudo().search_read(
- [('model', '=', 'res.groups'), ('res_id', '=', rec['groups_id'][0])],
- ['name', 'module']
- )
+ 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 group_data:
+ group_name = group_data[0]['name']
+ module_name = group_data[0]['module']
+ group_xml_id = f"{module_name}.{group_name}"
- if self.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
+ 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
+ return True
BaseModel._create = _create