跳转至内容
  • 版块
  • 标签
  • 热门
  • 用户
  • 群组
皮肤
  • 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. OPENERP 库存管理源码分析(目前是库链分析)

OPENERP 库存管理源码分析(目前是库链分析)

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

    既然是源码 就先开门见 "米田共" 吧 stock.py 模块的类列表[img]www.shine-it.net/attachments/month_1003/20100309_4cecc7f05dab5ad97937BUadDdZKL7It.jpg[/img]
    1.1

    stock.location
    [color=Blue] 'chained_location_id': fields.many2one('stock.location', 'Chained Location If Fixed'),[/color]
    [color=Blue] 'chained_location_type': fields.selection([('none', 'None'), ('customer', 'Customer'), ('fixed', 'Fixed Location')],[/color]
    [color=Blue] 'Chained Location Type', required=True),[/color]
    [color=Blue] 'chained_auto_packing': fields.selection([/color]
    [color=Blue] [('auto', 'Automatic Move'), ('manual', 'Manual Operation'), ('transparent', 'Automatic No Step Added')],[/color]
    [color=Blue] 'Automatic Move',[/color]
    [color=Blue] required=True,[/color]
    [color=Blue] help="This is used only if you selected a chained location type.n" [/color]
    [color=Blue] "The 'Automatic Move' value will create a stock move after the current one that will be "[/color]
    [color=Blue] "validated automatically. With 'Manual Operation', the stock move has to be validated "[/color]
    [color=Blue] "by a worker. With 'Automatic No Step Added', the location is replaced in the original move."[/color]
    [color=Blue] ),[/color]
    库位的库链概念

    从下面这个源码上看
    

    [color=DarkOrange] def chained_location_get(self, cr, uid, location, partner=None, product=None, context={}):[/color]
    [color=DarkOrange] result = None[/color]
    [color=DarkOrange] if location.chained_location_type == 'customer':[/color]
    [color=DarkOrange] if partner:[/color]
    [color=DarkOrange] result = partner.property_stock_customer[/color]
    [color=DarkOrange] elif location.chained_location_type == 'fixed':[/color]
    [color=DarkOrange] result = location.chained_location_id[/color]
    [color=DarkOrange] if result:[/color]
    [color=DarkOrange] return result, location.chained_auto_packing, location.chained_delay[/color]
    [color=DarkOrange] return result[/color]
    当 库链类型为客户的话 [color=DarkOrange]chained_location_get [/color] 将返回 业务伙伴的默认客户库位
    当 库链类型为固定的话 [color=DarkOrange]chained_location_get [/color] 将返回 chained_location_id的库位值
    还能分析出 如果选择库链类型为客户为 客户 固定连锁库位(Chained Location If Fixed) 可以不用设置
    如果选择库链类型为客户为 固定 固定连锁库位(Chained Location If Fixed) 需要设置

    stock.move

    def _chain_compute(self, cr, uid, moves, context={}):
        result = {}
        for m in moves:
            dest = self.pool.get('stock.location').[color=DarkOrange]chained_location_get[/color](
                cr,
                uid,
                [color=Red]m.location_dest_id,[/color]  #总是从 目的地库位上得到库链值
                m.picking_id and m.picking_id.address_id and m.picking_id.address_id.partner_id,
                m.product_id,
                context
            )
            if dest:
                if dest[1] == 'transparent':
                    self.write(cr, uid, [m.id], {
                        'date_planned': (DateTime.strptime(m.date_planned, '%Y-%m-%d %H:%M:%S') + 
                            DateTime.RelativeDateTime(days=dest[2] or 0)).strftime('%Y-%m-%d'),
                        '[color=Red]location_dest_id': dest[0].id[/color]})
                else:
                    result.setdefault(m.picking_id, [])
                    result[m.picking_id].append( (m, dest) )
        return result
    
    当库链计算时 在指定的出入库明细集合 moves 里 循环遍历每个出入库明细行 获得库链值 判断当库链[color=Blue]chained_auto_packing的值为[/color]transparent(透明)
    名称为[color=Blue]Automatic No Step Added(没有自动添加的步骤)[/color] 时 更新出入库明细行的计划日期+库链延迟(天) 同时最关键的是 改变 出入库明细行的出库目的地
    从而 实现 透明调拨  
    当库链[color=Blue]chained_auto_packing的值不是[/color]transparent(透明)时 当前函数就不处理了(还是把球踢给别人吧)返回 没有处理的出入库明细行和库链值的集合
    
    最变态的在这里***
    def action_confirm(self, cr, uid, ids, context={}):
        # ids = map(lambda m: m.id, moves)
        moves = self.browse(cr, uid, ids)
        self.write(cr, uid, ids, {'state': 'confirmed'})
        i = 0
    
        def create_chained_picking(self, cr, uid, moves, context):
            new_moves = []
            for picking, todo in self._chain_compute(cr, uid, moves, context).items():
                ptype = self.pool.get('stock.location').picking_type_get(cr, uid, todo[0][0].location_dest_id, todo[0][1][0])
                pickid = self.pool.get('stock.picking').create(cr, uid, {
                    'name': picking.name,
                    'origin': str(picking.origin or ''),
                    'type': ptype,
                    'note': picking.note,
                    'move_type': picking.move_type,
                  [color=Red]  'auto_picking': todo[0][1][1] == 'auto',[/color]        # 就是先获得[color=Blue]chained_auto_packing的值[/color]是不是自动[color=Red](auto:[/color][color=Blue]Automatic Move[/color][color=Red])[/color] 为真就是自动装箱
                    'address_id': picking.address_id.id,
                    'invoice_state': 'none'
                })
                for move, (loc, auto, delay) in todo:
                    # Is it smart to copy ? May be it's better to recreate ?
                    new_id = self.pool.get('stock.move').copy(cr, uid, move.id, {
                        'location_id': move.location_dest_id.id,
                        'location_dest_id': loc.id,
                        'date_moved': time.strftime('%Y-%m-%d'),
                        'picking_id': pickid,
                        'state': 'waiting',
                        'move_history_ids': [],
                        'date_planned': (DateTime.strptime(move.date_planned, '%Y-%m-%d %H:%M:%S') +
                                    DateTime.RelativeDateTime(days=delay or            0)).strftime('%Y-%m-%d'),
                        'move_history_ids2': []}
                    )
                    self.pool.get('stock.move').write(cr, uid, [move.id], {
                        'move_dest_id': new_id,
                        'move_history_ids': [(4, new_id)]
                    })
                    new_moves.append(self.browse(cr, uid, [new_id])[0])
                wf_service = netsvc.LocalService("workflow")
                wf_service.trg_validate(uid, 'stock.picking', pickid, 'button_confirm', cr)
            if new_moves:
                create_chained_picking(self, cr, uid, new_moves, context)
        create_chained_picking(self, cr, uid, moves, context)
        return []
    
       计算库链函数_chain_compute  只能完成库链处理的最简单的处理(就是打打酱油) 变态复杂的处理还得交给他大哥 create_chained_picking(建立库链出库单或入库单/建立库链装箱单)处理同时没那么简单还要被大哥不停的使唤 ()
       这位大哥只有在 stock.move-action_confirm触发时才会执行 话说这位大哥函数 处事原则是赶尽杀绝(递归大法) 
    

    老板action_confirm给了个名单(库链处理明细) , create_chained_picking大哥先让_chain_compute小弟把里面简单做掉的处理了再把复杂的名单交给大哥亲自处理 ,大哥处理了之后 把处理掉的名单再次交给小弟让它找到被大哥处理掉的名单上能给他们报仇的人的名单 然后先处理掉名单上简单的 再把复杂的再交给大哥亲自处理 直到赶紧杀绝为止!
    新生成的出入库单(装箱单)的[color=Red]auto_picking 就要看库链的自动调拨的值了
    [/color]
    举个例子 设定几个库位 C1, K1, K2, K3,K4,K5
    K1 的 库链类型为固定 ,库链库位为K2(K1死掉了K2会给它报仇的), 自动调拨([color=Blue]Automatic Move[/color]):
    为 [color=Blue]'auto', 'Automatic Move'[/color]
    K2 的 库链类型为客户(和固定处理方式一样,库链库位在库位信息里不用设置,会从出入库单的客户上的默认客户库位上获取假定为K3)
    1 当一个出库单是从C1到K1时 当确认(confirm)操作时 自动生成一个从K1到K2的出库单 同时原来的出库单明细行上的 ('move_dest_id': new_id,
    'move_history_ids': [(4, new_id)] )移动目标值为从K1到K2的出库单对应的明细行的值
    move_history_ids 对应 数据库表 stock_move_history_ids 这个表的作用到这里也就基本清楚了

                           K4 的 库链类型为客户  自动调拨([color=Blue]Automatic Move[/color]):                                
    

    为 [color=Blue]'transparent', 'Automatic No Step Added'[/color] ,库链库位为K5
    2 当一个出库单是从C1到K4是 当出入库单的action_confirm触发时 (出入库单的action_confirm 方法会调用 出入库明细的action_confirm)
    出入库明细的出库目的地就会从 K4变成K5 .没有新添加什么步骤 可能就是所谓透明

    [[i] 本帖最后由 leetaizhu 于 2010-3-10 17:46 编辑 [/i]]

    1 条回复 最后回复
    0
    • digitalsatoriD 离线
      digitalsatoriD 离线
      digitalsatori 管理员
      写于 最后由 编辑
      #2

      开源软件就应该这样去解剖,楼主继续。

      【上海先安科技】(tony AT openerp.cn)

      1 条回复 最后回复
      0
      • JoshuaJ 离线
        JoshuaJ 离线
        Joshua 管理员
        写于 最后由 编辑
        #3

        支持lz:handshake

        【上海先安科技】(joshua AT openerp.cn),欢迎关注公众号:openerp_cn

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

          你这不是给幼儿园读格林童话吗

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

            楼主好认真了。我其实也作了一些这部分工作,但是没有整理发贴。看到楼主的积极性,让我感动!:lol

            1 条回复 最后回复
            0
            • X 离线
              X 离线
              xtjie
              写于 最后由 编辑
              #6

              大家多发一些这样的东西,对学习openerp是非常有益的。希望能参与进来。

              1 条回复 最后回复
              0
              • B 离线
                B 离线
                bobrone
                写于 最后由 编辑
                #7

                赞一个!!

                1 条回复 最后回复
                0
                • M 离线
                  M 离线
                  mf1389004071
                  写于 最后由 编辑
                  #8

                  mark

                  1 条回复 最后回复
                  0

                  • 登录

                  • 没有帐号? 注册

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