-
  Create a Sale Order
-
  !record {model: sale.order, id: so_I}:
    company_id: base.main_company
    date_order: '2011-04-13'
    invoice_quantity: order
    order_policy: manual
    partner_id: partner_A
    partner_invoice_id: address_A
    partner_order_id: address_A
    partner_shipping_id: address_A
    picking_policy: direct
    pricelist_id: product.list0
    shop_id: sale.shop
    priority: normal
    categ: medical
-
  Create a Sale Order Line
-
  !record {model: sale.order.line, id: sol_I1}:
    product_uom: product.product_uom_unit
    product_id: product_A
    order_id: so_I
    price_unit: 1
    product_uom_qty: 10
    date_planned: '2011-04-13'
    type: make_to_order
-
  !record {model: sale.order.line, id: sol_I2}:
    product_uom: product.product_uom_unit
    product_id: product_B
    order_id: so_I
    price_unit: 1
    product_uom_qty: 5
    date_planned: '2011-04-13'
    type: make_to_order
-
  I validate the sale order
-
  !python {model: sale.order}: |
    import netsvc
    wf_service = netsvc.LocalService("workflow")
    wf_service.trg_validate(uid, 'sale.order', ref("so_I"), 'order_confirm', cr)
-
  Run the scheduler
-
  !python {model: procurement.order}: |
    self.run_scheduler(cr, uid)
-
  Validate the purchase order
-
  !python {model: purchase.order}: |
    proc_obj = self.pool.get('procurement.order')
    sol_obj = self.pool.get('sale.order.line')
    # get the corresponding procurement order
    data = sol_obj.read(cr, uid, [ref("sol_I1")], ['procurement_id'], context=context)[0]
    proc_id = data['procurement_id'][0]
    data = proc_obj.read(cr, uid, [proc_id], ['purchase_id', 'state', 'note'], context=context)[0]
    po_id = data['purchase_id'][0]
    # change Invoicing control to From Picking
    self.write(cr, uid, [po_id], {'invoice_method':'picking'}, context=context)
    import netsvc
    wf_service = netsvc.LocalService("workflow")
    wf_service.trg_validate(uid, 'purchase.order', po_id, 'purchase_confirm', cr)
    wf_service.trg_validate(uid, 'purchase.order', po_id, 'purchase_approve', cr)
-
  Process the incoming shipment - reduce both qty - a back order is created
-
  !python {model: stock.picking}: |
    proc_obj = self.pool.get('procurement.order')
    sol_obj = self.pool.get('sale.order.line')
    # get the corresponding procurement order
    data = sol_obj.read(cr, uid, [ref("sol_I1")], ['procurement_id'], context=context)[0]
    proc_id = data['procurement_id'][0]
    data = proc_obj.read(cr, uid, [proc_id], ['purchase_id', 'state', 'note'], context=context)[0]
    po_id = data['purchase_id'][0]
    # find the IN
    in_ids = self.search(cr, uid, [('purchase_id', '=', po_id)], context=context)
    pick = self.browse(cr, uid, in_ids[0], context=context)
    # get the weird openERP picking type
    picking_type = self.pool.get('stock.partial.picking').get_picking_type(cr, uid, pick, context=context)
    # Convert to OUT to Simple OUT
    out_ids = self.search(cr, uid, [('sale_id', '=', ref("so_I"))], context=context)
    for out_id in out_ids:
      self.convert_to_standard(cr, uid, [out_id], context=context)
    # open process wizard
    dic = self.action_process(cr, uid, in_ids, context=context)
    wiz_model = dic['res_model']
    wiz_id = dic['res_id']
    wiz_c = dic['context']
    # only change product for both lines
    wiz_obj = self.pool.get(wiz_model)
    wiz_obj.copy_all(cr,uid,[dic['res_id']], context=dic['context'])
    for obj in wiz_obj.browse(cr, uid, [wiz_id], context=wiz_c):
      for out in getattr(obj, 'product_moves_%s'%picking_type):
        # change the product of original move
        dic_change = out.change_product(context=wiz_c)
        change_model = dic_change['res_model']
        change_ids = [dic_change['res_id']]
        change_c = dic_change['context']
        change_obj = self.pool.get(change_model)
        # product A -> C
        if out.quantity == 10:
          change_obj.write(cr, uid, change_ids, {'new_product_id': ref("product_C"), 'change_reason': 'yml test'}, context=change_c)
          change_obj.change_product(cr, uid, change_ids, context=change_c)
        # product B -> D
        if out.quantity == 5:
          change_obj.write(cr, uid, change_ids, {'new_product_id': ref("product_D"), 'change_reason': 'yml test'}, context=change_c)
          change_obj.change_product(cr, uid, change_ids, context=change_c)
          out.unlink(context=context)
    wiz_obj.copy_all(cr,uid,[dic['res_id']], context=dic['context'])
    wiz_obj.do_incoming_shipment(cr, uid, [dic['res_id']], context=dic['context'])
    # openERP swap IN -> backorder
    data = self.read(cr, uid, in_ids, ['backorder_id'], context=context)[0]
    back_ids = in_ids
    in_ids = [data['backorder_id'][0]]
    # assert a backorder has been created
    assert in_ids, 'backorder does not exist'
    data = self.read(cr, uid, in_ids, ['state'], context=context)[0]
    assert data['state'] == 'done', 'the incoming shipment is not Done - done - %s'%data['state']
    # assert the backorder
    data = self.read(cr, uid, back_ids, ['state'], context=context)[0]
    assert data['state'] == 'assigned', 'the backorder is not assigned - assigned - %s'%data['state']
    # check the moves in IN - products have changed !
    b_qty = [] # b qty is 0.0 and therefore removed
    c_qty = [10.0]
    for obj in self.browse(cr, uid, in_ids, context=context):
      for move in obj.move_lines:
        if move.product_id.id == ref("product_B"):
          b_qty.remove(move.product_qty)
        if move.product_id.id == ref("product_C"):
          c_qty.remove(move.product_qty)
    # all qty must be empty
    assert not b_qty, 'Quantity for product B is not empty - %s'%b_qty
    assert not c_qty, 'Quantity for product C is not empty - %s'%c_qty
    # check the moves in OUT
    b_qty = [5.0]
    c_qty = [10.0]
    out_ids = self.search(cr, uid, [('sale_id', '=', ref("so_I"))], context=context)
    # only one OUT for the sale order
    assert len(out_ids) == 1, 'number of out objects is wrong - 1 - %s'%len(out_ids)
    for obj in self.browse(cr, uid, out_ids, context=context):
      for move in obj.move_lines:
        if move.product_id.id == ref("product_B"):
          b_qty.remove(move.product_qty)
        if move.product_id.id == ref("product_C"):
          c_qty.remove(move.product_qty)
    # all qty must be empty
    assert not b_qty, 'Quantity for product B is not empty - %s'%b_qty
    assert not c_qty, 'Quantity for product C is not empty - %s'%c_qty
    
    # check the moves in IN Backorder
    b_qty = [5.0]
    for obj in self.browse(cr, uid, back_ids, context=context):
      for move in obj.move_lines:
        if move.product_id.id == ref("product_B"):
          b_qty.remove(move.product_qty)
    # all qty must be empty
    assert not b_qty, 'Quantity for product B is not empty - %s'%b_qty
    
