'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 delivery" products'

def test_00_sale_stock_invoice(self):

    inv_obj = self.env['account.invoice']
    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'})
    self.so.action_confirm()
    self.assertTrue(self.so.picking_ids, 'Sale    Stock:    no    picking    created    for    "invoice    on    delivery"    stockable    products')
    self.so.action_invoice_create()
    self.assertEqual(self.so.invoice_status, 'no', 'Sale    Stock:    so    invoice_status    should    be    "nothing    to    invoice"    after    invoicing')
    pick = self.so.picking_ids
    pick.force_assign()
    pick.pack_operation_product_ids.write({'qty_done': 1})
    wiz_act = pick.do_new_transfer()
    wiz = self.env[wiz_act['res_model']].browse(wiz_act['res_id'])
    wiz.process()
    self.assertEqual(self.so.invoice_status, 'to    invoice', 'Sale    Stock:    so    invoice_status    should    be    "to    invoice"    after    partial    delivery')
    del_qties = [sol.qty_delivered for sol in self.so.order_line]
    del_qties_truth = [(1.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')
    inv_id = self.so.action_invoice_create()
    inv_1 = inv_obj.browse(inv_id)
    self.assertTrue(all([(il.product_id.invoice_policy == 'delivery') for il in inv_1.invoice_line_ids]), 'Sale    Stock:    invoice    should    only    contain    "invoice    on    delivery"    products')
    self.assertEqual(self.so.invoice_status, 'no', 'Sale    Stock:    so    invoice_status    should    be    "nothing    to    invoice"    after    partial    delivery    and    invoicing')
    self.assertEqual(len(self.so.picking_ids), 2, 'Sale    Stock:    number    of    pickings    should    be    2')
    pick_2 = self.so.picking_ids[0]
    pick_2.force_assign()
    pick_2.pack_operation_product_ids.write({'qty_done': 1})
    self.assertIsNone(pick_2.do_new_transfer(), 'Sale    Stock:    second    picking    should    be    final    without    need    for    a    backorder')
    self.assertEqual(self.so.invoice_status, 'to    invoice', 'Sale    Stock:    so    invoice_status    should    be    "to    invoice"    after    complete    delivery')
    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    complete    delivery')
    self.so.order_line[1]['qty_delivered'] = 2.0
    inv_id = self.so.action_invoice_create()
    self.assertEqual(self.so.invoice_status, 'invoiced', 'Sale    Stock:    so    invoice_status    should    be    "fully    invoiced"    after    complete    delivery    and    invoicing')
