Odoo 12项目任务序列按新项目重置计数问题求助
解决Odoo任务序列按项目独立计数的问题
你现在遇到的核心问题是全局序列会把所有项目的任务混在一起计数,要实现每个项目的任务序列从头开始,关键是让序列和具体项目绑定起来。下面给你两种实用的解决方案,你可以根据需求选择:
方案一:基于项目任务计数生成编号(简单易实现)
这个方案直接统计对应项目下已有的任务数量,加1作为新任务的编号。优点是不用额外创建模型,缺点是如果有任务被删除,编号会出现断层(如果不在意断层的话完全够用)。另外为了避免并发创建时重复编号,我们用SQL锁表来保证原子性:
@api.model def create(self, vals): if vals.get('name_seq', _('New')) == _('New'): project_id = vals.get('project_id') if project_id: # 用SQL查询并锁表,防止并发创建时重复计数 self.env.cr.execute(""" SELECT COUNT(*) + 1 FROM project_task WHERE project_id = %s FOR UPDATE """, (project_id,)) task_count = self.env.cr.fetchone()[0] # 自定义编号格式,比如加上项目ID和前缀 vals['name_seq'] = f"TASK-PROJ{project_id}-{task_count}" else: # 没有关联项目时,沿用原来的全局序列逻辑 vals['name_seq'] = self.env['ir.sequence'].with_context(force_company=vals.get('company_id')).next_by_code('task.project.sequence') or _('New') result = super(AddSequence, self).create(vals) return result
方案二:为每个项目维护独立的序列记录(更严谨)
如果需要严格连续的编号(即使任务被删除也不中断),可以创建一个专门的模型来存储每个项目的下一个序列值,这样每次创建任务时直接读取并更新这个值,完全避免并发和断层问题:
第一步:创建项目序列模型
先新增一个模型来保存每个项目的序列状态:
from odoo import models, fields class ProjectTaskSequence(models.Model): _name = 'project.task.sequence' _description = 'Project Task Sequence Tracker' project_id = fields.Many2one('project.project', string='Project', required=True, unique=True) next_number = fields.Integer(string='Next Sequence Number', default=1)
第二步:修改任务的create方法
在任务创建时,获取对应项目的序列记录,生成编号后更新序列值:
@api.model def create(self, vals): if vals.get('name_seq', _('New')) == _('New'): project_id = vals.get('project_id') if project_id: # 查找项目对应的序列记录,没有则自动创建 seq_tracker = self.env['project.task.sequence'].search([('project_id', '=', project_id)], limit=1) if not seq_tracker: seq_tracker = self.env['project.task.sequence'].create({ 'project_id': project_id, 'next_number': 1 }) # 生成自定义格式的编号 vals['name_seq'] = f"PROJ-{project_id}-TASK-{seq_tracker.next_number}" # 原子更新下一个序列值 seq_tracker.write({'next_number': seq_tracker.next_number + 1}) else: # 无项目时使用全局序列 vals['name_seq'] = self.env['ir.sequence'].with_context(force_company=vals.get('company_id')).next_by_code('task.project.sequence') or _('New') result = super(AddSequence, self).create(vals) return result
注意事项
- 如果你用的是自定义任务模型,记得把SQL里的
project_task换成你的模型表名。 - 编号格式可以根据需求调整,比如去掉项目ID、换成项目名称缩写等。
- 方案二需要新增模型,记得更新模块的
__manifest__.py和视图(如果需要后台管理序列的话)。
内容的提问来源于stack exchange,提问作者Ing
相关产品推荐
相关产品推荐

