跳转至内容
  • 版块
  • 标签
  • 热门
  • 用户
  • 群组
皮肤
  • 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 demo 测试数据分析及源码分析

OPENERP demo 测试数据分析及源码分析

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

    首先 需要修正一下OPENERP 5.0.7里的 产品BOM信息
    [attach]465[/attach]
    [attach]466[/attach]
    为了 简单 我们 先测试官方demo 测试数据 的 销售订单 SO003 我是在2010/03/26日创建的生产帐套
    第一我们需要取消除了 定期盘存以外其他的数据
    首先打开 pgAdmin III 里数据库
    删除 stock_picking
    mrp_procurement
    mrp_production
    mrp_production_move_ids
    mrp_production_product_line
    mrp_production_workcenter_line
    表的信息
    删除stock_move表里第16行以后的数据 (1-16行是盘点数据或者说是初始库存)
    取消 SO003,SO004,SO005的订单
    然后 审核订单 SO003 ---测试就从这里开始了
    因为SO003的 分拣策略 为分批出货 订单明细的获得方式都是 订货(MTO/来单生产)
    同时 SO003的订单明细 有 [color=Red][PC1] 基本电脑[/color] 基本电脑 3台 订单明细的交货期(Delivery Lead Time:delay) 为2天
    [color=Red][PC2] 基础+PC(按订单组装) [/color]3台 订单明细的交货期(Delivery Lead Time:delay) 为7天
    而公司的配置信息内设置了 交货安全期(company.security_lead) 为5天 依据源码
    date_planned = DateTime.now() + DateTime.DateTimeDeltaFromDays(line.delay or 0.0)
    date_planned = (date_planned - DateTime.DateTimeDeltaFromDays(company.security_lead)).strftime('%Y-%m-%d %H:%M:%S')
    [color=Red][PC1] 基本电脑 [/color]计划时间 就是 当期时间(2010/03/26)+2天-5天 =2010/03/23
    [color=Red][PC2] 基础+PC(按订单组装)[/color] 计划时间 就是 当期时间(2010/03/26)+7天-5天 =2010/03/28
    [attach]467[/attach]

    所以 审核订单 SO003
    第一 会创建 一个出库单
    第二 会创建 1) 会和上面的出单一样的计划时间
    [attach]468[/attach]
    订单 的 审核订单按钮会执行 sale.py 里的 action_ship_create方法
    里面有
    [color=Red] wf_service = netsvc.LocalService("workflow")[/color]
    [color=Red] wf_service.trg_validate(uid, 'mrp.procurement', proc_id, 'button_confirm', cr)[/color]
    [color=Red] self.pool.get('sale.order.line').write(cr, uid, [line.id], {'procurement_id': proc_id})[/color]

    上面红色字的就会 触发 需求单 里的工作流 的方法
    [attach]469[/attach]
    到 工作流 produce 里面的方法 action_produce_assign_product
    def action_produce_assign_product(self, cr, uid, ids, context={}):
    produce_id = False
    company = self.pool.get('res.users').browse(cr, uid, uid, context).company_id
    for procurement in self.browse(cr, uid, ids):
    res_id = procurement.move_id.id
    loc_id = procurement.location_id.id
    newdate = DateTime.strptime(procurement.date_planned, '%Y-%m-%d %H:%M:%S') - DateTime.RelativeDateTime(days=procurement.product_id.product_tmpl_id.produce_delay or 0.0)
    newdate = newdate - DateTime.RelativeDateTime(days=company.manufacturing_lead)
    produce_id = self.pool.get('mrp.production').create(cr, uid, {
    'origin': procurement.origin,
    'product_id': procurement.product_id.id,
    'product_qty': procurement.product_qty,
    'product_uom': procurement.product_uom.id,
    'product_uos_qty': procurement.product_uos and procurement.product_uos_qty or False,
    'product_uos': procurement.product_uos and procurement.product_uos.id or False,
    'location_src_id': procurement.location_id.id,
    'location_dest_id': procurement.location_id.id,
    'bom_id': procurement.bom_id and procurement.bom_id.id or False,
    'date_planned': newdate.strftime('%Y-%m-%d %H:%M:%S'),
    'move_prod_id': res_id,
    })
    [color=Red] self.write(cr, uid, [procurement.id], {'state':'running'})[/color]
    bom_result = self.pool.get('mrp.production').action_compute(cr, uid,
    [produce_id], properties=[x.id for x in procurement.property_ids])
    wf_service = netsvc.LocalService("workflow")
    [color=Red]wf_service.trg_validate(uid, 'mrp.production', produce_id, 'button_confirm', cr)[/color]
    self.pool.get('stock.move').write(cr, uid, [res_id],
    {'location_id':procurement.location_id.id})
    return produce_id

    上面的 [color=Red]self.write(cr, uid, [procurement.id], {'state':'running'})[/color] 说明 需求单 的状态为 运行中
    [attach]470[/attach]
    根据
    newdate = DateTime.strptime(procurement.date_planned, '%Y-%m-%d %H:%M:%S') - DateTime.RelativeDateTime(days=procurement.product_id.product_tmpl_id.produce_delay or 0.0)
    newdate = newdate - DateTime.RelativeDateTime(days=company.manufacturing_lead)
    [color=Red][PC1] 基本电脑 [/color]的 procurement.date_planned为 2010/03/23 - [color=Red][PC1] 基本电脑 [/color]的生产提前期(5.0.7翻译为 制造周期)为1天(procurement.product_id.product_tmpl_id.produce_delay) -公司的生产提前期(company.manufacturing_lead) 为1天
    newdate =2010/03/21
    [color=Red][PC2] 基础+PC(按订单组装)[/color] 的 procurement.date_planned为 2010/03/28 - [color=Red][PC1] 基本电脑 [/color]的生产提前期(5.0.7翻译为 制造周期)为1天(procurement.product_id.product_tmpl_id.produce_delay) -公司的生产提前期(company.manufacturing_lead) 为1天
    newdate =2010/03/26

    [color=Red]wf_service.trg_validate(uid, 'mrp.production', produce_id, 'button_confirm', cr) [/color]会触发
    [attach]471[/attach]
    (因一个贴子的字数限制 后面的内容在下面 或下一页)

    [[i] 本帖最后由 leetaizhu 于 2010-3-28 23:50 编辑 [/i]]

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

      def test_if_product(self, cr, uid, ids):
      res = True
      for production in self.browse(cr, uid, ids):
      [color=Red] if not production.product_lines:[/color]
      if not self.action_compute(cr, uid, [production.id]):
      res = False
      return res

      因为 上面 创建的 生产单里面没有 创建生产明细 所以会 执行 self.action_compute(cr, uid, [production.id])
      def action_compute(self, cr, uid, ids, properties=[]):
      results = []
      for production in self.browse(cr, uid, ids):
      cr.execute('delete from mrp_production_product_line where production_id=%s', (production.id,))
      cr.execute('delete from mrp_production_workcenter_line where production_id=%s', (production.id,))
      bom_point = production.bom_id
      bom_id = production.bom_id.id
      if not bom_point:
      bom_id = self.pool.get('mrp.bom')._bom_find(cr, uid, production.product_id.id, production.product_uom.id, properties)
      if bom_id:
      bom_point = self.pool.get('mrp.bom').browse(cr, uid, bom_id)
      routing_id = bom_point.routing_id.id or False
      self.write(cr, uid, [production.id], {'bom_id': bom_id, 'routing_id': routing_id})

              if not bom_id:
                  raise osv.except_osv(_('Error'), _("Couldn't find bill of material for product"))
      
              #if bom_point.routing_id and bom_point.routing_id.location_id:
              #   self.write(cr, uid, [production.id], {'location_src_id': bom_point.routing_id.location_id.id})
      
              factor = production.product_qty * production.product_uom.factor / bom_point.product_uom.factor
      

      [color=Red] res = self.pool.get('mrp.bom')._bom_explode(cr, uid, bom_point, factor / bom_point.product_qty, properties)[/color]
      results = res[0]
      results2 = res[1]
      for line in results:
      line['production_id'] = production.id
      self.pool.get('mrp.production.product.line').create(cr, uid, line)
      for line in results2:
      line['production_id'] = production.id
      self.pool.get('mrp.production.workcenter.line').create(cr, uid, line)
      return len(results)
      这里 就把 生产单产品的BOM的产品和工作中心信息 创建到 生产单的生产明细行里和生产单的工作中心明细行里
      [attach]472[/attach]
      [attach]473[/attach]
      这之后 就执行下面的方法了
      def action_confirm(self, cr, uid, ids):
      picking_id=False
      proc_ids = []
      for production in self.browse(cr, uid, ids):
      if not production.product_lines:
      self.action_compute(cr, uid, [production.id])
      production = self.browse(cr, uid, [production.id])[0]
      routing_loc = None
      pick_type = 'internal'
      address_id = False
      if production.bom_id.routing_id and production.bom_id.routing_id.location_id:
      routing_loc = production.bom_id.routing_id.location_id
      if routing_loc.usage<>'internal':
      pick_type = 'out'
      address_id = routing_loc.address_id and routing_loc.address_id.id or False
      routing_loc = routing_loc.id
      picking_id = self.pool.get('stock.picking').create(cr, uid, {
      'origin': (production.origin or '').split(':')[0] +':'+production.name,
      'type': pick_type,
      'move_type': 'one',
      'state': 'auto',
      'address_id': address_id,
      'auto_picking': self._get_auto_picking(cr, uid, production),
      })

              source = production.product_id.product_tmpl_id.property_stock_production.id
              data = {
                  'name':'PROD:'+production.name,
                  'date_planned': production.date_planned,
                  'product_id': production.product_id.id,
                  'product_qty': production.product_qty,
                  'product_uom': production.product_uom.id,
                  'product_uos_qty': production.product_uos and production.product_uos_qty or False,
                  'product_uos': production.product_uos and production.product_uos.id or False,
                  'location_id': source,
                  'location_dest_id': production.location_dest_id.id,
                  'move_dest_id': production.move_prod_id.id,
                  'state': 'waiting'
              }
              res_final_id = self.pool.get('stock.move').create(cr, uid, data)
      
              self.write(cr, uid, [production.id], {'move_created_ids': [(6, 0, [res_final_id])]})
              moves = []
              for line in production.product_lines:
                  move_id=False
                  newdate = production.date_planned
                  if line.product_id.type in ('product', 'consu'):
                      res_dest_id = self.pool.get('stock.move').create(cr, uid, {
                          'name':'PROD:'+production.name,
                          'date_planned': production.date_planned,
                          'product_id': line.product_id.id,
                          'product_qty': line.product_qty,
                          'product_uom': line.product_uom.id,
                          'product_uos_qty': line.product_uos and line.product_uos_qty or False,
                          'product_uos': line.product_uos and line.product_uos.id or False,
                          'location_id': routing_loc or production.location_src_id.id,
                          'location_dest_id': source,
                          'move_dest_id': res_final_id,
                          'state': 'waiting',
                      })
                      moves.append(res_dest_id)
                      move_id = self.pool.get('stock.move').create(cr, uid, {
                          'name':'PROD:'+production.name,
                          'picking_id':picking_id,
                          'product_id': line.product_id.id,
                          'product_qty': line.product_qty,
                          'product_uom': line.product_uom.id,
                          'product_uos_qty': line.product_uos and line.product_uos_qty or False,
                          'product_uos': line.product_uos and line.product_uos.id or False,
                          'date_planned': newdate,
                          'move_dest_id': res_dest_id,
                          'location_id': production.location_src_id.id,
                          'location_dest_id': routing_loc or production.location_src_id.id,
                          'state': 'waiting',
                      })
                  proc_id = self.pool.get('mrp.procurement').create(cr, uid, {
                      'name': (production.origin or '').split(':')[0] + ':' + production.name,
                      'origin': (production.origin or '').split(':')[0] + ':' + production.name,
                      'date_planned': newdate,
                      'product_id': line.product_id.id,
                      'product_qty': line.product_qty,
                      'product_uom': line.product_uom.id,
                      'product_uos_qty': line.product_uos and line.product_qty or False,
                      'product_uos': line.product_uos and line.product_uos.id or False,
                      'location_id': production.location_src_id.id,
                      'procure_method': line.product_id.procure_method,
                      'move_id': move_id,
                  })
                  wf_service = netsvc.LocalService("workflow")
                  wf_service.trg_validate(uid, 'mrp.procurement', proc_id, 'button_confirm', cr)
                  proc_ids.append(proc_id)
              wf_service = netsvc.LocalService("workflow")
              wf_service.trg_validate(uid, 'stock.picking', picking_id, 'button_confirm', cr)
              self.write(cr, uid, [production.id], {'picking_id':picking_id, 'move_lines': [(6,0,moves)], 'state':'confirmed'})
          return picking_id
      

      这个方法比较复杂同时也是最核心的地方
      首先来 看看 这里面有三个 创建 self.pool.get('stock.move').create 的地方
      分别来看看
      第一个 self.pool.get('stock.move').create 创建是
      [attach]474[/attach]
      第二个 self.pool.get('stock.move').create 创建是
      [attach]475[/attach]
      第三个 self.pool.get('stock.move').create 创建是
      [attach]476[/attach]
      proc_id = self.pool.get('mrp.procurement').create(cr, uid, {
      'name': (production.origin or '').split(':')[0] + ':' + production.name,
      'origin': (production.origin or '').split(':')[0] + ':' + production.name,
      'date_planned': newdate,
      'product_id': line.product_id.id,
      'product_qty': line.product_qty,
      'product_uom': line.product_uom.id,
      'product_uos_qty': line.product_uos and line.product_qty or False,
      'product_uos': line.product_uos and line.product_uos.id or False,
      'location_id': production.location_src_id.id,
      'procure_method': line.product_id.procure_method,
      'move_id': move_id,
      })
      wf_service = netsvc.LocalService("workflow")
      wf_service.trg_validate(uid, 'mrp.procurement', proc_id, 'button_confirm', cr)
      这里 这个 wf_service.trg_validate(uid, 'mrp.procurement', proc_id, 'button_confirm', cr) 是不是 很熟悉 对就是上面出现的 好像进入到 递归运算里了

      [[i] 本帖最后由 leetaizhu 于 2010-3-29 01:52 编辑 [/i]]

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

        继续赞.....

        图文有码...

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

          这个,非常不错,我现在也在看这个的代码

          1 条回复 最后回复
          0

          • 登录

          • 没有帐号? 注册

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