[FIX] sale: stop requesting payment on SO with negative balance

Prior to this commit, payment was requested on sale orders with a
negative balance. Customers could settle transactions with a negative
amount. No payment provider allows negative transactions which would
lead to crashes and errors during payment.

Now, payment is only requested if the total amount of the sale order is
strictly positive.

task-2887019

Part-of: odoo/odoo#104277
This commit is contained in:
Valentin Chevalier
2022-11-21 12:56:39 +01:00
parent 76cf429c83
commit e4a30ba31c
+40 -2
View File
@@ -1328,11 +1328,49 @@ class SaleOrder(models.Model):
# PORTAL #
def _has_to_be_signed(self, include_draft=False):
return (self.state == 'sent' or (self.state == 'draft' and include_draft)) and not self.is_expired and self.require_signature and not self.signature
"""A sale order has to be signed when:
- its state is `sent`, or `draft` if draft sale orders are included;
- it's not expired;
- it requires a signature;
- it's not already signed.
Note: self.ensure_one()
:param bool include_draft: Whether including `draft` sale orders, defaults to False.
:return: Whether the sale order has to be signed.
:rtype: bool
"""
self.ensure_one()
return (
(self.state == 'sent' or (self.state == 'draft' and include_draft))
and not self.is_expired
and self.require_signature
and not self.signature
)
def _has_to_be_paid(self, include_draft=False):
"""A sale order has to be paid when:
- its state is `sent`, or `draft` if draft sale orders are included;
- it's not expired;
- it requires a payment;
- the last transaction's state isn't `done`;
- the total amount is strictly positive.
Note: self.ensure_one()
:param bool include_draft: Whether including `draft` sale orders, defaults to False.
:return: Whether the sale order has to be paid.
:rtype: bool
"""
self.ensure_one()
transaction = self.get_portal_last_transaction()
return (self.state == 'sent' or (self.state == 'draft' and include_draft)) and not self.is_expired and self.require_payment and transaction.state != 'done' and self.amount_total
return (
(self.state == 'sent' or (self.state == 'draft' and include_draft))
and not self.is_expired
and self.require_payment
and transaction.state != 'done'
and self.amount_total > 0
)
def _get_portal_return_action(self):
""" Return the action used to display orders when returning from customer portal. """