Odoo中文社区可以通过以下三个域名访问:shine-it.net , odoocn.org,odoo.net.cn

原论坛用户的基本信息和发帖这里都予以保留,请注意:原论坛用户无需重新注册新用户,但是您的密码需要重置

开发人员可以登录gitter讨论组: http://gitter.im/odoo-china/Talk, 需要github账号

如果您登录系统碰到问题,请在微信公众号留言:

OE7的严重缺陷,有什么办法改进?



  • 1、OE7计算产品的可用库存和预测库存时,会将所有出入仓单数据调出来进行汇总。在生产环境,小型工厂一天出入仓单也有30-50张,一年下来超过一万张。稍大一点的工厂超过十万张。虽然单个产品出入仓数未必有这么多,但每次查看产品列表时调出这么庞大的数据进行运算,性能可想而知。如果不采用这个方法,而是在数据库端采用触发器进行计算,则不必每次查看产品资料时重新计算。<br /><br />2、数量和金额字段类型绝大部分采用 double precision(双精度浮点数) 而不是 numeric 或 decimal,导致计算结果小数部分不精确,容易造成借贷不平衡。<br /><br />以上两点可说是OE的硬伤,老外也在吐槽。不知道有什么办法改进。



  • 1、OE7计算产品的可用库存和预测库存时,会将所有出入仓单数据调出来进行汇总。在生产环境,小型工厂一天出入仓单也有30-50张,一年下来超过一万张。稍大一点的工厂超过十万张。虽然单个产品出入仓数未必有这么多,但每次查看产品列表时调出这么庞大的数据进行运算,性能可想而知。如果不采用这个方法,而是在数据库端采用触发器进行计算,则不必每次查看产品资料时重新计算。<br /><br />2、数量和金额字段类型绝大部分采用 double precision(双精度浮点数) 而不是 numeric 或 decimal,导致计算结果小数部分不精确,容易造成借贷不平衡。<br /><br />以上两点可说是OE的硬伤,老外也在吐槽。不知道有什么办法改进。



  • 问题1 还没测试,但是也比较担心<br /><br /><br />问题2 确实是硬伤,不知道应该怎么改进一下。



  • 这事是 tryton 的人搞出来的,我来回答一下:<br /><br />1、OE 中的库存计算之前和校长、joshua 讨论过,OE 计算库存代码是:<br /><br /> def get_product_available(self, cr, uid, ids, context=None):<br />.........<br /># TODO: perhaps merge in one query.<br />        if 'in' in what:<br />            # all moves from a location out of the set to a location in the set<br />            cr.execute(<br />                'select sum(product_qty), product_id, product_uom '<br />                'from stock_move '<br />                'where location_id NOT IN %s '<br />                'and location_dest_id IN %s '<br />                'and product_id IN %s '<br />                'and state IN %s ' + (date_str and 'and '+date_str+' ' or '') +' '<br />                + prodlot_clause + <br />                'group by product_id,product_uom',tuple(where))<br />            results = cr.fetchall()<br />        if 'out' in what:<br />            # all moves from a location in the set to a location out of the set<br />            cr.execute(<br />                'select sum(product_qty), product_id, product_uom '<br />                'from stock_move '<br />                'where location_id IN %s '<br />                'and location_dest_id NOT IN %s '<br />                'and product_id  IN %s '<br />                'and state in %s ' + (date_str and 'and '+date_str+' ' or '') + ' '<br />                + prodlot_clause + <br />                'group by product_id,product_uom',tuple(where))<br />            results2 = cr.fetchall()<br /><br />可以看到是 select sum(product_qty) 直接计算出来的。<br /><br />而 tryton 的做法是引入了 stock.period 和 stock.period.cache 模型,计算的代码在<br /><br />    def products_by_location(cls, location_ids, product_ids=None,<br />          .........<br />            periods = Period.search([<br />                    ('date', '<', context['stock_date_end']),<br />                    ], order=[('date', 'DESC')], limit=1)<br />            if periods:<br />                period, = periods<br />                state_date_clause += (' AND '<br />                    '(COALESCE(effective_date, planned_date) > %s)')<br />                state_date_vals.append(period.date)<br />                period_vals[0] = period.id<br />.........<br /><br />代码就不一一解释了,<br />stock.period 定义了一个库存时间戳,可以理解为日结<br />stock.period.cache则记录了某个时间戳下产品数量<br /><br />这样 tryton 计算库存的时候就无需把 stock.move 从头到尾计算一边,只需要取日结产品数量和未结的stock.move 进行计算即可。<br /><br />OE 的可能改进的地方可以参考 tryton 的做法,或是自行对产品数量进行日结,计算时就无需全部计算。<br /><br />2.  关于 double precision.<br />OE 这个的确没法改了,或者说因为涉及到底层ORM设计,修改的难度更大。估计这个是历史原因造成的吧<br />而 TRYTON 是从新设计,底层上就在去的是 decimal 字段。<br /><br />不过,尽管OE 难以改进,不过OE本身也提供了 tools/float_utils.py 模块,里面提供了很多实用函数:<br />如 float_compare float_is_zero 等函数,虽然很变态,不过应该还是够用。<br /><br /><br />结论:<br />问题1、可以改。<br />问题2、认命吧。



  • 步科连tryton的对比代码都找到了,牛!<br /><br />1、日结也是一种变通解决方案。但做日结的限制也多,做完日结后,就不能改先前的单了,也不能补录先前日期的单。如果能在数据库端采用触发器来计算这两个值,其可靠性会好很多。<br /><br />2、能否在数据库端直接修改表,把这字段类型改为 decimal 类型?



  • 2.数据库改decimal没用的,SERVER是python写的,类型转换成python 的float做运算。除非使用python的decimal模块重写所有server端的计算,否则没效果。


登录后回复
 

与 Odoo 中文社区 的连接断开,我们正在尝试重连,请耐心等待