sale_renting_planning 很适合写“跨模块链路”,因为它不是简单把租赁订单和 planning 拼在一起,而是把两边做成双向回写:订单变,slot 跟着变;slot 变,订单也跟着改;资源缺了,还会重新挑资源。
主要参考源码:
enterprise/sale_renting_planning/models/planning_slot.pyenterprise/sale_renting_planning/models/sale_order.pyenterprise/sale_renting_planning/models/sale_order_line.py
一、建 rental order 时,可能先去对齐已有 shifts
sale.order.create() 在发现是租赁单后,会把已关联 slot 的起止时间对齐到 rental_start_date / rental_return_date,同时把无资源的 open shift 收集起来再 _set_slot_resource()。
也就是说,订单创建不是 planning 的终点,而是一次反向清洗动作。
二、订单改租期,会推回 slot
sale.order.write() 记录旧租期,再在 super 后找出仍匹配旧时间的 slot,把新起止时间写回去。这里用 rental_order_updated 和 slots_rescheduled 这样的上下文标记,避免订单与 slot 互相无限回写。
三、反过来,slot 改时间也会推回订单
planning.slot.write() 发现自己属于启用 role_sync_shift_rental 的租赁订单时,会重新聚合该订单所有 shift 的最早开始和最晚结束,再把结果写回销售单。
这一步非常关键:planning 并不是租赁订单的附属展示,而是可以反向定义整单租期的来源。
四、数量变成 0 或删行时,为什么还要删 slot
sale.order.line.write() 在租赁行数量归零时会删关联 slot,unlink() 也会这么做。否则订单里已经没有该租赁行,planning 侧却还挂着 shift,资源和计费口径都会漂。
五、结论
租赁排班不是“改一下 shift 时间”而已,而是planning slot、sale order、sale order line、resource assignment 四者一起联动。它解决的是谁来定义租期、谁来收回资源、谁是最后真相的问题。
DISCUSSION
评论区