payment_refund_wizard.py 2.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667
  1. # Part of Odoo. See LICENSE file for full copyright and licensing details.
  2. from odoo import _, api, fields, models
  3. from odoo.exceptions import ValidationError
  4. class PaymentRefundWizard(models.TransientModel):
  5. _name = 'payment.refund.wizard'
  6. _description = "Payment Refund Wizard"
  7. payment_id = fields.Many2one(
  8. string="Payment",
  9. comodel_name='account.payment',
  10. readonly=True,
  11. default=lambda self: self.env.context.get('active_id'),
  12. )
  13. transaction_id = fields.Many2one(
  14. string="Payment Transaction", related='payment_id.payment_transaction_id'
  15. )
  16. payment_amount = fields.Monetary(string="Payment Amount", related='payment_id.amount')
  17. refunded_amount = fields.Monetary(string="Refunded Amount", compute='_compute_refunded_amount')
  18. amount_available_for_refund = fields.Monetary(
  19. string="Maximum Refund Allowed", related='payment_id.amount_available_for_refund'
  20. )
  21. amount_to_refund = fields.Monetary(
  22. string="Refund Amount", compute='_compute_amount_to_refund', store=True, readonly=False
  23. )
  24. currency_id = fields.Many2one(string="Currency", related='transaction_id.currency_id')
  25. support_refund = fields.Selection(related='transaction_id.provider_id.support_refund')
  26. has_pending_refund = fields.Boolean(
  27. string="Has a pending refund", compute='_compute_has_pending_refund'
  28. )
  29. @api.constrains('amount_to_refund')
  30. def _check_amount_to_refund_within_boundaries(self):
  31. for wizard in self:
  32. if not 0 < wizard.amount_to_refund <= wizard.amount_available_for_refund:
  33. raise ValidationError(_(
  34. "The amount to be refunded must be positive and cannot be superior to %s.",
  35. wizard.amount_available_for_refund
  36. ))
  37. @api.depends('amount_available_for_refund')
  38. def _compute_refunded_amount(self):
  39. for wizard in self:
  40. wizard.refunded_amount = wizard.payment_amount - wizard.amount_available_for_refund
  41. @api.depends('amount_available_for_refund')
  42. def _compute_amount_to_refund(self):
  43. """ Set the default amount to refund to the amount available for refund. """
  44. for wizard in self:
  45. wizard.amount_to_refund = wizard.amount_available_for_refund
  46. @api.depends('payment_id') # To always trigger the compute
  47. def _compute_has_pending_refund(self):
  48. for wizard in self:
  49. pending_refunds_count = self.env['payment.transaction'].search_count([
  50. ('source_transaction_id', '=', wizard.payment_id.payment_transaction_id.id),
  51. ('operation', '=', 'refund'),
  52. ('state', 'in', ['draft', 'pending', 'authorized']),
  53. ])
  54. wizard.has_pending_refund = pending_refunds_count > 0
  55. def action_refund(self):
  56. for wizard in self:
  57. wizard.transaction_id.action_refund(amount_to_refund=wizard.amount_to_refund)