From 0b2386ee5f2d3b7ee0539987ae9fd38b9eeb7de1 Mon Sep 17 00:00:00 2001 From: "Pedro M. Baeza" Date: Wed, 21 Oct 2015 23:43:25 +0200 Subject: [PATCH] account_payment_return: Improve behaviour --- account_payment_return/README.rst | 56 +++++- account_payment_return/__init__.py | 1 - account_payment_return/__openerp__.py | 31 ++-- .../i18n/account_payment_return.pot | 12 +- account_payment_return/i18n/de.po | 14 +- account_payment_return/i18n/es.po | 12 +- account_payment_return/models/__init__.py | 4 +- .../models/account_invoice.py | 11 +- .../models/payment_return.py | 159 ++++++++++-------- .../models/payment_return_line.py | 65 ------- account_payment_return/tests/__init__.py | 4 + .../tests/test_payment_return.py | 82 ++++++++- .../views/account_invoice_view.xml | 7 +- .../views/payment_return_view.xml | 27 ++- 14 files changed, 279 insertions(+), 206 deletions(-) delete mode 100644 account_payment_return/models/payment_return_line.py diff --git a/account_payment_return/README.rst b/account_payment_return/README.rst index a5e63b948021..46b18f5cd63d 100644 --- a/account_payment_return/README.rst +++ b/account_payment_return/README.rst @@ -1,11 +1,49 @@ -Payment orders returns +.. image:: https://img.shields.io/badge/licence-AGPL--3-blue.svg + :target: http://www.gnu.org/licenses/agpl-3.0-standalone.html + :alt: License: AGPL-3 + +================================= +Returned Customers Payment Orders +================================= + +This module implements customer receivables returns and allows to send +related reconciled account move lines back to a state where +the debt is still open, and letting history of it. + +This module can be extended adding importers that automatically fills the +full returned payment record. + +Usage +===== + +Go to Accounting > Customers > Customer Payment Returns, and create a new +record, register on each line a paid (reconciled) receivable journal item, +and input the amount that is going to be returned. + +Next, press button "Confirm" to create a new move line that removes the +balance from the bank journal and reconcile items together to show payment +history through it. + +.. image:: https://odoo-community.org/website/image/ir.attachment/5784_f2813bd/datas + :alt: Try me on Runbot + :target: https://runbot.odoo-community.org/runbot/96/8.0 + +Known issues / Roadmap ====================== -Features: ---------- +* Add a button to see the created move. +* Allow to add a commission amount on each line. - * This module implements the return of invoice payments and allows to catch several reconciled account move lines, to give back to a state where the debt is still open, and letting history of it. +Bug Tracker +=========== +Bugs are tracked on `GitHub Issues `_. +In case of trouble, please check there if your issue has already been reported. +If you spotted it first, help us smashing it by providing a detailed and welcomed feedback `here `_. Credits ======= @@ -14,9 +52,9 @@ Contributors ------------ * 7 i TRIA * Avanzosc -* Pedro M. Baeza -* Markus Schneider -* Sergio Teruel +* Pedro M. Baeza +* Markus Schneider +* Sergio Teruel Maintainer ---------- @@ -27,6 +65,8 @@ Maintainer This module is maintained by the OCA. -OCA, or the Odoo Community Association, is a nonprofit organization whose mission is to support the collaborative development of Odoo features and promote its widespread use. +OCA, or the Odoo Community Association, is a nonprofit organization whose +mission is to support the collaborative development of Odoo features and +promote its widespread use. To contribute to this module, please visit http://odoo-community.org. diff --git a/account_payment_return/__init__.py b/account_payment_return/__init__.py index 7d80ffe9de17..e7a68e1715f7 100644 --- a/account_payment_return/__init__.py +++ b/account_payment_return/__init__.py @@ -25,4 +25,3 @@ ############################################################################## from . import models - diff --git a/account_payment_return/__openerp__.py b/account_payment_return/__openerp__.py index b5aa649539a6..80d42306f3d9 100644 --- a/account_payment_return/__openerp__.py +++ b/account_payment_return/__openerp__.py @@ -1,4 +1,4 @@ -# -*- encoding: utf-8 -*- +# -*- coding: utf-8 -*- ############################################################################## # # OpenERP, Open Source Management Solution @@ -10,6 +10,8 @@ # Markus Schneider # Copyright (c) 2015 Incaser Informatica # Sergio Teruel +# Copyright (c) 2015 Serv. Tecnol. Avanzados +# Pedro M. Baeza # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU Affero General Public License as published @@ -28,19 +30,26 @@ { - "name": "Account Payment Return", - "version": "1.0", + "name": "Account Payment Returns", + "version": "8.0.1.0.0", + "summary": "Manage the return of your payments", 'license': 'AGPL-3', - "depends": ['mail', 'account'], - 'author': 'Serv. Tecnol. Avanzados - Pedro M. Baeza', + "depends": [ + 'mail', + 'account', + ], + 'author': '7 i TRIA, ' + 'Serv. Tecnol. Avanzados - Pedro M. Baeza, ' + 'Incaser Informática, ' + 'initOS GmbH & Co., ' + 'Odoo Community Association (OCA)', 'website': 'http://www.serviciosbaeza.com', 'data': [ - 'security/ir.model.access.csv', - 'security/account_payment_return_security.xml', - 'views/payment_return_view.xml', - 'data/ir_sequence_data.xml', - 'views/account_invoice_view.xml', + 'security/ir.model.access.csv', + 'security/account_payment_return_security.xml', + 'views/payment_return_view.xml', + 'data/ir_sequence_data.xml', + 'views/account_invoice_view.xml', ], - 'demo': [], 'installable': True, } diff --git a/account_payment_return/i18n/account_payment_return.pot b/account_payment_return/i18n/account_payment_return.pot index 4c28697d864d..4e2cddcf4b95 100644 --- a/account_payment_return/i18n/account_payment_return.pot +++ b/account_payment_return/i18n/account_payment_return.pot @@ -111,7 +111,7 @@ msgid "Invoice" msgstr "" #. module: account_payment_return -#: help:account.invoice,payment_returned:0 +#: help:account.invoice,returned_payment:0 msgid "Invoice has been included on a payment that has been returned later." msgstr "" @@ -178,15 +178,15 @@ msgid "Payment return lines" msgstr "" #. module: account_payment_return -#: field:account.invoice,payment_returned:0 -msgid "Payment returned" +#: field:account.invoice,returned_payment:0 +msgid "Retuned payment" msgstr "" #. module: account_payment_return #: model:ir.actions.act_window,name:account_payment_return.payment_return_action #: model:ir.ui.menu,name:account_payment_return.payment_return_menu #: view:payment.return:account_payment_return.payment_return_tree_view -msgid "Payment returns" +msgid "Customer Payment Returns" msgstr "" #. module: account_payment_return @@ -194,7 +194,7 @@ msgstr "" #: help:payment.return.line,date:0 #: help:payment.return.line,partner_name:0 #: help:payment.return.line,reason:0 -msgid "Readed from imported file. Only for reference." +msgid "Read from imported file. Only for reference." msgstr "" #. module: account_payment_return @@ -255,7 +255,7 @@ msgstr "" #. module: account_payment_return #: help:payment.return,date:0 -msgid "This date will be used as the date for the account entry." +msgid "This date will be used as the account entry date." msgstr "" #. module: account_payment_return diff --git a/account_payment_return/i18n/de.po b/account_payment_return/i18n/de.po index 7aa6845b3a20..44376e1a264c 100644 --- a/account_payment_return/i18n/de.po +++ b/account_payment_return/i18n/de.po @@ -23,7 +23,7 @@ msgstr "Importiert" #: code:addons/account_payment_return/payment_return.py:126 #. module: account_payment_return #, python-format -msgid "You must complete all invoice references in the payment return." +msgid "You must input all invoice references in the payment return." msgstr "Alle Zeilen müssen mit einer Rechnung verknüpft sein." #: view:payment.return:0 @@ -55,7 +55,7 @@ msgstr "Followers" #: model:ir.ui.menu,name:account_payment_return.payment_return_menu #: view:payment.return:0 #. module: account_payment_return -msgid "Payment returns" +msgid "Customer Payment returns" msgstr "Kunden Rückbuchungen" #: field:payment.return.line,reason:0 @@ -149,9 +149,9 @@ msgstr "" msgid "Messages and communication history" msgstr "" -#: field:account.invoice,payment_returned:0 +#: field:account.invoice,returned_payment:0 #. module: account_payment_return -msgid "Payment returned" +msgid "Returned payment" msgstr "Zahlung zurückgebucht" #: view:payment.return:0 @@ -196,7 +196,7 @@ msgstr "Rückbuchungsdatum" #: help:payment.return.line,partner_name:0 #: help:payment.return.line,reason:0 #. module: account_payment_return -msgid "Readed from imported file. Only for reference." +msgid "Read from imported file. Only for reference." msgstr "Feld für Import, nur zur Information." #: help:payment.return,message_unread:0 @@ -230,7 +230,7 @@ msgstr "" msgid "Status Change" msgstr "Status geändert" -#: help:account.invoice,payment_returned:0 +#: help:account.invoice,returned_payment:0 #. module: account_payment_return msgid "Invoice has been included on a payment that has been returned later." msgstr "Rechnung hat eine Zahlung die später zurück gebucht wurde." @@ -242,7 +242,7 @@ msgstr "" #: help:payment.return,date:0 #. module: account_payment_return -msgid "This date will be used as the date for the account entry." +msgid "This date will be used as the account entry date." msgstr "" #: selection:payment.return,state:0 diff --git a/account_payment_return/i18n/es.po b/account_payment_return/i18n/es.po index 563726a6041e..5f519354c206 100644 --- a/account_payment_return/i18n/es.po +++ b/account_payment_return/i18n/es.po @@ -114,7 +114,7 @@ msgid "Invoice" msgstr "Factura" #. module: account_payment_return -#: help:account.invoice,payment_returned:0 +#: help:account.invoice,returned_payment:0 msgid "Invoice has been included on a payment that has been returned later." msgstr "La factura ha sido incluida en un pago que ha sido devuelto más tarde." @@ -181,15 +181,15 @@ msgid "Payment return lines" msgstr "Líneas de la devolución" #. module: account_payment_return -#: field:account.invoice,payment_returned:0 -msgid "Payment returned" +#: field:account.invoice,returned_payment:0 +msgid "Returned payment" msgstr "Pago devuelto" #. module: account_payment_return #: model:ir.actions.act_window,name:account_payment_return.payment_return_action #: model:ir.ui.menu,name:account_payment_return.payment_return_menu #: view:payment.return:account_payment_return.payment_return_tree_view -msgid "Payment returns" +msgid "Customer Payment Returns" msgstr "Devoluciones de cobros" #. module: account_payment_return @@ -197,7 +197,7 @@ msgstr "Devoluciones de cobros" #: help:payment.return.line,date:0 #: help:payment.return.line,partner_name:0 #: help:payment.return.line,reason:0 -msgid "Readed from imported file. Only for reference." +msgid "Read from imported file. Only for reference." msgstr "Leído del archivo importado. Sólo como referencia." #. module: account_payment_return @@ -258,7 +258,7 @@ msgstr "Resumen" #. module: account_payment_return #: help:payment.return,date:0 -msgid "This date will be used as the date for the account entry." +msgid "This date will be used as the account entry date." msgstr "Esta fecha se utilizará como fecha del asiento contable." #. module: account_payment_return diff --git a/account_payment_return/models/__init__.py b/account_payment_return/models/__init__.py index c9806ec036e2..9689c6f5c974 100644 --- a/account_payment_return/models/__init__.py +++ b/account_payment_return/models/__init__.py @@ -1,4 +1,4 @@ -# -*- encoding: utf-8 -*- +# -*- coding: utf-8 -*- ############################################################################## # # OpenERP, Open Source Management Solution @@ -8,7 +8,6 @@ # Pedro M. Baeza # Copyright (c) 2014 initOS GmbH & Co. KG # Markus Schneider -# $Id$ # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU Affero General Public License as published @@ -26,5 +25,4 @@ ############################################################################## from . import payment_return -from . import payment_return_line from . import account_invoice diff --git a/account_payment_return/models/account_invoice.py b/account_payment_return/models/account_invoice.py index d24005299217..0bcede89b656 100644 --- a/account_payment_return/models/account_invoice.py +++ b/account_payment_return/models/account_invoice.py @@ -1,4 +1,4 @@ -# -*- encoding: utf-8 -*- +# -*- coding: utf-8 -*- ############################################################################## # # OpenERP, Open Source Management Solution @@ -24,9 +24,10 @@ from openerp import models, fields -class account_invoice(models.Model): +class AccountInvoice(models.Model): _inherit = "account.invoice" - payment_returned = fields.Boolean('Payment returned', help='Invoice ' - 'has been included on a payment ' - 'that has been returned later.') + returned_payment = fields.Boolean( + string='Payment returned', + help='Invoice has been included on a payment that has been returned ' + 'later.') diff --git a/account_payment_return/models/payment_return.py b/account_payment_return/models/payment_return.py index 0f7d35fac645..b4e6e9c0bd72 100644 --- a/account_payment_return/models/payment_return.py +++ b/account_payment_return/models/payment_return.py @@ -1,4 +1,4 @@ -# -*- encoding: utf-8 -*- +# -*- coding: utf-8 -*- ############################################################################## # # OpenERP, Open Source Management Solution @@ -24,7 +24,8 @@ # ############################################################################## from openerp import models, fields, api, _ -from openerp.exceptions import except_orm +from openerp.exceptions import Warning as UserError +import openerp.addons.decimal_precision as dp class PaymentReturn(models.Model): @@ -34,50 +35,47 @@ class PaymentReturn(models.Model): _order = 'date DESC, id DESC' company_id = fields.Many2one( - 'res.company', 'Company', required=True, - help="Company", + 'res.company', string='Company', required=True, states={'done': [('readonly', True)], - 'cancelled': [('readonly', True)] - }, + 'cancelled': [('readonly', True)]}, default=lambda self: self.env['res.company']._company_default_get( 'account')) - date = fields.Date('Return date', - help="This date will be used as the date for the " - "account entry.", - states={'done': [('readonly', True)], - 'cancelled': [('readonly', True)]}, - default=lambda *x: fields.Date.today()) + date = fields.Date( + string='Return date', + help="This date will be used as the account entry date.", + states={'done': [('readonly', True)], + 'cancelled': [('readonly', True)]}, + default=lambda x: fields.Date.today()) name = fields.Char( - "Reference", size=64, required=True, + string="Reference", required=True, states={'done': [('readonly', True)], 'cancelled': [('readonly', True)]}, default=lambda self: self.env['ir.sequence'].next_by_code( 'payment.return')) - period_id = fields.Many2one('account.period', 'Forced period', - states={'done': [('readonly', True)], - 'cancelled': [('readonly', True)] - }) - line_ids = fields.One2many('payment.return.line', 'return_id', - states={'done': [('readonly', True)], - 'cancelled': [('readonly', True)] - }) - journal_id = fields.Many2one('account.journal', 'Bank journal', - required=True, - states={'done': [('readonly', True)], - 'cancelled': [('readonly', True)] - }) - move_id = fields.Many2one('account.move', - 'Reference to the created journal entry', - states={'done': [('readonly', True)], - 'cancelled': [('readonly', True)] - }) - notes = fields.Text('Notes') - state = fields.Selection([('draft', 'Draft'), - ('imported', 'Imported'), - ('done', 'Done'), - ('cancelled', 'Cancelled')], - 'State', readonly=True, default='draft', - track_visibility='onchange') + period_id = fields.Many2one( + comodel_name='account.period', string='Forced period', + states={'done': [('readonly', True)], + 'cancelled': [('readonly', True)]}) + line_ids = fields.One2many( + comodel_name='payment.return.line', inverse_name='return_id', + states={'done': [('readonly', True)], + 'cancelled': [('readonly', True)]}) + journal_id = fields.Many2one( + comodel_name='account.journal', string='Bank journal', required=True, + states={'done': [('readonly', True)], + 'cancelled': [('readonly', True)]}) + move_id = fields.Many2one( + comodel_name='account.move', + string='Reference to the created journal entry', + states={'done': [('readonly', True)], + 'cancelled': [('readonly', True)]}) + state = fields.Selection( + selection=[('draft', 'Draft'), + ('imported', 'Imported'), + ('done', 'Done'), + ('cancelled', 'Cancelled')], + string='State', readonly=True, default='draft', + track_visibility='onchange') def _get_invoices(self, move_lines): invoice_moves = self.env['account.move'] @@ -89,62 +87,48 @@ def _get_invoices(self, move_lines): @api.one def action_confirm(self): - move_obj = self.env['account.move'] # Check for incomplete lines - for return_line in self.line_ids: - if not return_line.move_line_id: - raise except_orm(_('Error!'), - _("You must complete all moves " - "references in the " - "payment return.")) - + if any(not x.move_line_id for x in self.line_ids): + raise UserError( + _("You must input all moves references in the payment " + "return.")) move = { 'name': '/', 'ref': _('Return %s') % self.name, 'journal_id': self.journal_id.id, 'date': self.date, 'company_id': self.company_id.id, + 'period_id': (self.period_id.id or self.period_id.with_context( + company_id=self.company_id.id).find(self.date).id), } - # Period - if self.period_id: - move['period_id'] = self.period_id.id - else: - move['period_id'] = self.period_id.with_context( - company_id=self.company_id.id).find(self.date).id - move_id = move_obj.create(move) + move_id = self.env['account.move'].create(move) for return_line in self.line_ids: move_line = return_line.move_line_id old_reconcile = move_line.reconcile_id lines2reconcile = old_reconcile.line_id invoices = self._get_invoices(lines2reconcile) - move_line_id = move_line.copy( + move_line2 = move_line.copy( default={ 'move_id': move_id.id, - 'ref': move['ref'], - 'date': move['date'], - 'period_id': move['period_id'], - 'journal_id': move['journal_id'], 'debit': return_line.amount, + 'name': move['ref'], 'credit': 0, }) - lines2reconcile += move_line_id - move_line_id.copy( + lines2reconcile += move_line2 + move_line2.copy( default={ 'debit': 0, 'credit': return_line.amount, - 'account_id': move_line.move_id.journal_id - .default_credit_account_id.id, + 'account_id': self.journal_id.default_credit_account_id.id, }) # Break old reconcile and # make a new one with at least three moves old_reconcile.unlink() lines2reconcile.reconcile_partial() - move_line = move_line_id - return_line.write({'reconcile_id': move_line - .reconcile_partial_id.id}) + return_line.write( + {'reconcile_id': move_line2.reconcile_partial_id.id}) # Mark invoice as payment refused - invoices.write({'payment_returned': True}) - + invoices.write({'returned_payment': True}) move_id.button_validate() self.write({'state': 'done', 'move_id': move_id.id}) return True @@ -154,6 +138,7 @@ def action_cancel(self): if not self.move_id: return True for return_line in self.line_ids: + invoices = self.env['account.invoice'] if return_line.reconcile_id: reconcile = return_line.reconcile_id lines2reconcile = reconcile.line_partial_ids.filtered( @@ -164,7 +149,7 @@ def action_cancel(self): lines2reconcile.reconcile() return_line.write({'reconcile_id': False}) # Remove payment refused flag on invoice - invoices.write({'payment_returned': False}) + invoices.write({'returned_payment': False}) self.move_id.button_cancel() self.move_id.unlink() self.write({'state': 'cancelled', 'move_id': False}) @@ -174,3 +159,41 @@ def action_cancel(self): def action_draft(self): self.write({'state': 'draft'}) return True + + +class PaymentReturnLine(models.Model): + _name = "payment.return.line" + _description = 'Payment return lines' + + return_id = fields.Many2one( + comodel_name='payment.return', string='Payment return', + required=True, ondelete='cascade') + concept = fields.Char( + string='Concept', + help="Read from imported file. Only for reference.") + reason = fields.Char( + string='Return reason', readonly=True, + help="Read from imported file. Only for reference.") + move_line_id = fields.Many2one( + comodel_name='account.move.line', string='Payment Reference') + date = fields.Date( + string='Return date', readonly=True, + help="Read from imported file. Only for reference.", + default=lambda x: fields.Date.today()) + partner_name = fields.Char( + string='Partner name', readonly=True, + help="Read from imported file. Only for reference.") + partner_id = fields.Many2one( + comodel_name='res.partner', string='Customer', + domain="[('customer', '=', True)]") + amount = fields.Float( + string='Amount', + help="Returned amount. Can be different from the move amount", + digits_compute=dp.get_precision('Account')) + reconcile_id = fields.Many2one( + comodel_name='account.move.reconcile', string='Reconcile', + help="Reference to the reconcile object.") + + @api.onchange('move_line_id') + def onchange_move_line(self): + self.amount = self.move_line_id.credit diff --git a/account_payment_return/models/payment_return_line.py b/account_payment_return/models/payment_return_line.py deleted file mode 100644 index d470eb6a0fd5..000000000000 --- a/account_payment_return/models/payment_return_line.py +++ /dev/null @@ -1,65 +0,0 @@ -# -*- encoding: utf-8 -*- -############################################################################## -# -# OpenERP, Open Source Management Solution -# Copyright (c) 2011-2012 7 i TRIA -# Copyright (c) 2011-2012 Avanzosc -# Copyright (c) 2013 Serv. Tecnol. Avanzados -# Pedro M. Baeza -# Copyright (c) 2014 initOS GmbH & Co. KG -# Markus Schneider -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU Affero General Public License as published -# by the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU Affero General Public License for more details. -# -# You should have received a copy of the GNU Affero General Public License -# along with this program. If not, see . -# -############################################################################## - -from openerp import models, fields, api -import openerp.addons.decimal_precision as dp - - -class PaymentReturnLine(models.Model): - _name = "payment.return.line" - _description = 'Payment return lines' - - return_id = fields.Many2one('payment.return', 'Payment return', - required=True, ondelete='cascade') - concept = fields.Char('Concept', - help="Readed from imported file. " - "Only for reference.") - reason = fields.Char('Return reason', - help="Readed from imported file. " - "Only for reference.") - move_line_id = fields.Many2one( - 'account.move.line', 'Payment Reference') - date = fields.Date('Return date', - help="Readed from imported file. " - "Only for reference.", - default=lambda *x: fields.Date.today()) - notes = fields.Text('Notes') - partner_name = fields.Char('Partner name', - help="Readed from imported file. " - "Only for reference.") - partner_id = fields.Many2one('res.partner', 'Customer', - domain="[('customer', '=', True)]") - amount = fields.Float('Amount', - help="Returned amount. Can be different from " - "the move amount", - digits_compute=dp.get_precision('Account')) - reconcile_id = fields.Many2one('account.move.reconcile', 'Reconcile', - help="Reference to the " - "reconcile object.") - - @api.onchange('move_line_id') - def onchange_move_line(self): - self.amount = self.move_line_id.credit diff --git a/account_payment_return/tests/__init__.py b/account_payment_return/tests/__init__.py index 973abd98e658..2d78b9b34ab7 100644 --- a/account_payment_return/tests/__init__.py +++ b/account_payment_return/tests/__init__.py @@ -1 +1,5 @@ +# -*- coding: utf-8 -*- +# (c) 2015 Serv. Tecnol. Avanzados - Pedro M. Baeza +# License AGPL-3 - See http://www.gnu.org/licenses/agpl-3.0.html + from . import test_payment_return diff --git a/account_payment_return/tests/test_payment_return.py b/account_payment_return/tests/test_payment_return.py index 27d64ec6226e..fdfa42015783 100644 --- a/account_payment_return/tests/test_payment_return.py +++ b/account_payment_return/tests/test_payment_return.py @@ -1,15 +1,81 @@ +# -*- coding: utf-8 -*- +# (c) 2015 Serv. Tecnol. Avanzados - Pedro M. Baeza +# License AGPL-3 - See http://www.gnu.org/licenses/agpl-3.0.html + +from openerp.exceptions import Warning as UserError from openerp.tests.common import TransactionCase -class TestPaymentReturn(TransactionCase): - """Tests for payment returns - Test used to check that when doing a payment return the result will be balanced. - """ +class TestPaymentReturn(TransactionCase): def setUp(self): - a = 3 super(TestPaymentReturn, self).setUp() - self.account_invoice_model = self.registry('account.invoice') + self.account_invoice_model = self.env['account.invoice'] + self.payment_return_model = self.env['payment.return'] + self.partner = self.env.ref('base.res_partner_1') + # Prepare invoice and pay it for making the return + self.invoice = self.env.ref('account.invoice_2') + self.invoice.journal_id.update_posted = True + self.invoice.signal_workflow('invoice_open') + self.receivable_line = self.invoice.move_id.line_id.filtered( + lambda x: x.account_id.type == 'receivable') + # Invert the move to simulate the payment + self.payment_move = self.invoice.move_id.copy() + for move_line in self.payment_move.line_id: + debit = move_line.debit + move_line.write({'debit': move_line.credit, + 'credit': debit}) + self.payment_line = self.payment_move.line_id.filtered( + lambda x: x.account_id.type == 'receivable') + # Reconcile both + self.reconcile = self.env['account.move.reconcile'].create( + {'type': 'manual', + 'line_id': [(4, self.payment_line.id), + (4, self.receivable_line.id)]}) + # Create payment return + self.payment_return = self.payment_return_model.create( + {'journal_id': self.env.ref('account.bank_journal').id, + 'line_ids': [ + (0, 0, {'partner_id': self.partner.id, + 'move_line_id': self.receivable_line.id, + 'amount': self.receivable_line.debit})]}) + self.payment_return.journal_id.update_posted = True + + def test_confirm_error(self): + self.payment_return.line_ids[0].move_line_id = False + with self.assertRaises(UserError): + self.payment_return.action_confirm() + + def test_onchange_move_line(self): + with self.env.do_in_onchange(): + record = self.env['payment.return.line'].new() + record.move_line_id = self.payment_line.id + record.onchange_move_line() + self.assertEqual(record.amount, self.payment_line.credit) + + def test_payment_return(self): + self.payment_return.action_cancel() # No effect + self.assertEqual(self.invoice.state, 'paid') + self.assertEqual(self.payment_return.state, 'draft') + self.payment_return.action_confirm() + self.assertEqual(self.payment_return.state, 'done') + self.assertEqual(self.invoice.state, 'open') + self.assertEqual(self.invoice.residual, self.receivable_line.debit) + self.assertEqual( + len(self.receivable_line.reconcile_partial_id.line_partial_ids), 3) + self.payment_return.action_cancel() + self.assertEqual(self.payment_return.state, 'cancelled') + self.assertEqual(self.invoice.state, 'paid') + self.payment_return.action_draft() + self.assertEqual(self.payment_return.state, 'draft') - def test_balanced_customer_invoice(self): - cr, uid = self.cr, self.uid + def test_payment_partial_return(self): + self.payment_return.line_ids[0].amount = 5.0 + self.assertEqual(self.invoice.state, 'paid') + self.payment_return.action_confirm() + self.assertEqual(self.invoice.state, 'open') + self.assertEqual(self.invoice.residual, 5.0) + self.assertEqual( + len(self.receivable_line.reconcile_partial_id.line_partial_ids), 3) + self.payment_return.action_cancel() + self.assertEqual(self.invoice.state, 'paid') diff --git a/account_payment_return/views/account_invoice_view.xml b/account_payment_return/views/account_invoice_view.xml index 122f6b8d1772..d16da993ad2a 100644 --- a/account_payment_return/views/account_invoice_view.xml +++ b/account_payment_return/views/account_invoice_view.xml @@ -9,7 +9,7 @@ - + @@ -22,8 +22,9 @@ - diff --git a/account_payment_return/views/payment_return_view.xml b/account_payment_return/views/payment_return_view.xml index 6cb1ec51613f..32f6751692ab 100644 --- a/account_payment_return/views/payment_return_view.xml +++ b/account_payment_return/views/payment_return_view.xml @@ -31,20 +31,15 @@ + domain="[('partner_id', '=', partner_id), + ('account_id.type', '=', 'receivable'), + ('credit', '>', 0.0), + ('reconcile_ref', '!=', False)]" + /> - - - - -
@@ -60,7 +55,7 @@ payment.return tree - + @@ -71,15 +66,17 @@ - Payment returns + Customer Payment Returns payment.return form tree,form - +