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