odoo tree view dynamic column

ODOO列表视图动态列
由于框架模型限定了字段是需要事先定义的,也就是个数是确定的,对应成列表视图仅仅是显示或者不显示这些字段而已

时间横排

一些特殊的场景,比如工时单记录,根据项目在列表视图上一行行的填写工时就变得非常重复和多余,可惜官方没有改造列表视图使其获得通用能力,而是专门为之新开发了一个项目日期横排组件级视图,使得应用范围比较窄,多些固定列或者非时间动态列的情况下就无法直接使用了

尺码横排

一些行业的应用,比如服装行业的尺码横排,动态列一般是浮点型价格或者整型数量,而固定列除了颜色之外,一般还有批次、仓位、款式、订单等组合。前期也参考了工时单和Grid视图的优秀设计,甚至尝试基于其进行二次开发改良,但最终还是选择最普遍的原生列表视图为基础进行扩展,希望最终用户可以获得习惯一致的体验,同时也对经典视图深入发展多元化应用进行了一次实打实的尝试

odoo mail delivery integration

ODOO邮件发送集成
电子邮件这个场景在国外集成率非常高,国内则相对少很多。一是因为文化习惯,而且我们还有微信、钉钉;二是因为Mail模块是针对国际化普世标准设计的,如Gmail、Postfix,不太适合中国大部分中小企业还在用腾讯、网易企业邮箱服务的国情

所以新手在中国要完美使用邮件集成是折腾的,这里我们先将问题一分为二,按照顺序从发送开始说,理解透彻了发送模式对后续接收及分发原理会有一定的帮助

相关系统参数:
mail.bounce.alias(默认值bounce,无界面设置)
mail.catchall.domain(默认值odoo域名,可以在通用设置别名域里设置)

发送账号配置:
默认localhost用于本地自建smtp邮件发送服务器使用,如Postfix服务
一般配置成企业邮箱专门为之新建的一个ODOO账号,如odoo@renjie.me

发件名义原则:
1、系统邮件如新用户邀请、密码重置等以公司Email设置里的邮箱名义发送,如info@renjie.me
2、个人邮件如操作者自己的业务沟通,以用户对应的联系人Email设置里的邮箱名义发送,如i@renjie.me

三大发送模式:
1、简单发送(mail.catchall.domain不设置)
直接用发送账号发出,发件人需要与发送账号相同或者是其同一账号下的其他别名,否则会被邮件系统拒绝,如SMTPSenderRefused: 501 mail from address must be same as authorization user test@renjie.me。接收方也直接回复该真实地址,非常容易理解,属于最原始的模式,最适合做邮件通知这种只集成发送不用集成接收的情况

2、代理发送(mail.catchall.domain设置,mail.bounce.alias不设置)
间接用postmaster-odoo账号代发出,发送账号需要具有该名称授权,否则也会被邮件系统拒绝,如SMTPSenderRefused: 501 mail from address must be same as authorization user postmaster-odoo@renjie.me。接收方默认回复catchall专用地址,由于属于代发,且发件地址、代发地址、回复地址都可以不相同,第一次使用还会有些颠覆邮箱观,甚至某些客户端出于谨慎还会出现欺诈提醒,但这确是目前国内用的最多的务实模式,大部分教程都是以此展开详解

3、反弹发送(mail.catchall.domain设置,mail.bounce.alias设置)
间接用bounce地址代发出,如bounce+5-res.users-2@renjie.me或者bounce+5@renjie.me,其中+5为邮件流水号,-2为单据流水号,可见前者还是单据相关邮件,接收方也默认回复catchall专用地址,因为其涉及到邮件接收等相关知识,而且国内免费邮箱服务基本没有完美支持,本文将不深入探讨,待以后ODOO邮件接收集成的时候在讨论如何配合Postfix实现完美收发自如

odoo document management system

ODOO文档管理系统
自从开始玩上官方应用市场,一直坚持平均一个月推出一款应用,日积月累也慢慢形成了移动互联网流行的应用矩阵,同时也对海外客户的国际化需求和口味风格异同都有了不少的了解

