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

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

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

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

Mrp.py 中 action_confirm 的一个疑似bug



  • 晕 ,是我看错了.  谢谢 jeff
    上海-gavin 的跟帖很好 ,这帖子就留着吧

    ==============================
    今天读 mrp.py 的 action_confirm

    [code]
        def action_confirm(self, cr, uid, ids, context=None):
            """ Confirms production order.
            @return: Newly generated Shipment Id.
            """
            shipment_id = False
            wf_service = netsvc.LocalService("workflow")
            uncompute_ids = filter(lambda x:x, [not x.product_lines and x.id or False for x in self.browse(cr, uid, ids, context=context)])
            self.action_compute(cr, uid, uncompute_ids, context=context)
            for production in self.browse(cr, uid, ids, context=context):
                shipment_id = self._make_production_internal_shipment(cr, uid, production, context=context)
                produce_move_id = self._make_production_produce_line(cr, uid, production, context=context)

                # Take routing location as a Source Location.
                source_location_id = production.location_src_id.id
                if production.bom_id.routing_id and production.bom_id.routing_id.location_id:
                    source_location_id = production.bom_id.routing_id.location_id.id

                for line in production.product_lines:
                    consume_move_id = self._make_production_consume_line(cr, uid, line, produce_move_id, source_location_id=source_location_id, context=context)
                    shipment_move_id = self._make_production_internal_shipment_line(cr, uid, line, shipment_id, consume_move_id,<br />                                destination_location_id=source_location_id, context=context)
                    self._make_production_line_procurement(cr, uid, line, shipment_move_id, context=context)

                wf_service.trg_validate(uid, 'stock.picking', shipment_id, 'button_confirm', cr)
                production.write({'state':'confirmed'}, context=context)
            return shipment_id
    [/code]
    下面这句, 应该是创建一个 picking , 为 mo 领料.
        shipment_id = self._make_production_internal_shipment(cr, uid, production, context=context)


    我感觉应该 是为当前mo 创建 一个picking 即可, 不应该放在 循环内的.

          shipment_id = self._make_production_internal_shipment(cr, uid, production, context=context)

    而且  方法_make_production_internal_shipment 最后有一句 

    [code]        production.write({'picking_id': picking_id}, context=context)
    [/code]

    显然是将 picking 关联到了 mo .

    大牛们 看看, 是不是应该把
          shipment_id = self._make_production_internal_shipment(cr, uid, production, context=context)
    这行 放在 循环外面 ?



  • 晕 ,是我看错了.  谢谢 jeff
    上海-gavin 的跟帖很好 ,这帖子就留着吧

    ==============================
    今天读 mrp.py 的 action_confirm

    [code]
        def action_confirm(self, cr, uid, ids, context=None):
            """ Confirms production order.
            @return: Newly generated Shipment Id.
            """
            shipment_id = False
            wf_service = netsvc.LocalService("workflow")
            uncompute_ids = filter(lambda x:x, [not x.product_lines and x.id or False for x in self.browse(cr, uid, ids, context=context)])
            self.action_compute(cr, uid, uncompute_ids, context=context)
            for production in self.browse(cr, uid, ids, context=context):
                shipment_id = self._make_production_internal_shipment(cr, uid, production, context=context)
                produce_move_id = self._make_production_produce_line(cr, uid, production, context=context)

                # Take routing location as a Source Location.
                source_location_id = production.location_src_id.id
                if production.bom_id.routing_id and production.bom_id.routing_id.location_id:
                    source_location_id = production.bom_id.routing_id.location_id.id

                for line in production.product_lines:
                    consume_move_id = self._make_production_consume_line(cr, uid, line, produce_move_id, source_location_id=source_location_id, context=context)
                    shipment_move_id = self._make_production_internal_shipment_line(cr, uid, line, shipment_id, consume_move_id,<br />                                destination_location_id=source_location_id, context=context)
                    self._make_production_line_procurement(cr, uid, line, shipment_move_id, context=context)

                wf_service.trg_validate(uid, 'stock.picking', shipment_id, 'button_confirm', cr)
                production.write({'state':'confirmed'}, context=context)
            return shipment_id
    [/code]
    下面这句, 应该是创建一个 picking , 为 mo 领料.
        shipment_id = self._make_production_internal_shipment(cr, uid, production, context=context)


    我感觉应该 是为当前mo 创建 一个picking 即可, 不应该放在 循环内的.

          shipment_id = self._make_production_internal_shipment(cr, uid, production, context=context)

    而且  方法_make_production_internal_shipment 最后有一句 

    [code]        production.write({'picking_id': picking_id}, context=context)
    [/code]

    显然是将 picking 关联到了 mo .

    大牛们 看看, 是不是应该把
          shipment_id = self._make_production_internal_shipment(cr, uid, production, context=context)
    这行 放在 循环外面 ?



  • 看错了?所在循环用于遍历MO啊,每个循环内确定一个生产订单,对应创建一个picking,我这边不觉得有问题啊。



  • 哈哈 我也重构过这块的代码!!我还是放在循环里面的 我_make

    _production_consume_line 方法被我返回成数组了

    [code]
    class mrp_fresh(osv.osv):
        _inherit='mrp.production'

        def _make_production_consume_line(self, cr, uid, production_line, parent_move_id, source_location_id=False, context=None):
            stock_move = self.pool.get('stock.move')
            production = production_line.production_id
            # Internal shipment is created for Stockable and Consumer Products
            if production_line.product_id.type not in ('product', 'consu'):
                return False
            destination_location_id = production.product_id.property_stock_production.id
            if not source_location_id:
                source_location_id = production.location_src_id.id
           
            #TODO 自动选择批次号 先入先出
            production_lot = self.pool.get('stock.production.lot')
           
            #查询该商品所有的批次号信息,是根据批次号的排序查询
            ids = production_lot.search(cr,uid,[('product_id','=',production_line.product_id.id)])
            objects = production_lot.browse(cr,uid,ids)
            temp_new = []
            move_state = ['assigned','waiting']
            #需求要的数量
            use_quantity = production_line.product_qty
            #下面查找符合条件的批次号
            for obj in objects:
                prodlot_id = obj.id
                #查询该批次号  的商品 所有的待生产  未投料的 数量
                cr.execute('select sum(product_qty) from stock_move where (state IN %s) and product_id =%s and prodlot_id =%s',(tuple(move_state),production_line.product_id.id,prodlot_id))
                res = cr.fetchone()
                # 已有的生产单的在本批次号中 商品数量  和 本次要的数量 总和
                #等待生产的数量
                user_quantity = (res and res[0] and int(res[0])) or 0
                #需求总量
                def_quantity = obj.stock_available - user_quantity
                if def_quantity >=use_quantity:#如果需求的数量直接就被该批次满足了情况
                    temp_new.append({'prodlot_id':prodlot_id,'quantity':use_quantity})
                    break
                else :
                    temp_new.append({'prodlot_id':prodlot_id,'quantity':def_quantity})
                    use_quantity -= def_quantity
            move_ids = []
            all_quantity = 0
            for temp in temp_new:
                all_quantity+=int(temp['quantity'])
           
            if int(production_line.product_qty - all_quantity)>0:
                temp_new.append({'prodlot_id':None,'quantity':int(production_line.product_qty - all_quantity)})

            for new in temp_new:
                move_id = stock_move.create(cr, uid, {
                    'name': production.name,
                    'date': production.date_planned,
                    'product_id': production_line.product_id.id,
                    #'product_qty': production_line.product_qty,
                    'product_qty': new['quantity'],
                    'product_uom': production_line.product_uom.id,
                    'product_uos_qty': production_line.product_uos and production_line.product_uos_qty or False,
                    'product_uos': production_line.product_uos and production_line.product_uos.id or False,
                    'location_id': source_location_id,
                    'location_dest_id': destination_location_id,
                    'move_dest_id': parent_move_id,
                    'state': 'waiting',
                    #'prodlot_id':prodlot_id,
                    'prodlot_id':new['prodlot_id'],
                    'company_id': production.company_id.id,
                })
                production.write({'move_lines': [(4, move_id)]}, context=context)
                move_ids.append(move_id)
            return move_ids
       
       
        def action_confirm(self, cr, uid, ids, context=None):
            """ Confirms production order.
            @return: Newly generated Shipment Id.
            """
            shipment_id = False
            wf_service = netsvc.LocalService("workflow")
            uncompute_ids = filter(lambda x:x, [not x.product_lines and x.id or False for x in self.browse(cr, uid, ids, context=context)])
            self.action_compute(cr, uid, uncompute_ids, context=context)
            for production in self.browse(cr, uid, ids, context=context):
                shipment_id = self._make_production_internal_shipment(cr, uid, production, context=context)
                produce_move_id = self._make_production_produce_line(cr, uid, production, context=context)

                # Take routing location as a Source Location.
                source_location_id = production.location_src_id.id
                if production.bom_id.routing_id and production.bom_id.routing_id.location_id:
                    source_location_id = production.bom_id.routing_id.location_id.id

                for line in production.product_lines:
                    consume_move_ids = self._make_production_consume_line(cr, uid, line, produce_move_id, source_location_id=source_location_id, context=context)
                    if shipment_id:
                        for consume_move_id in consume_move_ids:
                            shipment_move_id = self._make_production_internal_shipment_line(cr, uid, line, shipment_id, consume_move_id,<br />                                    destination_location_id=source_location_id, context=context)
                            self._make_production_line_procurement(cr, uid, line, shipment_move_id, context=context)

                if shipment_id:
                    wf_service.trg_validate(uid, 'stock.picking', shipment_id, 'button_confirm', cr)
                production.write({'state':'confirmed'}, context=context)
            return shipment_id

    [/code]


登录后回复
 

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