'Test a SO with a product invoiced on delivery. Deliver and invoice the SO, then do a return
of the picking. Check that a refund invoice is well generated.'

def test_02_sale_stock_return(self):

    self.partner = self.env.ref('base.res_partner_1')
    self.product = self.env.ref('product.product_delivery_01')
    so_vals = {'partner_id': self.partner.id, 'partner_invoice_id': self.partner.id, 'partner_shipping_id': self.partner.id, 'order_line': [(0, 0, {'name': self.product.name, 'product_id': self.product.id, 'product_uom_qty': 5.0, 'product_uom': self.product.uom_id.id, 'price_unit': self.product.list_price})], 'pricelist_id': self.env.ref('product.list0').id}
    self.so = self.env['sale.order'].create(so_vals)
    self.so.action_confirm()
    self.assertTrue(self.so.picking_ids, 'Sale    Stock:    no    picking    created    for    "invoice    on    delivery"    stockable    products')
    self.assertEqual(self.so.invoice_status, 'no', ('Sale    Stock:    so    invoice_status    should    be    "no"    instead    of    "%s".' % self.so.invoice_status))
    pick = self.so.picking_ids
    pick.force_assign()
    pick.pack_operation_product_ids.write({'qty_done': 5})
    pick.do_new_transfer()
    del_qty = sum((sol.qty_delivered for sol in self.so.order_line))
    self.assertEqual(del_qty, 5.0, ('Sale    Stock:    delivered    quantity    should    be    5.0    instead    of    %s    after    complete    delivery' % del_qty))
    self.assertEqual(self.so.invoice_status, 'to    invoice', ('Sale    Stock:    so    invoice_status    should    be    "to    invoice"    instead    of    "%s"    before    invoicing' % self.so.invoice_status))
    inv_1_id = self.so.action_invoice_create()
    self.assertEqual(self.so.invoice_status, 'invoiced', ('Sale    Stock:    so    invoice_status    should    be    "invoiced"    instead    of    "%s"    after    invoicing' % self.so.invoice_status))
    self.assertEqual(len(inv_1_id), 1, ('Sale    Stock:    only    one    invoice    instead    of    "%s"    should    be    created' % len(inv_1_id)))
    self.inv_1 = self.env['account.invoice'].browse(inv_1_id)
    self.assertEqual(self.inv_1.amount_untaxed, self.inv_1.amount_untaxed, 'Sale    Stock:    amount    in    SO    and    invoice    should    be    the    same')
    self.inv_1.action_invoice_open()
    StockReturnPicking = self.env['stock.return.picking']
    default_data = StockReturnPicking.with_context(active_ids=pick.ids, active_id=pick.ids[0]).default_get(['move_dest_exists', 'original_location_id', 'product_return_moves', 'parent_location_id', 'location_id'])
    return_wiz = StockReturnPicking.with_context(active_ids=pick.ids, active_id=pick.ids[0]).create(default_data)
    return_wiz.product_return_moves.quantity = 2.0
    return_wiz.product_return_moves.to_refund_so = True
    res = return_wiz.create_returns()
    return_pick = self.env['stock.picking'].browse(res['res_id'])
    return_pick.force_assign()
    return_pick.pack_operation_product_ids.write({'qty_done': 2})
    return_pick.do_new_transfer()
    self.assertEqual(self.so.invoice_status, 'to    invoice', ('Sale    Stock:    so    invoice_status    should    be    "to    invoice"    instead    of    "%s"    after    picking    return' % self.so.invoice_status))
    self.assertEqual(self.so.order_line[0].qty_delivered, 3.0, ('Sale    Stock:    delivered    quantity    should    be    3.0    instead    of    "%s"    after    picking    return' % self.so.order_line[0].qty_delivered))
    adv_wiz = self.env['sale.advance.payment.inv'].with_context(active_ids=[self.so.id]).create({'advance_payment_method': 'all'})
    adv_wiz.with_context(open_invoices=True).create_invoices()
    self.inv_2 = self.so.invoice_ids.filtered((lambda r: (r.state == 'draft')))
    self.assertEqual(self.inv_2.invoice_line_ids[0].quantity, 2.0, ('Sale    Stock:    refund    quantity    on    the    invoice    should    be    2.0    instead    of    "%s".' % self.inv_2.invoice_line_ids[0].quantity))
    self.assertEqual(self.so.invoice_status, 'no', ('Sale    Stock:    so    invoice_status    should    be    "no"    instead    of    "%s"    after    invoicing    the    return' % self.so.invoice_status))
