其他深度

Odoo 车队为什么不只是“车辆台账”:司机历史、里程读数与合同提醒链路讲透

很多人把 Odoo Fleet 当成资产卡片,但源码里的 vehicle、assignation log、odometer 和 contract 其实组成了一条持续更新的运营链。看懂这条链,才能真正用 Odoo 管住司机交接、保单续期和车辆成本节奏。

其他
进阶 开发者 2 分钟阅读
0 评论 0 点赞 0 收藏 5 阅读

先说结论

Odoo Fleet 不是一套“把车录进系统里”的静态台账,而是一套围绕车辆生命周期持续刷新的运营模型。

/home/ubuntu/odoo-temp/addons/fleet/models/fleet_vehicle.pyfleet_vehicle_log_contract.pyfleet_vehicle_assignation_log.py 来看,官方实际把四条链绑在了一起:

  • 车辆主档与车型参数继承
  • 司机当前归属与历史交接记录
  • 里程表持续采集与统计
  • 合同状态变化、到期提醒与自动调度

所以它真正解决的问题不是“公司有几辆车”,而是:

每台车现在归谁、跑了多少、有哪些服务与合同还在生效,以及哪些风险即将发生。


第一层:为什么车辆名称本身就在提示“这不是静态资产卡”

fleet.vehiclename 不是人工手填主键,而是由:

  • 品牌
  • 车型
  • 车牌

组合计算出来。

这一点看似普通,其实很有代表性。

它说明 Odoo 不鼓励把车辆当成一条孤立资产编号,而是强调车辆在运营里最常被识别的自然键。

同时,车辆上还挂着:

  • driver_id
  • future_driver_id
  • manager_id
  • location
  • state_id
  • contract_renewal_due_soon
  • service_activity
  • odometer

这些字段摆在一起,就能看出官方的视角并不是资产盘点,而是日常运营看板。

你打开一台车,最该先知道的通常也是:

  • 现在谁在用
  • 接下来谁会接手
  • 是否快到续约期
  • 服务有没有逾期
  • 当前最新里程是多少

第二层:为什么当前司机和司机历史必须分开

fleet.vehicle 上有当前的 driver_id,同时又有一张独立的 fleet.vehicle.assignation.log

  • vehicle_id
  • driver_id
  • date_start
  • date_end

这说明 Odoo 明确区分了:

  • 当前归属状态
  • 历史交接轨迹

很多企业最开始做车队管理时,只在车辆卡片上改一个“当前司机”。 短期内看似够用,长期一定出问题:

  • 谁在什么时间段用过这台车,追不回去
  • 出险、违章、油耗异常很难追责
  • 车辆交接频率和使用负载无法分析

独立 assignation log 的价值就在这里。

它让“司机变更”不只是覆盖旧值,而是留下时段历史。 这对于公务车、共享车、销售用车、项目驻场车都非常关键。


第三层:里程为什么不直接改字段,而是通过 log 写入

fleet.vehicle.odometer 没在这次展开的文件里完整展示,但 fleet.vehicle 已经把设计意图说得很清楚:

  • 车辆上有一个计算字段 odometer
  • _get_odometer() 读取历史里程记录里的最新值
  • _set_odometer() 不是覆盖旧值,而是创建一条新的 odometer 记录

这套设计很专业。

因为里程不是“车辆现在的一个属性”,而是一串时间序列数据。

如果只是把当前值改成 42851 km,你会失去:

  • 何时录入的
  • 当时是谁的车
  • 里程上升速度
  • 是否存在异常跳变

而通过日志化写入,里程才能参与更多管理:

  • 保养周期判断
  • 使用强度分析
  • 成本分摊
  • 异常油耗与异常使用排查

也就是说,车辆页显示的 odometer 只是日志的投影结果


第四层:合同为什么是单独的运营对象,而不是附件

fleet.vehicle.log.contract 不是“给车辆挂个 PDF”。 它本身就是一张业务表,带着:

  • start_date
  • expiration_date
  • days_left
  • expires_today
  • state
  • cost_generated
  • cost_frequency
  • insurer_id
  • user_id

