You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

100 lines
3.5 KiB

  1. # Copyright (C) 2015 - Today: GRAP (http://www.grap.coop)
  2. # @author: Julien WESTE
  3. # @author: Sylvain LE GAL (https://twitter.com/legalsylvain)
  4. # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
  5. from datetime import datetime
  6. from odoo import _, api, fields, models
  7. from odoo.tools import float_is_zero
  8. from odoo.exceptions import Warning as UserError
  9. class PosOrder(models.Model):
  10. _inherit = "pos.order"
  11. @api.multi
  12. def change_payment(self, payment_lines):
  13. """
  14. Change payment of a given order.
  15. payment_lines should be a list of data that are
  16. the argument of the Odoo Core function add_payment()
  17. Return a list of order ids, depending on the
  18. payment_change_policy of the related pos_config.
  19. """
  20. self.ensure_one()
  21. orders = self
  22. # Removing zero lines
  23. precision = self.pricelist_id.currency_id.decimal_places
  24. payment_lines = [
  25. x for x in payment_lines if not float_is_zero(
  26. x["amount"], precision_digits=precision)
  27. ]
  28. self._check_payment_change_allowed()
  29. comment = _(
  30. "The payments of the Order %s (Ref: %s) has been changed"
  31. " by %s at %s." % (
  32. self.name,
  33. self.pos_reference,
  34. self.env.user.name,
  35. datetime.today(),
  36. )
  37. )
  38. if self.config_id.payment_change_policy == "update":
  39. self.statement_ids.with_context().unlink()
  40. # Create new payment
  41. for line in payment_lines:
  42. self.add_payment(line)
  43. elif self.config_id.payment_change_policy == "refund":
  44. # Refund order and mark it as paid
  45. # with same payment method as the original one
  46. refund_result = self.refund()
  47. refund_order = self.browse(refund_result["res_id"])
  48. for statement in self.statement_ids:
  49. refund_order.add_payment({
  50. "journal": statement.journal_id.id,
  51. "amount": - statement.amount,
  52. "payment_date": fields.Date.context_today(self),
  53. })
  54. refund_order.action_pos_order_paid()
  55. # Resale order and mark it as paid
  56. # with the new payment
  57. resale_order = self.copy(
  58. default={"pos_reference": self.pos_reference}
  59. )
  60. for line in payment_lines:
  61. resale_order.add_payment(line)
  62. resale_order.action_pos_order_paid()
  63. orders += refund_order + resale_order
  64. comment += _(" (Refund Order: %s ; Resale Order: %s)" % (
  65. refund_order.name, resale_order.name))
  66. for order in orders:
  67. order.note = "%s\n%s" % (order.note or "", comment)
  68. return orders
  69. @api.multi
  70. def _check_payment_change_allowed(self):
  71. """Return True if the user can change the payment of a POS, depending
  72. of the state of the current session."""
  73. closed_orders = self.filtered(lambda x: x.session_id.state == "closed")
  74. if len(closed_orders):
  75. raise UserError(
  76. _(
  77. "You can not change payments of the POS '%s' because"
  78. " the associated session '%s' has been closed!"
  79. % (
  80. ", ".join(closed_orders.mapped("name")),
  81. ", ".join(closed_orders.mapped("session_id.name")),
  82. )
  83. )
  84. )