[FIX] sale: fix search "invoices is not set" for sale.order

Previous attempt #70343 of fixing was incorrect. Check code comments for
details.

---

opw-2516124

closes odoo/odoo#71547

X-original-commit: 9b64e523dfdbc82099c1de5b47ed13d6d6f75fe5
Signed-off-by: Ivan Yelizariev // IEL <yelizariev@users.noreply.github.com>
This commit is contained in:
Ivan Yelizariev
2021-06-01 12:29:25 +00:00
parent eaed74dec0
commit 4774c58dbe
2 changed files with 44 additions and 2 deletions
+16 -2
View File
@@ -138,8 +138,22 @@ class SaleOrder(models.Model):
""", (list(value),))
so_ids = self.env.cr.fetchone()[0] or []
return [('id', 'in', so_ids)]
if operator == '=' and not value:
return [('order_line.invoice_lines', '=', False)]
elif operator == '=' and not value:
# special case for [('invoice_ids', '=', False)], i.e. "Invoices is not set"
#
# We cannot just search [('order_line.invoice_lines', '=', False)]
# because it returns orders with uninvoiced lines, which is not
# same "Invoices is not set" (some lines may have invoices and some
# doesn't)
#
# A solution is making inverted search first ("orders with invoiced
# lines") and then invert results ("get all other orders")
#
# Domain below returns subset of ('order_line.invoice_lines', '!=', False)
order_ids = self._search([
('order_line.invoice_lines.move_id.move_type', 'in', ('out_invoice', 'out_refund'))
])
return [('id', 'not in', order_ids)]
return ['&', ('order_line.invoice_lines.move_id.move_type', 'in', ('out_invoice', 'out_refund')), ('order_line.invoice_lines.move_id', operator, value)]
name = fields.Char(string='Order Reference', required=True, copy=False, readonly=True, states={'draft': [('readonly', False)]}, index=True, default=lambda self: _('New'))
+28
View File
@@ -66,12 +66,37 @@ class TestSaleToInvoice(TestSaleCommon):
'default_journal_id': cls.company_data['default_journal_sale'].id,
}
def _check_order_search(self, orders, domain, expected_result):
domain += [('id', 'in', orders.ids)]
result = self.env['sale.order'].search(domain)
self.assertEqual(result, expected_result, "Unexpected result on search orders")
def test_search_invoice_ids(self):
"""Test searching on computed fields invoice_ids"""
# Make qty zero to have a line without invoices
self.sol_prod_order.product_uom_qty = 0
self.sale_order.action_confirm()
# Tests before creating an invoice
self._check_order_search(self.sale_order, [('invoice_ids', '=', False)], self.sale_order)
self._check_order_search(self.sale_order, [('invoice_ids', '!=', False)], self.env['sale.order'])
# Create invoice
moves = self.sale_order._create_invoices()
# Tests after creating the invoice
self._check_order_search(self.sale_order, [('invoice_ids', 'in', moves.ids)], self.sale_order)
self._check_order_search(self.sale_order, [('invoice_ids', '=', False)], self.env['sale.order'])
self._check_order_search(self.sale_order, [('invoice_ids', '!=', False)], self.sale_order)
def test_downpayment(self):
""" Test invoice with a way of downpayment and check downpayment's SO line is created
and also check a total amount of invoice is equal to a respective sale order's total amount
"""
# Confirm the SO
self.sale_order.action_confirm()
self._check_order_search(self.sale_order, [('invoice_ids', '=', False)], self.sale_order)
# Let's do an invoice for a deposit of 100
payment = self.env['sale.advance.payment.inv'].with_context(self.context).create({
'advance_payment_method': 'fixed',
@@ -79,6 +104,7 @@ class TestSaleToInvoice(TestSaleCommon):
'deposit_account_id': self.company_data['default_account_revenue'].id
})
payment.create_invoices()
self._check_order_search(self.sale_order, [('invoice_ids', '=', False)], self.env['sale.order'])
self.assertEqual(len(self.sale_order.invoice_ids), 1, 'Invoice should be created for the SO')
downpayment_line = self.sale_order.order_line.filtered(lambda l: l.is_downpayment)
@@ -161,7 +187,9 @@ class TestSaleToInvoice(TestSaleCommon):
payment = self.env['sale.advance.payment.inv'].with_context(self.context).create({
'advance_payment_method': 'delivered'
})
self._check_order_search(self.sale_order, [('invoice_ids', '=', False)], self.sale_order)
payment.create_invoices()
self._check_order_search(self.sale_order, [('invoice_ids', '=', False)], self.env['sale.order'])
invoice = self.sale_order.invoice_ids[0]
invoice.action_post()