跳转至内容
  • 版块
  • 标签
  • 热门
  • 用户
  • 群组
皮肤
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • 默认(Flatly)
  • 不使用皮肤
折叠

Odoo 中文社区

  1. 主页
  2. 版块
  3. Odoo 开发与实施交流
  4. OE7的严重缺陷,有什么办法改进?

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

已定时 已固定 已锁定 已移动 Odoo 开发与实施交流
6 帖子 4 发布者 4.2k 浏览
  • 从旧到新
  • 从新到旧
  • 最多赞同
登录后回复
此主题已被删除。只有拥有主题管理权限的用户可以查看。
  • S 离线
    S 离线
    stephenl
    写于 最后由 编辑
    #1

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

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

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

    1 条回复 最后回复
    0
    • C 离线
      C 离线
      ccdos
      写于 最后由 编辑
      #2

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


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

      1 条回复 最后回复
      0
      • W 离线
        W 离线
        wangbuke
        写于 最后由 编辑
        #3

        这事是 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、认命吧。

        1 条回复 最后回复
        0
        • S 离线
          S 离线
          stephenl
          写于 最后由 编辑
          #4

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

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

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

          1 条回复 最后回复
          0
          • N 离线
            N 离线
            netice
            写于 最后由 编辑
            #5

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

            1 条回复 最后回复
            0

            • 登录

            • 没有帐号? 注册

            • 登录或注册以进行搜索。
            • 第一个帖子
              最后一个帖子
            0
            • 版块
            • 标签
            • 热门
            • 用户
            • 群组