这意味着 Odoo 把保险、租赁、服务协议等合同看成可持续追踪、可提醒、可变化状态的对象。

尤其 write()scheduler_manage_contract_expiration() 很值得注意。

系统会根据日期自动把合同切成:

  • futur
  • open
  • expired
  • closed

同时:

  • 快到期时给负责人创建活动提醒
  • 已过期时自动改状态
  • 未来合同到了起始日自动转成 running

这说明合同在 Odoo Fleet 里不是“备案信息”,而是运营节奏的一部分。


第五层:为什么续约提醒会先落到车辆维度

fleet.vehicle 上有:

  • contract_renewal_due_soon
  • contract_renewal_overdue
  • contract_state

这些字段并不是手填,而是根据车辆所有未关闭合同聚合计算出来。

这一步很关键,因为运营团队日常不会一条条先看合同表,他们首先看的是车辆清单。

也就是说,Odoo 做了两层表达:

合同表负责细节

  • 哪份合同什么时候开始
  • 谁负责
  • 哪家供应商
  • 哪种费用频率

车辆表负责摘要

  • 这台车有没有续约风险
  • 当前最重要的合同状态是什么

这才符合实际使用习惯。

否则系统虽然记录得很全,但真正有风险的车不会自动浮出来。


第六层:车型字段自动下沉,说明车辆主档并不想重复维护

fleet.vehicle 里,大量字段都是从 model_id 自动带下来:

  • transmission
  • fuel_type
  • seats
  • doors
  • power
  • horsepower
  • co2
  • category_id
  • range_unit

这说明 Odoo 很清楚,车型级事实和车辆级事实应当分层。

车型级事实

  • 这个型号通常几门几座
  • 默认燃料、排放和动力参数是什么

车辆级事实

  • 这辆具体车现在给谁开
  • 当前状态、位置、里程是多少
  • 合同和服务记录怎样

这种“模型默认、车辆承接”的分层设计,能显著减少车队主档维护成本。


第七层:服务活动和合同提醒为什么都是“运营信号”

service_activity 会从 service log 的 activity state 汇总出:

  • none
  • today
  • overdue

再加上合同提醒、里程计数、历史司机数量,车辆卡片实际上已经具备了一个轻量“风险面板”。

这意味着 Odoo Fleet 最合适的使用方式,并不是把它当档案柜,而是当持续更新的监控台。

当一台车出现以下信号时,管理员应当立刻注意:

  • 续约即将到期
  • 服务活动 overdue
  • 司机频繁交接
  • 里程增长异常快

这些信号彼此叠加,往往比任何单一字段更能说明问题。


最容易误解的三个点

误区一:Fleet 就是录车辆基础信息

不对。那只是最浅的一层,真正有价值的是车辆与司机、里程、合同、活动的联动。

误区二:当前司机够用了,不需要历史

错。只要车会换人,历史交接就不是可选项。

误区三:合同只要上传附件备查

也不够。没有状态、提醒和活动调度,系统就不能真正承担续期管理。


实战上怎么把 Fleet 用顺

推荐按这个顺序搭:

  1. 先把车型层数据整理好,让车辆能自动继承基础参数
  2. 车辆主档维护当前司机、位置和状态
  3. 任何司机交接都落 assignation log,而不是只改当前司机
  4. 里程录入坚持日志化,别直接覆盖“最新值”
  5. 合同由独立对象维护起止日、责任人和供应商
  6. 用车辆视图盯 due soon / overdue,而不是等合同到期后被动补救

最后一句话

Odoo Fleet 最值得重视的地方,不是它能存车辆资料,而是它把司机关系、里程序列和合同时间轴都汇到同一台车上。

所以理解这套模块最好的方式不是“车辆台账”,而是:

它是一套以车辆为中心的持续运营系统。

DISCUSSION

评论区

想参与讨论?先 登录 再发表评论。
还没有评论,你可以成为第一个留言的人。