采购
This commit is contained in:
@@ -6,6 +6,7 @@ class ProductTemplate(models.Model):
|
||||
_inherit = 'product.template'
|
||||
|
||||
is_fixed_assets = fields.Boolean(string='是否固定资产', default=True)
|
||||
journal_item_count = fields.Integer(string='会计凭证行数量', compute='_compute_journal_item_count')
|
||||
|
||||
@api.onchange('is_fixed_assets')
|
||||
def _onchange_fixed_assets(self):
|
||||
@@ -21,4 +22,99 @@ class ProductTemplate(models.Model):
|
||||
template_ids = self.env["product.template"].browse(self._context.get('active_ids', self._context.get('active_id')))
|
||||
company_id = self.env['res.company'].search([('name', '=', '集团本部')])
|
||||
for template in template_ids:
|
||||
template.write({'company_id': company_id.id})
|
||||
template.write({'company_id': company_id.id})
|
||||
|
||||
# 常见关联模型映射(表名 → 中文显示名)
|
||||
_DELETE_CHECK_MODELS = [
|
||||
# (模型名, 关联字段, 中文名, 描述模板)
|
||||
('account.move.line', 'product_id', '会计凭证行(Journal Item)', '该产品已被 {count} 条会计凭证行引用'),
|
||||
('sale.order.line', 'product_template_id', '销售订单行', '该产品已被 {count} 条销售订单行引用'),
|
||||
('purchase.order.line', 'product_template_id', '采购订单行', '该产品已被 {count} 条采购订单行引用'),
|
||||
('stock.move', 'product_tmpl_id', '库存移动单', '该产品已被 {count} 条库存移动单引用'),
|
||||
('stock.move.line', 'product_tmpl_id', '库存移动明细', '该产品已被 {count} 条库存移动明细引用'),
|
||||
('stock.quant', 'product_tmpl_id', '库存数量记录', '该产品存在 {count} 条库存数量记录'),
|
||||
('maintenance.equipment', 'product_tmpl_id', '固定资产设备', '该产品已关联 {count} 个设备'),
|
||||
('mrp.production', 'product_tmpl_id', '生产工单', '该产品已关联 {count} 张生产工单'),
|
||||
('mrp.bom', 'product_tmpl_id', '物料清单(BOM)', '该产品已关联 {count} 个物料清单'),
|
||||
('pos.order.line', 'product_id', 'POS订单行', '该产品已被 {count} 条POS订单行引用'),
|
||||
]
|
||||
|
||||
def unlink(self):
|
||||
"""重写删除方法,删除前检查关联数据并给出友好提示"""
|
||||
# 逐个检查每个产品的关联情况
|
||||
blocked_products = []
|
||||
for record in self:
|
||||
references = self._check_product_references(record)
|
||||
if references:
|
||||
blocked_products.append((record.display_name, references))
|
||||
|
||||
# 如果有被阻塞的产品,汇总提示
|
||||
if blocked_products:
|
||||
detail_lines = []
|
||||
for prod_name, refs in blocked_products:
|
||||
for ref_msg in refs:
|
||||
detail_lines.append(f'• 【{prod_name}】{ref_msg}')
|
||||
raise UserError(
|
||||
'以下产品无法删除,因为它们已被其他业务数据引用:\n\n'
|
||||
+ '\n'.join(detail_lines) +
|
||||
'\n\n建议操作:请使用「存档」功能替代「删除」,'
|
||||
'存档后产品不会在列表中展示且不影响已有数据。'
|
||||
)
|
||||
return super().unlink()
|
||||
|
||||
def _check_product_references(self, record):
|
||||
"""检查单个产品的关联引用,返回提示信息列表"""
|
||||
results = []
|
||||
# 获取该产品所有变体ID
|
||||
variant_ids = record.product_variant_ids.ids
|
||||
|
||||
for model_name, field_name, cn_name, msg_template in self._DELETE_CHECK_MODELS:
|
||||
try:
|
||||
# 检查模型是否存在
|
||||
if model_name not in self.env:
|
||||
continue
|
||||
|
||||
domain = []
|
||||
# 根据关联字段是 product_id 还是 product_tmpl_id 构建搜索条件
|
||||
if field_name == 'product_id':
|
||||
domain = [('product_id', 'in', variant_ids)]
|
||||
elif field_name == 'product_template_id' or field_name == 'product_tmpl_id':
|
||||
domain = [(field_name, '=', record.id)]
|
||||
|
||||
count = self.env[model_name].search_count(domain)
|
||||
if count > 0:
|
||||
results.append(msg_template.format(count=count))
|
||||
except Exception:
|
||||
# 某些模型可能查询异常,跳过不影响主流程
|
||||
continue
|
||||
|
||||
return results
|
||||
|
||||
def _compute_journal_item_count(self):
|
||||
"""计算该产品关联的会计凭证行数量"""
|
||||
for record in self:
|
||||
# 获取所有变体ID
|
||||
variant_ids = record.product_variant_ids.ids
|
||||
if 'account.move.line' in record.env:
|
||||
# 按变体product_id统计凭证行数量
|
||||
count = self.env['account.move.line'].search_count([
|
||||
('product_id', 'in', variant_ids)
|
||||
])
|
||||
record.journal_item_count = count
|
||||
else:
|
||||
record.journal_item_count = 0
|
||||
|
||||
def action_view_journal_items(self):
|
||||
"""打开关联的会计凭证行列表"""
|
||||
self.ensure_one()
|
||||
variant_ids = self.product_variant_ids.ids
|
||||
# 构建搜索域:按产品的变体ID查找凭证行
|
||||
domain = [('product_id', 'in', variant_ids)]
|
||||
return {
|
||||
'name': f'{self.display_name} - 会计凭证行',
|
||||
'type': 'ir.actions.act_window',
|
||||
'res_model': 'account.move.line',
|
||||
'view_mode': 'tree,form',
|
||||
'domain': domain,
|
||||
'context': {'default_product_id': variant_ids[0] if variant_ids else False},
|
||||
}
|
||||
@@ -26,6 +26,17 @@
|
||||
<label for="is_fixed_assets" string="是否固定资产"/>
|
||||
<field name="is_fixed_assets" nolabel="1"/>
|
||||
</xpath>
|
||||
|
||||
<!-- 在智能按钮区域添加关联会计凭证行按钮 -->
|
||||
<xpath expr="//div[@name='button_box']" position="inside">
|
||||
<button name="action_view_journal_items"
|
||||
type="object"
|
||||
icon="fa-file-text-o"
|
||||
class="oe_stat_button"
|
||||
string="会计凭证行">
|
||||
<field string="会计凭证行" name="journal_item_count" widget="statinfo"/>
|
||||
</button>
|
||||
</xpath>
|
||||
</field>
|
||||
</record>
|
||||
</odoo>
|
||||
Reference in New Issue
Block a user