# Copyright (C) 2015 - Today: GRAP (http://www.grap.coop) # @author: Julien WESTE # @author: Sylvain LE GAL (https://twitter.com/legalsylvain) # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). from datetime import datetime from odoo import _, api, fields, models from odoo.tools import float_is_zero from odoo.exceptions import Warning as UserError class PosOrder(models.Model): _inherit = "pos.order" @api.multi def change_payment(self, payment_lines): """ Change payment of a given order. payment_lines should be a list of data that are the argument of the Odoo Core function add_payment() Return a list of order ids, depending on the payment_change_policy of the related pos_config. """ self.ensure_one() orders = self # Removing zero lines precision = self.pricelist_id.currency_id.decimal_places payment_lines = [ x for x in payment_lines if not float_is_zero( x["amount"], precision_digits=precision) ] self._check_payment_change_allowed() comment = _( "The payments of the Order %s (Ref: %s) has been changed" " by %s at %s." % ( self.name, self.pos_reference, self.env.user.name, datetime.today(), ) ) if self.config_id.payment_change_policy == "update": self.statement_ids.with_context().unlink() # Create new payment for line in payment_lines: self.add_payment(line) elif self.config_id.payment_change_policy == "refund": # Refund order and mark it as paid # with same payment method as the original one refund_result = self.refund() refund_order = self.browse(refund_result["res_id"]) for statement in self.statement_ids: refund_order.add_payment({ "journal": statement.journal_id.id, "amount": - statement.amount, "payment_date": fields.Date.context_today(self), }) refund_order.action_pos_order_paid() # Resale order and mark it as paid # with the new payment resale_order = self.copy( default={"pos_reference": self.pos_reference} ) for line in payment_lines: resale_order.add_payment(line) resale_order.action_pos_order_paid() orders += refund_order + resale_order comment += _(" (Refund Order: %s ; Resale Order: %s)" % ( refund_order.name, resale_order.name)) for order in orders: order.note = "%s\n%s" % (order.note or "", comment) return orders @api.multi def _check_payment_change_allowed(self): """Return True if the user can change the payment of a POS, depending of the state of the current session.""" closed_orders = self.filtered(lambda x: x.session_id.state == "closed") if len(closed_orders): raise UserError( _( "You can not change payments of the POS '%s' because" " the associated session '%s' has been closed!" % ( ", ".join(closed_orders.mapped("name")), ", ".join(closed_orders.mapped("session_id.name")), ) ) )