Odoo10:如何通过按钮调用copy函数复制销售订单续订服务
正确实现Odoo服务续订订单复制功能
Hey there! Let's get your "Re-New" button working exactly how you need it—copying the full sales order with all data and setting up the 2-year renewal. Your current code is a good start, but we need to tweak it to fit Odoo's best practices and your specific requirements.
1. 替换已废弃的装饰器
首先,@api.one在Odoo 10及以后版本已经被废弃了,建议换成@api.multi——它专门用于处理单条或多条记录的操作,非常适合按钮触发的动作场景。
2. 自定义复制行为
默认的copy()方法只会复制基础字段,但我们需要针对续订场景覆盖关键值:
- 给新订单名称添加明确的标识(比如"- 续订"),方便区分原订单和续订订单
- 将订单状态重置为
draft,方便后续调整或确认 - 设置2年续订周期的起止日期
- 按需覆盖其他和服务相关的自定义字段
3. 返回动作跳转至新订单
复制完成后,最好直接引导用户打开刚生成的续订订单,方便他们立即查看或处理。
完整可用代码
以下是更新后的方法和按钮配置(注意根据你的实际模型调整字段名称):
模型方法
from odoo import models, fields, api class YourServiceOrderModel(models.Model): _inherit = 'sale.order' # 如果是自定义服务订单模型,替换成你的模型名 @api.multi def dup_line(self): for order in self: # 计算2年续订周期的日期 today = fields.Date.today() renewal_end_date = fields.Date.add(today, years=2) # 复制订单并设置自定义默认值 copied_order = order.copy(default={ 'name': f"{order.name} - 续订", 'state': 'draft', 'date_order': today, # 将订单日期设为今日 'start_date': today, # 替换成你模型里实际的服务开始日期字段名 'end_date': renewal_end_date, # 替换成你模型里实际的服务结束日期字段名 # 这里可以添加其他需要覆盖的字段,比如客户参考、备注等 }) # 可选:如果需要自动确认续订订单,取消下面的注释 # copied_order.action_confirm() # 跳转至新生成的续订订单页面 return { 'type': 'ir.actions.act_window', 'name': '续订服务订单', 'res_model': self._name, 'res_id': copied_order.id, 'view_mode': 'form', 'view_type': 'form', 'target': 'current', }
按钮定义
保留你的按钮代码,确保它放在正确的视图中(比如销售订单表单视图):
<button name="dup_line" type="object" string="Re-New" class="oe_highlight"/>
关键注意事项
- 字段匹配:请将
start_date、end_date等字段替换成你模型中实际的字段名,如果使用标准sale.order模型,可能需要先添加服务有效期的自定义字段。 - 关联行复制:默认的
copy()方法会自动复制所有order_line记录,只要这些行项目的字段定义中设置了copy=True(大多数字段默认都是开启的)。 - 权限检查:确保操作按钮的用户拥有该订单模型的创建权限,否则复制操作会静默失败。
- 批量处理:使用
@api.multi可以让你后续轻松扩展成批量续订多个订单的功能。
内容的提问来源于stack exchange,提问作者Pawan Kumar Sharma
相关产品推荐
相关产品推荐

