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

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

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

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

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



  • 1、OE7计算产品的可用库存和预测库存时,会将所有出入仓单数据调出来进行汇总。在生产环境,小型工厂一天出入仓单也有30-50张,一年下来超过一万张。稍大一点的工厂超过十万张。虽然单个产品出入仓数未必有这么多,但每次查看产品列表时调出这么庞大的数据进行运算,性能可想而知。如果不采用这个方法,而是在数据库端采用触发器进行计算,则不必每次查看产品资料时重新计算。

    2、数量和金额字段类型绝大部分采用 double precision(双精度浮点数) 而不是 numeric 或 decimal,导致计算结果小数部分不精确,容易造成借贷不平衡。

    以上两点可说是OE的硬伤,老外也在吐槽。不知道有什么办法改进。



  • 1、OE7计算产品的可用库存和预测库存时,会将所有出入仓单数据调出来进行汇总。在生产环境,小型工厂一天出入仓单也有30-50张,一年下来超过一万张。稍大一点的工厂超过十万张。虽然单个产品出入仓数未必有这么多,但每次查看产品列表时调出这么庞大的数据进行运算,性能可想而知。如果不采用这个方法,而是在数据库端采用触发器进行计算,则不必每次查看产品资料时重新计算。

    2、数量和金额字段类型绝大部分采用 double precision(双精度浮点数) 而不是 numeric 或 decimal,导致计算结果小数部分不精确,容易造成借贷不平衡。

    以上两点可说是OE的硬伤,老外也在吐槽。不知道有什么办法改进。



  • 问题1 还没测试,但是也比较担心


    问题2 确实是硬伤,不知道应该怎么改进一下。



  • 这事是 tryton 的人搞出来的,我来回答一下:

    1、OE 中的库存计算之前和校长、joshua 讨论过,OE 计算库存代码是:

    def get_product_available(self, cr, uid, ids, context=None):
    .........
    # TODO: perhaps merge in one query.
            if 'in' in what:
                # all moves from a location out of the set to a location in the set
                cr.execute(
                    '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 +
                    'group by product_id,product_uom',tuple(where))
                results = cr.fetchall()
            if 'out' in what:
                # all moves from a location in the set to a location out of the set
                cr.execute(
                    '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 +
                    'group by product_id,product_uom',tuple(where))
                results2 = cr.fetchall()

    可以看到是 select sum(product_qty) 直接计算出来的。

    而 tryton 的做法是引入了 stock.period 和 stock.period.cache 模型,计算的代码在

        def products_by_location(cls, location_ids, product_ids=None,
              .........
                periods = Period.search([
                        ('date', '<', context['stock_date_end']),
                        ], order=[('date', 'DESC')], limit=1)
                if periods:
                    period, = periods
                    state_date_clause += (' AND '
                        '(COALESCE(effective_date, planned_date) > %s)')
                    state_date_vals.append(period.date)
                    period_vals[0] = period.id
    .........

    代码就不一一解释了,
    stock.period 定义了一个库存时间戳,可以理解为日结
    stock.period.cache则记录了某个时间戳下产品数量

    这样 tryton 计算库存的时候就无需把 stock.move 从头到尾计算一边,只需要取日结产品数量和未结的stock.move 进行计算即可。

    OE 的可能改进的地方可以参考 tryton 的做法,或是自行对产品数量进行日结,计算时就无需全部计算。

    2.  关于 double precision.
    OE 这个的确没法改了,或者说因为涉及到底层ORM设计,修改的难度更大。估计这个是历史原因造成的吧
    而 TRYTON 是从新设计,底层上就在去的是 decimal 字段。

    不过,尽管OE 难以改进,不过OE本身也提供了 tools/float_utils.py 模块,里面提供了很多实用函数:
    如 float_compare float_is_zero 等函数,虽然很变态,不过应该还是够用。


    结论:
    问题1、可以改。
    问题2、认命吧。



  • 步科连tryton的对比代码都找到了,牛!

    1、日结也是一种变通解决方案。但做日结的限制也多,做完日结后,就不能改先前的单了,也不能补录先前日期的单。如果能在数据库端采用触发器来计算这两个值,其可靠性会好很多。

    2、能否在数据库端直接修改表,把这字段类型改为 decimal 类型?



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


登录后回复
 

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