Odoo | 多个tree之间实时复制数据?安排!


Odoo
神州数码云基地
在 Odoo 上的尝试、调研与分享
本期内容
多个tree实时复制
在项目中我们有时会遇到如下需求:表单中的多个列表之间存在紧密联系,一个列表内增加或者删除数据,这些修改的数据需要在另一个列表实现实时复制。
一般的方法是在前端处理,而在Odoo中,列表是通过tree视图呈现,多个tree视图要实现上述功能,需要改造前端方法,较为复杂。
本文将从odoo后端出发,介绍在odoo中如何实现多个tree之间的数据复制,为大家提供一个参考方案~
具体案例
这里以项目中遇到的一个具体问题作为案例举例说明:
如下图所示,当我们在年度目标业绩中新增或删除一条数据时,需将这条增加或删除的数据复制到第一季度目标对应的列表中。
实施细节
本方案采用后端实现,主要通过@api.onchange装饰器来完成。
该装饰器的作用是监听输入框值的改变,若改变则会调用相应的方法。
这里我们在年度目标输入值后,通过@api.onchange装饰器将年度目标的值复制一份给第一季度目标。
因为第一季度可能存在不输入年度的值,因此这里需要在第一季度目标原有的基础上添加或删除年度目标的值,其代码如下图所示:
# 监听年度目标信息
@api.onchange('year_target_performance_ids')
def onchange_year_target_performance_ids(self):
year_target_agent_and_item_dict = {}
total = Total()
for item in self.year_target_performance_ids:
total.calculate_total(item.year_quantity_target, item.year_amount_target, item.year_full_target,
item.year_public_cloud_target)
if item.year_general_agent_target:
year_target_agent_and_item_dict[item.year_general_agent_target] = item
self.which_table_edit.append(EditTable.YEAR_TARGET.value)
self.calculate_percent(total)
self.copy_year_target_to_first_target(year_target_agent_and_item_dict)
这里监听到年度目标后,将年度的信息进行了复制,复制方法如下:
def copy_year_target_to_first_target(self, year_target_agent_and_item_dict):
"""
复制年度目标总代到第一季度总代
"""
self.first_extends_year_delete(year_target_agent_and_item_dict)
first_target_general_agent_lists = self.current_exist_general_agent()
for key in year_target_agent_and_item_dict.keys():
if key not in first_target_general_agent_lists:
first_general_agent_target_item = {'first_general_agent_target': key, 'is_copy': True}
self.first_target_performance_ids += self.first_target_performance_ids.new(
first_general_agent_target_item)
此方法不会将数据存储到数据库,并且可以将复制的结果显示在自己的tree列表中,其效果如下图所示:
当我们在年度目标新增一条数据后,第一季度目标通过以上方法可以将新增的年度目标复制:
以上就实现了数据新增的复制。
删除数据复制与新增稍有区别,其实现方法如下:
def three_actual_extends_three_target_delete(self):
"""
第三季度实际继承删除
"""
three_target_agent = []
for key in self.three_target_performance_ids:
three_target_agent.append(key.three_general_agent_target)
for item in self.three_actual_performance_ids:
if item.three_general_agent_actual not in three_target_agent and item.is_copy:
item.three_tranche_management_id_actual = None
删除方法只需要将其绑定的id置为None即可。
说得再多,不如尝试!
有更好的办法或疑问请
欢迎加入社群一起讨论哦⬇
本期作者
高级后端开发工程师 程欢