未分类资料教程

康虎云报表与odoo整合示例

康虎云报表与odoo整合,实现odoo报表精准输出,复杂报表快速开发,这个任务我筹划很久了,也已经拖了很久了,昨天终于抽出时间给一班兄弟讲解了一下,讲的过程中气氛还不错,可惜的是录视频时,声音没录下来,成了哑剧。这两天要抽时间再录一段。
康虎云报表与odoo集成,原理其实很简单,就是在odoo原有报表基础上或者新建报表,把原来用QWeb输出的报表内容,转换成符合康虎云报表的json数据。在这个转换过程中,如果是简单字段,是很方便的,用<t t-esc=”…”>即可输出不带html标签的数值;而对于one2many、many2many等关联字段,最简便的办法就是利用Qweb引擎自身的功能把关联字段值取出来,即t-field标签。但t-field标签有个问题,它生成的值带有多重HTML标签,不仅容易造成json出现语法错误,也不易在康虎云报表中使用,因此如何生成不带HTML标签的值(姑且称之为 raw值)是转换的关键。
通过对QWeb底层渲染机制的研究,想出一种办法,在字段值最终输出前调用自定义函数移除HTML标签,只保留内容,目前这个功能已经做成通用功能,内置在 cfprint这个模块中,要在odoo中使用康虎云报表,需要先安装这个模块。然后对Qweb报表进行简单改造,插入生成json的代码。这次使用的是对仓库收货功能的一个小扩展,打印“入库核对单”,即仓管在收货前先打印“入库核对单”,然后根据核对单上的商品一个个清点,把实际清点的数据填写到表格里,在然后在odoo收货单里填上实际收货数量。
如何开发一个odoo模块并创建一个QWeb报表就不赘述了,大家自己去网上搜索,这里只贴出对Qweb报表的改造部分。在QWeb报表代码中,在模板底部找到

</template>

标签,然后在该标签上一行插入如下的代码:

<!--必须先安装cfprint模块,以引入基础类库-->
<script type="text/javascript">
var cfprint_addr = "127.0.0.1";   //打印服务器监听地址
var _delay_close = -1;          //打印完成后关闭窗口的延时时长(毫秒), -1则表示不关闭
var _tablePack = {
    "Name": "Pack",
    "Cols":[
        { "type": "str", "size": 255, "name": "仓库", "required": false },
        { "type": "str", "size": 50, "name": "供应商", "required": false },
        { "type": "str", "size": 30, "name": "日期", "required": false },
        { "type": "str", "size": 255, "name": "入库单号", "required": false },
        { "type": "str", "size": 30, "name": "采购单号", "required": false },
        { "type": "int", "size": 0, "name": "件数", "required": false },
        { "type": "str", "size": 20, "name": "包装种类", "required": false },
        { "type": "str", "size": 30, "name": "车号", "required": false },
        { "type": "str", "size": 30, "name": "柜号", "required": false }
    ],
    "Data":[ ]
};

var _tablePackLines = {
    "Name": "PackLines",
    "Cols":[
        { "type": "str", "size": 30, "name": "入库单号", "required": false },
        { "type": "str", "size": 255, "name": "产品", "required": false },
        { "type": "str", "size": 30, "name": "条形码", "required": false },
        { "type": "float", "size": 0, "name": "采购数量", "required": false },
        { "type": "float", "size": 0, "name": "实际数量", "required": false },
        { "type": "str", "size": 20, "name": "计量单位", "required": false },
    ],
    "Data":[ ]
};

<t t-foreach="docs" t-as="o">
/*生成主表数据*/
_tablePack.Data.push(
{
    "仓库":"<span t-field="o.picking_type_id.warehouse_id.partner_id" t-field-options='{"widget": "contact", "fields": ["name"], "no_marker": true, "no_tag_br": true, "data_type": "raw"}' />",
    "供应商":"<t t-if="o.partner_id" name="partner_header"><span t-field="o.partner_id" t-field-options='{"widget": "contact", "fields": ["name"], "no_marker": true, "no_tag_br": true, "data_type": "raw"}' /></t>",
    "日期":"<t t-esc="context_timestamp(datetime.datetime.now()).strftime('%Y-%m-%d %H:%M')"/>",
    "入库单号":"<t t-esc="o.name" class="mt0"/>",
    "采购单号":"<t t-if="o.origin"><t t-esc="o.origin"/></t>",
    "件数":"<t t-esc="sum(pack_operation.product_qty for pack_operation in o.pack_operation_ids)"/>",
    "包装种类":"",
    "车号":"",
    "柜号":""
});
    <t t-foreach="o.pack_operation_ids" t-as="pack_operation">
/*生成从表数据*/
_tablePackLines.Data.push(
{
    "入库单号":"<t t-esc="o.name" class="mt0"/>",
    "产品":"<span t-field="pack_operation.product_id" t-options='{"data_type":"raw"}'/>",
    "条形码":"<t t-if="pack_operation.product_id and pack_operation.product_id.barcode"><span t-field="pack_operation.product_id.barcode" t-field-options='{"data_type":"raw"}'/></t>",
    "采购数量":"<t t-esc="pack_operation.product_qty"/>",
    "实际数量":"",
    "计量单位":"<span t-field="pack_operation.product_uom_id" t-options='{"data_type":"raw"}'/>"
});
    </t>
</t>
/*数据合并到总的数据对象*/
var _data = {"template": "warehouse_checklist.fr3", "ver": 4, "Copies": 1, "Duplex": 0, "Tables":[]};
_data["Tables"].push(_tablePack);
_data["Tables"].push(_tablePackLines);
var _reportData = JSON.stringify(_data);  //转成json字符串

console.log(_reportData);
//生成数据之后,在cfprint_ext.js中会自动调用进行打印

</script>

细心的用户可能会发现,在

<span t-field="pack_operation.product_id" t-options='{"data_type":"raw"}'/>"

里有一个t-options='{“data_type”:”raw”}’,这正是我们对t-field标签的扩展,以输出raw值。
在QWeb报表中插入上面代码之后,还需要把报表类型由pdf改为html才可以。具体是在报表定义中进行修改(也可以通过界面修改,不过通过界面修改的话,重装或升级模块报表类型就恢复成PDF了)。具体修改如下:

<report
    string="Warehouse Checklist"
    id="action_report_warehouse_checklist"
    model="stock.picking"
    report_type="qweb-html"                          ###这个地方由qweb-pdf改成为 qweb-html
    name="stock_cf.report_warehouse_checklist"
    file="stock_cf.report_warehouse_checklist"
/>

改造完成后,把康虎云报表解压到任意目录(例如:康虎云报表系统_ver1.3.7.3),运行cfprint\cfprint.exe程序并保持运行状态。把预先设计好的报表模板(stock_cf\cfprint_template\warehouse_checklist.fr3)复制到康虎云报表安装目录(cfprint.exe所在目录)。
重新安装或升级stock_cf模块,然后进入仓库管理,如果有待收货记录,选择一条收货记录(如果没有,就新建一个采购订单并确认),然后按“打印”–>“入库核对单”,如果不出意外,康虎云报表就会接收到打印请求并向打印机输出报表。如果没有输出,建议打开浏览器的javascript控制台,看看有什么出错信息,并根据出错信息进行修改除错。
以上就是康虎云报表与odoo的整合工作,以后就只需要按此步骤操作即可。

另外附上两个示例的程序包(里面带康虎云报表1.3.7.3版,可以永久免费使用):

康虎云报表与odoo10整合基础模块及示例.zip
康虎云报表与odoo8集成基础模块及示例.zip

发表评论

邮箱地址不会被公开。 必填项已用*标注