[FIX] point_of_sale: automatic reconciliation with returns

In the case where:
1- Do an order on the pos selling a product A (amount = 10)
2- Do another order returning a certain quantity of A (with a quantity < 0)
3- Do a third order selling something else (amount = 5)

Before this commit, the account move lines of the payment move and of the sale move of operation 2 weren't reconciled
This was because the credit to the receivable account of the return was reconciled with the debit of the first operation,
leaving the debit of the payment of the return alone
(i. e. the lines number 1 & 3 & 5 were reconciled together, instead of 1 & 2 & 5, and 3 & 4)

We end up in a situation like this (at validation time)

	RECEIVABLE
D	|	C	||	OPERATION		|	Line Number
----------------------------------------------------------------------------
15	|		||	(1 & 3-Engaging Sale)	|	1
	|	10	||	(1-Payment)		|	2
	|	10	||	(2-Engaging Return)	|	3
10	|		||	(2-Payment Return)	|	4
	|	5	||	(3-Payment)		|	5

After this commit, we reconcile the returns for each order before reconciling other transaction chains
The fix is limited in its scope as the automatic reconciliation for the pos transaction is fairly recent
and a "nice to have"

OPW 787298
This commit is contained in:
Lucas Perais (lpe)
2018-01-23 09:23:42 +01:00
parent 7a63d471ed
commit 296c5a2106
+10 -3
View File
@@ -339,15 +339,22 @@ class PosOrder(models.Model):
for order in self:
aml = order.statement_ids.mapped('journal_entry_ids').mapped('line_ids') | order.account_move.line_ids | order.invoice_id.move_id.line_ids
aml = aml.filtered(lambda r: not r.reconciled and r.account_id.internal_type == 'receivable' and r.partner_id == order.partner_id.commercial_partner_id)
# Reconcile returns first
# to avoid mixing up the credit of a payment and the credit of a return
# in the receivable account
aml_returns = aml.filtered(lambda l: (l.journal_id.type == 'sale' and l.credit) or (l.journal_id.type != 'sale' and l.debit))
try:
aml.reconcile()
aml_returns.reconcile()
(aml - aml_returns).reconcile()
except:
# There might be unexpected situations where the automatic reconciliation won't
# work. We don't want the user to be blocked because of this, since the automatic
# reconciliation is introduced for convenience, not for mandatory accounting
# reasons.
_logger.error('Reconciliation did not work for order %s', order.name)
continue
# It may be interesting to have the Traceback logged anyway
# for debugging and support purposes
_logger.exception('Reconciliation did not work for order %s', order.name)
def _default_session(self):
return self.env['pos.session'].search([('state', '=', 'opened'), ('user_id', '=', self.env.uid)], limit=1)