flectra/addons/sale/tests/test_sale_to_invoice_and_to_be_invoiced.py
2018-01-16 02:34:37 -08:00

272 lines
16 KiB
Python

# -*- coding: utf-8 -*-
# Part of Odoo, Flectra. See LICENSE file for full copyright and licensing details.
from flectra.addons.account.tests.account_test_classes import AccountingTestCase
class TestSaleOrderInvoicing(AccountingTestCase):
def test_sale_to_invoice_and_to_be_invoiced(self):
""" Testing amount to invoice and amount to be invoiced, with advances. """
partner = self.env.ref('base.res_partner_1')
partner.property_account_receivable_id = self.env['account.account'].search(
[('user_type_id', '=', self.env.ref('account.data_account_type_revenue').id)], limit=1)
product_1 = self.env.ref('product.product_product_8')
product_2 = self.env.ref('product.product_product_11')
# In order to test I create sales order and confirmed it.
order = self.env['sale.order'].create({
'partner_id': partner.id,
'partner_invoice_id': partner.id,
'partner_shipping_id': partner.id,
'order_line': [
(0, 0, {
'name': product_1.name,
'product_id': product_1.id,
'product_uom_qty': 2,
'qty_delivered': 2,
'product_uom': product_1.uom_id.id,
'price_unit': 100
}),
(0, 0, {
'name': product_2.name,
'product_id': product_2.id,
'product_uom_qty': 2,
'qty_delivered': 2,
'product_uom': product_2.uom_id.id,
'price_unit': 300
})
],
'pricelist_id': self.env.ref('product.list0').id,
})
context = {"active_model": 'sale.order', "active_ids": [order.id], "active_id": order.id}
order.with_context(context).action_confirm()
# Now I create invoice.
advance_product = self.env.ref('sale.advance_product_0')
advance_product.property_account_income_id = self.env['account.account'].search(
[('user_type_id', '=', self.env.ref('account.data_account_type_revenue').id)], limit=1)
payment = self.env['sale.advance.payment.inv'].create({
'advance_payment_method': 'fixed',
'amount': 500,
'product_id': advance_product.id,
})
payment.with_context(context).create_invoices()
invoice_1 = order.invoice_ids[0]
# Lets create one more invoice.
payment = self.env['sale.advance.payment.inv'].create({
'advance_payment_method': 'fixed',
'amount': 300,
'product_id': advance_product.id,
})
payment.with_context(context).create_invoices()
invoice_2 = order.invoice_ids[1]
self.assertEqual(sum(order.order_line.mapped('amt_to_invoice')), 800.0, 'Sale: the Amount To Invoice for the sale order should be 800.0.')
self.assertEqual(sum(order.order_line.mapped('amt_invoiced')), 0.0, 'Sale: the Amount Invoiced for the sale order should be 0.0.')
# Now I validate invoice_1.
invoice_1.invoice_validate()
self.assertEqual(sum(order.order_line.mapped('amt_to_invoice')), 300.0, 'Sale: the Amount To Invoice for the sale order should be 300.0.')
self.assertEqual(sum(order.order_line.mapped('amt_invoiced')), 500.0, 'Sale: the Amount Invoiced for the sale order should be 500.0.')
# Now I validate invoice_2.
invoice_2.invoice_validate()
self.assertEqual(sum(order.order_line.mapped('amt_to_invoice')), 0.0, 'Sale: the Amount To Invoice for the sale order should be 0.0.')
self.assertEqual(sum(order.order_line.mapped('amt_invoiced')), 800.0, 'Sale: the Amount Invoiced for the sale order should be 800.0.')
# Lets create a refund invoice for invoice_1.
# I refund the invoice Using Refund Button.
context = {"active_model": 'account.invoice', "active_ids": [invoice_1.id], "active_id": invoice_1.id}
account_invoice_refund_1 = self.env['account.invoice.refund'].with_context(context).create(dict(
description='Refund for Invoice 1',
filter_refund='refund'
))
# I clicked on refund button.
account_invoice_refund_1.with_context(context).invoice_refund()
invoice_1.refund_invoice_ids and invoice_1.refund_invoice_ids[0].invoice_validate()
self.assertEqual(sum(order.order_line.mapped('amt_to_invoice')), 0.0, 'Sale: the Amount To Invoice for the sale order should be 0.0.')
self.assertEqual(sum(order.order_line.mapped('amt_invoiced')), 300.0, 'Sale: the Amount Invoiced for the sale order should be 300.0.')
# Lets create a refund invoice for invoice_2.
# I refund the invoice Using Refund Button.
context = {"active_model": 'account.invoice', "active_ids": [invoice_2.id], "active_id": invoice_2.id}
account_invoice_refund_2 = self.env['account.invoice.refund'].with_context(context).create(dict(
description='Refund for Invoice 2',
filter_refund='refund'
))
# I clicked on refund button.
account_invoice_refund_2.with_context(context).invoice_refund()
invoice_2.refund_invoice_ids and invoice_2.refund_invoice_ids[0].invoice_validate()
self.assertEqual(sum(order.order_line.mapped('amt_to_invoice')), 0.0, 'Sale: the Amount To Invoice for the sale order should be 0.0.')
self.assertEqual(sum(order.order_line.mapped('amt_invoiced')), 0.0, 'Sale: the Amount Invoiced for the sale order should be 0.0.')
def test_amount_delivered_and_ordered_qty(self):
""" Testing amount to invoice and amount to be invoiced, with different invoice policy and cancelling SO """
# disable mail feature to speed test
context_no_mail = {
'tracking_disable': True,
'mail_notrack': True,
'mail_create_nolog': True,
}
# create products and partner
Product = self.env['product.product'].with_context(context_no_mail)
product_order = Product.create({
'name': "Service Ordered",
'standard_price': 10,
'list_price': 20,
'type': 'service',
'invoice_policy': 'order',
'default_code': 'SERV-ORDERED1',
'taxes_id': False, # force no tax
})
product_deli = Product.create({
'name': 'iMac',
'standard_price': 400,
'list_price': 500,
'type': 'consu',
'invoice_policy': 'delivery',
'default_code': 'E-COM09',
'taxes_id': False, # force no tax
})
partner = self.env.ref('base.res_partner_1')
partner.property_account_receivable_id = self.env['account.account'].search([('user_type_id', '=', self.env.ref('account.data_account_type_revenue').id)], limit=1)
# create Sales order, with 2 lines: one delivered, one ordered
order = self.env['sale.order'].with_context(context_no_mail).create({
'partner_id': partner.id,
'partner_invoice_id': partner.id,
'partner_shipping_id': partner.id,
'pricelist_id': self.env.ref('product.list0').id,
})
sale_line_ord = self.env['sale.order.line'].with_context(context_no_mail).create({
'order_id': order.id,
'name': product_order.name,
'product_id': product_order.id,
'product_uom_qty': 2,
'qty_delivered': 0,
'product_uom': product_order.uom_id.id,
'price_unit': 20
})
sale_line_deli = self.env['sale.order.line'].with_context(context_no_mail).create({
'order_id': order.id,
'name': product_deli.name,
'product_id': product_deli.id,
'product_uom_qty': 2,
'qty_delivered': 0,
'product_uom': product_deli.uom_id.id,
'price_unit': 500
})
self.assertEqual(sale_line_deli.amt_to_invoice, 0.0, 'Amount to invoice for delivered qty SO line should zero, since its state is draft')
self.assertEqual(sale_line_deli.amt_invoiced, 0.0, 'Amount invoiced for delivered qty SO line should zero, since its state is draft, and there is no invoice at this moment')
self.assertEqual(sale_line_ord.amt_to_invoice, 0.0, 'Amount to invoice for ordered qty SO line should zero, since its state is draft')
self.assertEqual(sale_line_ord.amt_invoiced, 0.0, 'Amount invoiced for ordered qty SO line should zero, since its state is draft, and there is no invoice at this moment')
# confirm SO
order.action_confirm()
self.assertEqual(sale_line_deli.amt_to_invoice, 0.0, 'Amount to invoice for delivered SO line is still zero, since its delivered quantity is zero')
self.assertEqual(sale_line_deli.amt_invoiced, 0.0, 'Amount invoiced for delivered SO line is still zero, since its delivered quantity is zero, and there is no invoice at this moment')
self.assertEqual(sale_line_ord.amt_to_invoice, 40.0, 'Amount to invoice for ordered SO line should be 40, even if there is no invoice')
self.assertEqual(sale_line_ord.amt_invoiced, 0.0, 'Amount invoiced for ordered SO line should zero, there is no invoice at this moment')
# create invoice for delivered product
invoice_context = {"active_model": 'sale.order', "active_ids": [order.id], "active_id": order.id}
payment = self.env['sale.advance.payment.inv'].with_context(context_no_mail).create({
'advance_payment_method': 'delivered',
})
payment.with_context(invoice_context).create_invoices()
invoice_1 = order.invoice_ids[0]
self.assertEqual(sale_line_deli.amt_to_invoice, 0.0, 'Amount to invoice for delivered SO line is still zero, since its delivered quantity (on SO line) is zero')
self.assertEqual(sale_line_deli.amt_invoiced, 0.0, 'Amount invoiced for delivered SO line is still zero, since its delivered quantity (on SO line) is zero, and there is no invoice at this moment')
self.assertEqual(sale_line_ord.amt_to_invoice, 40.0, 'Amount to invoice for ordered SO line should be 40, since there is a draft invoice')
self.assertEqual(sale_line_ord.amt_invoiced, 0.0, 'Amount invoiced for ordered SO line should zero, there is no validated invoice at this moment')
# validate invoice
invoice_1.invoice_validate()
self.assertEqual(sale_line_deli.amt_to_invoice, 0.0, 'Amount to invoice for delivered SO line is still zero, since its delivered quantity (on SO line) is zero')
self.assertEqual(sale_line_deli.amt_invoiced, 0.0, 'Amount invoiced for delivered SO line is still zero, since its delivered quantity (on SO line) is zero, and there is no invoice at this moment')
self.assertEqual(sale_line_ord.amt_to_invoice, 0.0, 'Amount to invoice for ordered SO line is zero, since the invoice is validated')
self.assertEqual(sale_line_ord.amt_invoiced, 40.0, 'Amount invoiced for ordered SO line should 40, there is a validated invoice at this moment')
# deliver 2 unit of product_deli
sale_line_deli.write({'qty_delivered': 2})
self.assertEqual(sale_line_deli.amt_to_invoice, 1000.0, 'Amount to invoice for delivered SO line is now 1000, since its delivered quantity (on SO line) is 2 (unit price = 500)')
self.assertEqual(sale_line_deli.amt_invoiced, 0.0, 'Amount invoiced for delivered SO line is still zero, since there is no invoice at this moment for this product')
self.assertEqual(sale_line_ord.amt_to_invoice, 0.0, 'Amount to invoice for ordered SO line is zero, since the invoice is validated')
self.assertEqual(sale_line_ord.amt_invoiced, 40.0, 'Amount invoiced for ordered SO line should 40, there is a validated invoice at this moment')
# create second invoice and validate it
payment = self.env['sale.advance.payment.inv'].with_context(context_no_mail).create({
'advance_payment_method': 'delivered',
})
payment.with_context(invoice_context).create_invoices()
invoice_2 = order.invoice_ids.sorted(key='id')[1]
invoice_2.invoice_validate()
self.assertEqual(sale_line_deli.amt_to_invoice, 0.0, 'Amount to invoice for delivered SO line is 0, since this is all invoiced')
self.assertEqual(sale_line_deli.amt_invoiced, 1000.0, 'Amount invoiced for delivered SO line is now 1000, since the invoice for this product is validated')
self.assertEqual(sale_line_ord.amt_to_invoice, 0.0, 'Amount to invoice for ordered SO line is zero, since the invoice is validated')
self.assertEqual(sale_line_ord.amt_invoiced, 40.0, 'Amount invoiced for ordered SO line should 40, there is a validated invoice at this moment')
# deliver 1 more unit of product_deli
sale_line_deli.write({'qty_delivered': sale_line_deli.qty_delivered+1})
self.assertEqual(sale_line_deli.amt_to_invoice, 500.0, 'Amount to invoice for delivered SO line is now 500, since we got a uninvoiced unit')
self.assertEqual(sale_line_deli.amt_invoiced, 1000.0, 'Amount invoiced for delivered SO line is still 1000, even the delivered qty change')
self.assertEqual(sale_line_ord.amt_to_invoice, 0.0, 'Amount to invoice for ordered SO line is zero, since the invoice is validated')
self.assertEqual(sale_line_ord.amt_invoiced, 40.0, 'Amount invoiced for ordered SO line should 40, there is a validated invoice at this moment')
# create third invoice
payment = self.env['sale.advance.payment.inv'].with_context(context_no_mail).create({
'advance_payment_method': 'delivered',
})
payment.with_context(invoice_context, open_invoices=True).create_invoices()
invoice_3 = order.invoice_ids.sorted(key='id')[2]
self.assertEqual(sale_line_deli.amt_to_invoice, 500.0, 'Amount to invoice for delivered SO line is now 500, since we got a uninvoiced unit')
self.assertEqual(sale_line_deli.amt_invoiced, 1000.0, 'Amount invoiced for delivered SO line is still 1000')
self.assertEqual(sale_line_ord.amt_to_invoice, 0.0, 'Amount to invoice for ordered SO line is zero, since the invoice is validated')
self.assertEqual(sale_line_ord.amt_invoiced, 40.0, 'Amount invoiced for ordered SO line should 40, there is a validated invoice at this moment')
# cancel order
order.action_cancel()
self.assertEqual(sale_line_deli.amt_to_invoice, 0.0, 'Amount to invoice for delivered SO line is now 0, since SO is cancel')
self.assertEqual(sale_line_deli.amt_invoiced, 1000.0, 'Amount invoiced for delivered SO line is still 1000, even if the SO is cancelled')
self.assertEqual(sale_line_ord.amt_to_invoice, 0.0, 'Amount to invoice for ordered SO line is zero, since the invoice is validated')
self.assertEqual(sale_line_ord.amt_invoiced, 40.0, 'Amount invoiced for ordered SO line should 40, there is a validated invoice at this moment')
# change the unit price on 3rd invoice
invoice_3.invoice_line_ids.write({'price_unit': 300})
self.assertEqual(sale_line_deli.amt_to_invoice, 0.0, 'Amount to invoice for delivered SO line is now 0: nothing should change as the invoice is in draft state')
self.assertEqual(sale_line_deli.amt_invoiced, 1000.0, 'Amount invoiced for delivered SO line is still 1000, even if we change price of unvalidated invoice')
self.assertEqual(sale_line_ord.amt_to_invoice, 0.0, 'Amount to invoice for ordered SO line is zero, since the invoice is validated')
self.assertEqual(sale_line_ord.amt_invoiced, 40.0, 'Amount invoiced for ordered SO line should 40, there is a validated invoice at this moment')
# validate third invoice
invoice_3.invoice_validate()
self.assertEqual(sale_line_deli.amt_to_invoice, 0.0, 'Amount to invoice for delivered SO line is now 0, since SO is cancel')
self.assertEqual(sale_line_deli.amt_invoiced, 1300.0, 'Amount invoiced for delivered SO line is incremented, since the 3rd invoice for this product is validated')
self.assertEqual(sale_line_ord.amt_to_invoice, 0.0, 'Amount to invoice for ordered SO line is zero, since the invoice is validated')
self.assertEqual(sale_line_ord.amt_invoiced, 40.0, 'Amount invoiced for ordered SO line should 40, there is a validated invoice at this moment')