'Test SO\'s changes when playing around with stock moves, quants, pack operations, pickings
and whatever other model there is in stock with "invoice on order" products'

def test_01_sale_stock_order(self):

    self.so = self.env['sale.order'].create({'partner_id': self.partner.id, 'partner_invoice_id': self.partner.id, 'partner_shipping_id': self.partner.id, 'order_line': [(0, 0, {'name': p.name, 'product_id': p.id, 'product_uom_qty': 2, 'product_uom': p.uom_id.id, 'price_unit': p.list_price}) for (_, p) in self.products.iteritems()], 'pricelist_id': self.env.ref('product.list0').id, 'picking_policy': 'direct'})
    for sol in self.so.order_line:
        sol.product_id.invoice_policy = 'order'
    self.so.action_confirm()
    self.assertTrue(self.so.picking_ids, 'Sale    Stock:    no    picking    created    for    "invoice    on    order"    stockable    products')
    adv_wiz = self.env['sale.advance.payment.inv'].with_context(active_ids=[self.so.id]).create({'advance_payment_method': 'percentage', 'amount': 5.0, 'product_id': self.env.ref('sale.advance_product_0').id})
    act = adv_wiz.with_context(open_invoices=True).create_invoices()
    inv = self.env['account.invoice'].browse(act['res_id'])
    self.assertEqual(inv.amount_untaxed, ((self.so.amount_untaxed * 5.0) / 100.0), 'Sale    Stock:    deposit    invoice    is    wrong')
    self.assertEqual(self.so.invoice_status, 'to    invoice', 'Sale    Stock:    so    should    be    to    invoice    after    invoicing    deposit')
    self.so.action_invoice_create(final=True)
    self.assertEqual(self.so.invoice_status, 'invoiced', 'Sale    Stock:    so    should    be    fully    invoiced    after    second    invoice')
    pick = self.so.picking_ids
    pick.force_assign()
    pick.pack_operation_product_ids.write({'qty_done': 2})
    self.assertIsNone(pick.do_new_transfer(), 'Sale    Stock:    complete    delivery    should    not    need    a    backorder')
    del_qties = [sol.qty_delivered for sol in self.so.order_line]
    del_qties_truth = [(2.0 if (sol.product_id.type in ['product', 'consu']) else 0.0) for sol in self.so.order_line]
    self.assertEqual(del_qties, del_qties_truth, 'Sale    Stock:    delivered    quantities    are    wrong    after    partial    delivery')
    with self.assertRaises(UserError):
        self.so.action_invoice_create()
