odoo one2many2many mix field model

ODOO一对多对多混合字段模型
原生的One2many和Many2many已经可以解决大部分模型之间的关系映射,但在一些特殊场景下还是需要混合两者优点形成一个新的关系模型

odoo one2many2many mix field model

如生产制造相关的部件与工序:一个部件是由多个工序所组成,而其工序之间还有调整顺序等要求;一个工序可以在多个部件里的不同位置所引用,也可以在同一个部件里不同顺序多次引用

标准的一对多模型桥接做映射可以自定义明细行顺序、独立参数。缺点是只能一个个添加,无法直接打开被桥接的模型进行操作
标准的多对多模型直接做映射可以批量选择、直接编辑。缺点是不可重复且没有顺序及独立参数,后续基本没有可扩展的灵活性
混合的一对多对多模型则是结合上述两者各自优势进行互补以达到可用性层面的最佳用户体验

odoo12 new starting point

ODOO12新起点
终于迎来了12,也是传说中期待的双数版本号
去年这个时候是11,虽也惊喜,但毕竟是python2到3的过渡期,有历史责任包袱的产品还是需要双兼容,于是那个版本是从7持续以来第一个被忽视的版本
所以我们现在的感觉就如同当年还在Windows Mobile的odoo78910,因为专注取舍错过了整个Symbian过渡时期,然后一口气飞奔进入iOS/Android双雄争霸时代
这比喻也许有些夸张,但对定位为开源企业级应用操作系统的我们来说,还是比较合适的:)

随着新产品线开始全面拥抱odoo12已经一个月有余,目前各种感觉都很顺畅,真不愧是一个全新的高起点定制系统:
框架模式方面基本成型,落后的能淘汰的都淘汰了,缺陷的能优化的也都优化了,结构上开始趋向稳定,预计未来大版本升级会容易很多
数据库方面过去成熟稳定的PostgreSQL9低版本已经无法胜任,久违的ORM开始慢慢的启用了一些新特性,长远发展看pg10+要成为标配
XML视图方面更新了更为严谨的rng约束,各种元素及属性将不可随意添加或缺失,有效的规范了页面结构的整体质量
CSS样式方面预处理器由Less改成了与整体框架更为融洽的Scss,核心的Bootstrap库大版本也从经典的3升级到了最新的4,感觉表现层这系列折腾起码要稳定几年了
Python方面彻底进入3时代,以后可能还有一些3.7前后版本的对应兼容库问题,但总算是完全告别2时代了
JavaScript方面基本已经将odoo9以来奠定的框架基础改造至极限,虽不能说很完美,但这一路优化过来已属不易,二次可开发的地方也越多越完善,将来Hack代码的机会不多了

其他应用层面的变化太多就不一一列举了,这里就重点说一个原来的document模块要废弃了,其在表单顶部工具栏的文档附件管理已被底部的mail消息日志功能所整合替代。长远看这也是一个很好的改进,只是可惜了原来依赖该基础模块的一大波第三方模块要被迫转型升级。考虑到要适应多年以来形成的附件操作习惯突然改变,同时我们自己也有直接间接依赖的几十号各类模块需要以空间换时间的兼容使用,特此立项从12版本开始上架维护用于替代的Document Sidebar模块,该应用市场链接https://apps.odoo.com/apps/modules/12.0/document_sidebar/

document_sidebar

odoo integrated excel xls and xlsx file read write library

ODOO集成Excel xls和xlsx文件读写库
开源物以类聚角度LibreOffice Calc的ods格式是整合电子表格的最佳选择,但由于Excel尾大不掉还有着2003及之前xls格式和2007及之后xlsx格式的历史问题

存储:原生Binary字段是最合适的,但不管最终是文件存储还是数据库存储,程序上都是以base64库的encodestring编码和decodestring解码进行出入

前端:SheetJS库可以用来做附件和报表的预览应用及所见即所得数据的快速结构化导出

后端:xlrd+xlwt、XlsxWriter、OpenPyXL三大Python库各有所长又相互制衡反垄断,根据场景自由组合起来可以做各种类型复杂应用。StringIO和BytesIO可用于中转处理过程中的内存临时存储,避免了要生成和清理文件的麻烦

odoo list view dynamic row selection field

ODOO列表视图动态行选择字段
由于框架模型限定了选择字段是需要事先定义的,也就是选择下拉内容是确定且固定的,对应成列表视图则是每一行都是相同有限的选择

物料颜色和规格集

比如以上这种每一个物料都有自己的颜色和规格明细组合,这与odoo原生的产品变体刚好相反,后者是由产品属性及值自动生成所有排列组合的变体,前者则根据实际有限的明细反推出其属性集合

物料颜色规格选择

最后体现在一些行业应用中,比如鞋服箱包产品款式的BOM配色配码,其颜色尺码的表头是由产品基础属性组成动态列,而颜色规格的配置行则是根据所选物料的不同集合来动态限定范围选择列,间接实现每一行的Many2one和Selection字段都是独立定义

odoo wechat user info sync issue

ODOO微信用户信息同步问题
Python使用http高级requests库来对接微信开放平台和公众平台非常干净利落,主要两个小问题需要注意一下:

1、用户昵称乱码
正常拉取用户信息所返回的内容编码不太友好,读取时乱码,需要显式设定lang和encoding

2、用户头像时效
如只保存头像链接,若用户更换头像,原有链接将失效,需要用Binary字段存储一份图片二进制base64编码的副本

odoo form view action edit mode open

ODOO表单视图动作编辑模式打开
表单有两种模式,分别是view浏览和edit编辑,一般通过动作跳转的默认都是浏览模式,需要额外点击编辑按扭切换成编辑模式,对一些要求快速编辑的场景来说显得有些多余

ODOO10截止目前的版本已经可以直接通过action flags对象来透传initial_mode参数,具体用法如下:

早期的版本虽然不支持,但是对于dict类型来说,也是可以通过return透传给前端拿到,只需额外添加一个通用的桥接口中转下即可:

odoo tree view dynamic column

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

时间横排

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

尺码横排

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

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 model import data ignore error

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

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