[FIX] sale: avoid false positives in reconciliation match

- ILIKE and other regex operators are not appropriate for the
  comparison, as we need an exact substring match.
  Using POSITION() and looking for position != 0 gives the expected behavior.
- Addiionally, regex operator ~  is not available in PostgreSQL 9.x
- Add regression tests

Closes #30720
This commit is contained in:
Nicolas Seinlet
2019-02-12 15:56:59 +01:00
committed by Olivier Dony
parent f45609d76b
commit b90fcdb162
2 changed files with 56 additions and 1 deletions
@@ -16,7 +16,7 @@ class AccountReconciliation(models.AbstractModel):
FROM sale_order o,
account_bank_statement_line stl
WHERE
lower(concat(o.name,o.reference)) ~ lower(stl.name)
POSITION(lower(stl.name) IN lower(concat(o.name,o.reference))) != 0
AND stl.id IN %s
AND (stl.partner_id is null OR stl.partner_id = o.partner_id)
AND (o.invoice_status = 'to invoice' OR o.state = 'sent')
+55
View File
@@ -238,3 +238,58 @@ class TestSaleOrder(TestCommonSaleNoChart):
self.assertEquals(self.sale_order.amount_total,
self.sale_order.amount_untaxed + self.sale_order.amount_tax,
'Taxes should be applied')
def test_reconciliation_with_so(self):
# create SO
so = self.env['sale.order'].create({
'name': 'SO/01/01',
'reference': 'Petit suisse',
'partner_id': self.partner_customer_usd.id,
'partner_invoice_id': self.partner_customer_usd.id,
'partner_shipping_id': self.partner_customer_usd.id,
'pricelist_id': self.pricelist_usd.id,
})
self.env['sale.order.line'].create({
'name': self.product_order.name,
'product_id': self.product_order.id,
'product_uom_qty': 2,
'product_uom': self.product_order.uom_id.id,
'price_unit': self.product_order.list_price,
'order_id': so.id,
'tax_id': False,
})
# Mark SO as sent otherwise we won't find any match
so.write({'state': 'sent'})
# Create bank statement
statement = self.env['account.bank.statement'].create({
'name': 'Test',
'journal_id': self.journal_purchase.id,
'user_id': self.user_employee.id,
})
st_line1 = self.env['account.bank.statement.line'].create({
'name': 'should not find anything',
'amount': 15,
'statement_id': statement.id
})
st_line2 = self.env['account.bank.statement.line'].create({
'name': 'SO/01',
'amount': 15,
'statement_id': statement.id
})
st_line3 = self.env['account.bank.statement.line'].create({
'name': 'suisse',
'amount': 15,
'statement_id': statement.id
})
# Call get_bank_statement_line_data for st_line_1, should not find any sale order
res = self.env['account.reconciliation.widget'].get_bank_statement_line_data([st_line1.id])
line = res.get('lines', [{}])[0]
self.assertFalse(line.get('sale_order_ids', False))
# Call again for st_line_2, it should find sale_order
res = self.env['account.reconciliation.widget'].get_bank_statement_line_data([st_line2.id])
line = res.get('lines', [{}])[0]
self.assertEquals(line.get('sale_order_ids', []), [so.id])
# Call again for st_line_3, it should find sale_order based on reference
res = self.env['account.reconciliation.widget'].get_bank_statement_line_data([st_line3.id])
line = res.get('lines', [{}])[0]
self.assertEquals(line.get('sale_order_ids', []), [so.id])