今天突然发现上个月发布的一款文档管理系统今天已经进入下载排名十强,目前位于第八个的样子,这可是破记录了,因为之前最高也就是在第二页徘徊而已。曾经也羡慕过那些霸榜应用,现在看来只要坚持总会摸索到爆款痛点:)

论市场优秀应用,我认为至少要同步官方的节奏,不仅要支持最新的三个版本,更要兼容企业版,当然最重要的还是开源免费,而开发者所收获的则是国际的规范的扎实的基础能力

https://apps.odoo.com/apps/modules/10.0/document_management_system/
document_management_system

odoo web window title config app

ODOO浏览器窗口标题配置模块
前文odoo custom web window title已经讲解了基础原理,虽然代码很简洁易懂,但对非开发出身的odoo玩家使用还是有一些难度,而且不同版本可能还会有一些实施细节上的差异

整体开箱即用、细节精益求精是我毕生追求的odoo一体化目标,周末趁这个小机会将其一步到位适配成8、9、10三大主流版本全覆盖的模块,并已发布到odoo官方应用市场,支持在线自动安装,也可以下载相应的版本到本地进行传统手动安装

https://apps.odoo.com/apps/modules/8.0/web_window_title/
https://apps.odoo.com/apps/modules/9.0/web_window_title/
https://apps.odoo.com/apps/modules/10.0/web_window_title/

odoo-web-window-title-app

odoo form view document directory upload

ODOO表单视图文档目录上传
关于附件上传的可行性体验优化,目前国际上最多最成熟的方案都是扩展支持多选和拖拽两种方式,也能极大的改善ODOO原生的单附件上传模式
但是如果追求极致的话还可以扩展支持文档目录直接上传,一次选择操作就可以将目录里的所有文件全部上传,无论目录有多少层级多少子目录全部一网打尽

基础结构:file元素添加html5新特性

PS:一堆浏览器私有前缀属性仿佛又回到了IE多版本称霸年代:)

事件支持:odoo form view document multi upload
居然上次多选上传的代码直接支持,可见写的一手兼容未来代码的重要性

有图有真相:Linux都兼容,Win、Mac理论不在话下。。。

目录上传

目录上传选择

目录上传结果

参考资料:
https://docs.microsoft.com/en-us/microsoft-edge/dev-guide/html5/folder-upload
https://developer.mozilla.org/en-US/Firefox/Releases/50

odoo model import data ignore error

ODOO模块导入数据忽略错误
经常遇到大量的数据导入,不仅耗时很长,如果其中有一条数据有异常产生错误,就会导致整个过程回滚,这是非常悲剧的,其中相关源码如下:

明白核心代码处理逻辑后,就可以在外层拦截并过滤错误数据继续提交干净数据以实现自动纠错导入,实现源码如下:

odoo notify and warning client action

odoo后台接口如果出现错误可以简单抛出一个UserError异常给前端进行处理
但是有些时候可能只是一个通知或者警告给用户,不需要错误这么重的模态强交互,也不用影响主流程

从odoo8的addons/web/static/src/js/chrome.js源码中可以发现这个功能曾经拥有

本次以notify通知为例,其对应到odoo9之后的移植代码为:

相对应后台调用统一封装方法:

 

odoo form view document multi upload

odoo表单相关的附件文档如果过多,逐个本地选择上传也是一种负担,比较好的方式是适配现代H5浏览器文件选择对话框原生的多选功能,这可以大大提高多文件操作效率

基础结构:file元素添加multiple属性

事件支持:

odoo custom web window title

odoo窗口标题的修改方法有很多,但最灵活的还是后台开发者模式动态修改视图里的title,这就需要先搭一座便桥先:

上述是桥接视图方便随时修改,接着还需要将原生前端硬编码优雅的架构到一起

如果还想追求到极致的话,下一步就是再将其整合到res_config通用设置里,特别适合SAAS运营的场景:)

odoo form view pic url widget

原生表单视图的image组件只能使用binary类型字段存储本地图片,而互联网应用一般都使用cdn,如第三方的七牛云存储,其在odoo中的表现形式其实是一个char类型的url,并不会占用自身服务器的存储,这就需要量身为其定制一种外链图片的widget:

之后就可以在表单视图中直接使用诸如<field name=”pic_url” widget=”pic”/>形式的网络图片字段组件