Skip to content

Commit 264ec41

Browse files
committed
[FIX] pos_online_payment: prevent refunding online payment method
**Problem:** When refunding an order that has been done in the frontend from the backend, then when trying to pay for it again using an online payment method, it will currently work. The problem is that doing this will prevent the user from closing their session afterwards. The issue is that refunding through online payment method is not supported but is going through either way. **Steps to reproduce:** - Have an online payment method. - Go to your POS session and make a purchase, pay for it in cash. - Go back to the backend, to orders and chose your order. - Return the products and click payment to pay for it again. - Chose your online payment method and make the payment. - Try to close your POS session, an error prevents you from doing so. **Why the fix:** The problem is that an error should be thrown when trying to pay the refund with an online payment method as it is not supported. But this error is never reached. It was reached before this commit 2dce0f2 This commit is fixing an error that has since been avoided by this commit 0c8f0d7 The use case does not even go through the fixed *create* function anymore, so there should be no problem reverting the fix. Before said commit, we set the *online_account_payment_id* whether it exists or not. This then allows us to check if one of them is None later on. If it is, it means we can't create the online payment, as we can't create one without an accounting payment. After said commit, we didn't add it if the accounting payment didn't exist, so the error was never thrown as the code couldn't be reached. opw-4815049 closes odoo#213117 Signed-off-by: David Monnom (moda) <[email protected]>
1 parent 7b4e005 commit 264ec41

File tree

2 files changed

+45
-2
lines changed

2 files changed

+45
-2
lines changed

addons/pos_online_payment/models/pos_payment.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,7 @@ def create(self, vals_list):
2020
pm_id = vals['payment_method_id']
2121
if pm_id not in online_account_payments_by_pm:
2222
online_account_payments_by_pm[pm_id] = set()
23-
if vals.get('online_account_payment_id'):
24-
online_account_payments_by_pm[pm_id].add(vals['online_account_payment_id'])
23+
online_account_payments_by_pm[pm_id].add(vals.get('online_account_payment_id'))
2524

2625
opms_read_id = self.env['pos.payment.method'].search_read(['&', ('id', 'in', list(online_account_payments_by_pm.keys())), ('is_online_payment', '=', True)], ["id"])
2726
opms_id = {opm_read_id['id'] for opm_read_id in opms_read_id}

addons/pos_online_payment/tests/test_frontend.py

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
from odoo.addons.account.models.account_payment_method import AccountPaymentMethod
1313
from odoo.osv.expression import AND
1414
from odoo.addons.point_of_sale.tests.common import archive_products
15+
from odoo.exceptions import UserError
1516

1617
import odoo.tests
1718

@@ -286,6 +287,49 @@ def test_customer_display_online_payment(self):
286287
self.start_tour(f"/pos_customer_display/{self.main_pos_config.id}/{self.main_pos_config.access_token}",
287288
'CustomerDisplayTourOnlinePayment', login="pos_user")
288289

290+
def test_refuse_online_payment_without_accounting_payment(self):
291+
"""
292+
Test that a an order can not be paid through an online payment method from the backend
293+
when no accounting payment are set for this payment method. Ensure that it will raise
294+
an error as soon as it is tried as it is not supported yet. Also ensures that we can still
295+
close the session afterwards, as it is a side effect of not throwing the error.
296+
"""
297+
self.main_pos_config.open_ui()
298+
session = self.main_pos_config.current_session_id
299+
try:
300+
self.env["pos.order"].sync_from_ui([{
301+
"amount_paid": 1180,
302+
"amount_tax": 180,
303+
"amount_return": 0,
304+
"amount_total": 1180,
305+
"lines": [
306+
Command.create({
307+
"price_unit": 1000.0,
308+
"product_id": self.letter_tray.id,
309+
"price_subtotal": 1000.0,
310+
"price_subtotal_incl": 1180.0,
311+
"qty": 1,
312+
}),
313+
],
314+
"name": "Order 12345-123-1234",
315+
"session_id": session.id,
316+
"payment_ids": [
317+
Command.create({
318+
"amount": 1180,
319+
"name": fields.Datetime.now(),
320+
"payment_method_id": self.online_payment_method.id,
321+
}),
322+
],
323+
"uuid": "12345-123-1234",
324+
}])
325+
self.fail("An error should be raised if no accounting payment has been set")
326+
except UserError as e:
327+
self.assertIn("Cannot create a POS online payment without an accounting payment", str(e))
328+
# Make sure that we can close the session
329+
session.order_ids.filtered(lambda o: o.state == 'draft').unlink()
330+
session.action_pos_session_close()
331+
self.assertEqual(session.state, 'closed')
332+
289333
@classmethod
290334
def tearDownClass(cls):
291335
# Restore company values after the tests

0 commit comments

Comments
 (0)