From cbff79040c16fc1166db17dbda9deb691c57f884 Mon Sep 17 00:00:00 2001 From: Carlos Dauden Date: Wed, 30 Nov 2016 19:47:37 +0100 Subject: [PATCH 1/4] [9.0][ADD] partner_payment_return_risk: New module --- partner_payment_return_risk/README.rst | 66 +++++++++++++++++++ partner_payment_return_risk/__init__.py | 3 + partner_payment_return_risk/__openerp__.py | 19 ++++++ .../models/__init__.py | 3 + .../models/res_partner.py | 33 ++++++++++ .../views/res_partner_view.xml | 20 ++++++ 6 files changed, 144 insertions(+) create mode 100644 partner_payment_return_risk/README.rst create mode 100644 partner_payment_return_risk/__init__.py create mode 100644 partner_payment_return_risk/__openerp__.py create mode 100644 partner_payment_return_risk/models/__init__.py create mode 100644 partner_payment_return_risk/models/res_partner.py create mode 100644 partner_payment_return_risk/views/res_partner_view.xml diff --git a/partner_payment_return_risk/README.rst b/partner_payment_return_risk/README.rst new file mode 100644 index 000000000..1b376a392 --- /dev/null +++ b/partner_payment_return_risk/README.rst @@ -0,0 +1,66 @@ +.. 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 + +=========================== +Partner Payment Return Risk +=========================== + +Extends Partner Financial Risk to manage payments returns. + +If any limit is exceed the partner gets forbidden to confirm sale orders. + + +Usage +===== + +To use this module, you need to: + +#. Go to *Customers > Financial Risk* +#. Set limits and choose options to compute in credit limit. +#. Create an invoice and pay it. +#. Create a payment return. +#. Go to *Sales -> Sales Orders* and create a new Sales Orders. + + +.. image:: https://odoo-community.org/website/image/ir.attachment/5784_f2813bd/datas + :alt: Try me on Runbot + :target: https://runbot.odoo-community.org/runbot/134/9.0 + + +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. + +Credits +======= + +Images +------ + +* Odoo Community Association: `Icon `_. + +Contributors +------------ + +* Carlos Dauden - Tecnativa + + +Maintainer +---------- + +.. image:: https://odoo-community.org/logo.png + :alt: Odoo Community Association + :target: https://odoo-community.org + +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. + +To contribute to this module, please visit https://odoo-community.org. \ No newline at end of file diff --git a/partner_payment_return_risk/__init__.py b/partner_payment_return_risk/__init__.py new file mode 100644 index 000000000..cde864bae --- /dev/null +++ b/partner_payment_return_risk/__init__.py @@ -0,0 +1,3 @@ +# -*- coding: utf-8 -*- + +from . import models diff --git a/partner_payment_return_risk/__openerp__.py b/partner_payment_return_risk/__openerp__.py new file mode 100644 index 000000000..8fe7a1c8a --- /dev/null +++ b/partner_payment_return_risk/__openerp__.py @@ -0,0 +1,19 @@ +# -*- coding: utf-8 -*- +# © 2016 Carlos Dauden - Tecnativa +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). +{ + 'name': 'Partner Payment Return Risk', + 'version': '9.0.1.0.0', + 'author': 'Tecnativa, ' + 'Odoo Community Association (OCA)', + 'category': 'Sales Management', + 'license': 'AGPL-3', + 'depends': [ + 'partner_financial_risk', + 'account_payment_return', + ], + 'data': [ + 'views/res_partner_view.xml', + ], + 'installable': True, +} diff --git a/partner_payment_return_risk/models/__init__.py b/partner_payment_return_risk/models/__init__.py new file mode 100644 index 000000000..f261da797 --- /dev/null +++ b/partner_payment_return_risk/models/__init__.py @@ -0,0 +1,3 @@ +# -*- coding: utf-8 -*- + +from . import res_partner diff --git a/partner_payment_return_risk/models/res_partner.py b/partner_payment_return_risk/models/res_partner.py new file mode 100644 index 000000000..ef0f57f88 --- /dev/null +++ b/partner_payment_return_risk/models/res_partner.py @@ -0,0 +1,33 @@ +# -*- coding: utf-8 -*- +# © 2016 Carlos Dauden +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +from openerp import api, fields, models + + +class ResPartner(models.Model): + _inherit = 'res.partner' + + risk_payment_return_include = fields.Boolean( + string='Include Payments Returns', help='Full risk computation') + risk_payment_return_limit = fields.Monetary( + string='Limit Payments Returns', help='Set 0 if it is not locked') + risk_payment_return = fields.Monetary( + compute='_compute_risk_payment_return', store=True, + string='Total Returned Invoices', + help='Total returned invoices in Open state') + + @api.multi + @api.depends('invoice_ids.state', 'invoice_ids.returned_payment') + def _compute_risk_payment_return(self): + for partner in self: + invoices = partner.invoice_ids.filtered( + lambda x: x.returned_payment and x.state == 'open') + partner.risk_payment_return = sum(invoices.mapped('residual')) + + @api.model + def _risk_field_list(self): + res = super(ResPartner, self)._risk_field_list() + res.append(('risk_payment_return', 'risk_payment_return_limit', + 'risk_payment_return_include')) + return res diff --git a/partner_payment_return_risk/views/res_partner_view.xml b/partner_payment_return_risk/views/res_partner_view.xml new file mode 100644 index 000000000..1349f131c --- /dev/null +++ b/partner_payment_return_risk/views/res_partner_view.xml @@ -0,0 +1,20 @@ + + + + + res.partner + + + + + + + + + + + + From 60a50f9273c75a20e9918e8f25c7f644f54b74d9 Mon Sep 17 00:00:00 2001 From: Carlos Dauden Date: Tue, 10 Jan 2017 19:23:59 +0100 Subject: [PATCH 2/4] [9.0][IMP] partner_payment_return_risk: Translate --- partner_payment_return_risk/i18n/es.po | 53 ++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) create mode 100644 partner_payment_return_risk/i18n/es.po diff --git a/partner_payment_return_risk/i18n/es.po b/partner_payment_return_risk/i18n/es.po new file mode 100644 index 000000000..f10d66e0f --- /dev/null +++ b/partner_payment_return_risk/i18n/es.po @@ -0,0 +1,53 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * partner_payment_return_risk +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 9.0c\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2017-01-10 18:34+0100\n" +"PO-Revision-Date: 2017-01-10 18:40+0100\n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" +"X-Generator: Poedit 1.8.7.1\n" +"Last-Translator: Carlos Dauden \n" +"Language: es_ES\n" + +#. module: partner_payment_return_risk +#: model:ir.model.fields,help:partner_payment_return_risk.field_res_partner_risk_payment_return_include +msgid "Full risk computation" +msgstr "Cálculo de riesgo completo" + +#. module: partner_payment_return_risk +#: model:ir.model.fields,field_description:partner_payment_return_risk.field_res_partner_risk_payment_return_include +msgid "Include Payments Returns" +msgstr "Incluir pagos devueltos" + +#. module: partner_payment_return_risk +#: model:ir.model.fields,field_description:partner_payment_return_risk.field_res_partner_risk_payment_return_limit +msgid "Limit Payments Returns" +msgstr "Límite en pagos devueltos" + +#. module: partner_payment_return_risk +#: model:ir.model,name:partner_payment_return_risk.model_res_partner +msgid "Partner" +msgstr "Empresa" + +#. module: partner_payment_return_risk +#: model:ir.model.fields,help:partner_payment_return_risk.field_res_partner_risk_payment_return_limit +msgid "Set 0 if it is not locked" +msgstr "Establece 0 si no está bloqueado" + +#. module: partner_payment_return_risk +#: model:ir.model.fields,field_description:partner_payment_return_risk.field_res_partner_risk_payment_return +msgid "Total Returned Invoices" +msgstr "Total facturas devueltas" + +#. module: partner_payment_return_risk +#: model:ir.model.fields,help:partner_payment_return_risk.field_res_partner_risk_payment_return +msgid "Total returned invoices in Open state" +msgstr "Total facturas devueltas en estado abierto" From 1cee545732e96ab0c65b42639b62f514a45b4d99 Mon Sep 17 00:00:00 2001 From: Carlos Dauden Date: Wed, 3 May 2017 17:27:12 +0200 Subject: [PATCH 3/4] [9.0][IMP] partner_payment_return_risk: Improve performance using search_group --- partner_payment_return_risk/models/res_partner.py | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/partner_payment_return_risk/models/res_partner.py b/partner_payment_return_risk/models/res_partner.py index ef0f57f88..3a1eb4892 100644 --- a/partner_payment_return_risk/models/res_partner.py +++ b/partner_payment_return_risk/models/res_partner.py @@ -20,10 +20,16 @@ class ResPartner(models.Model): @api.multi @api.depends('invoice_ids.state', 'invoice_ids.returned_payment') def _compute_risk_payment_return(self): + AccountInvoice = self.env['account.invoice'] for partner in self: - invoices = partner.invoice_ids.filtered( - lambda x: x.returned_payment and x.state == 'open') - partner.risk_payment_return = sum(invoices.mapped('residual')) + partner.risk_payment_return = AccountInvoice.read_group( + [('id', '=', partner.id), + ('returned_payment', '=', True), + ('state', '=', 'open'), + ], + ['residual'], + [] + )[0]['residual'] @api.model def _risk_field_list(self): From 628e8a3b1745f0cabb284aeb05a9af65085ed1af Mon Sep 17 00:00:00 2001 From: cubells Date: Tue, 9 May 2017 20:02:28 +0200 Subject: [PATCH 4/4] [IMP] Add tests and dependencies to pass travis and build runbot --- oca_dependencies.txt | 1 + .../models/res_partner.py | 2 +- partner_payment_return_risk/tests/__init__.py | 5 +++ .../tests/test_payment_return_risk.py | 38 +++++++++++++++++++ 4 files changed, 45 insertions(+), 1 deletion(-) create mode 100644 partner_payment_return_risk/tests/__init__.py create mode 100644 partner_payment_return_risk/tests/test_payment_return_risk.py diff --git a/oca_dependencies.txt b/oca_dependencies.txt index d8a2d4efc..2c2cd8f80 100644 --- a/oca_dependencies.txt +++ b/oca_dependencies.txt @@ -1 +1,2 @@ +account-payment product-attribute diff --git a/partner_payment_return_risk/models/res_partner.py b/partner_payment_return_risk/models/res_partner.py index 3a1eb4892..dc2481fec 100644 --- a/partner_payment_return_risk/models/res_partner.py +++ b/partner_payment_return_risk/models/res_partner.py @@ -23,7 +23,7 @@ class ResPartner(models.Model): AccountInvoice = self.env['account.invoice'] for partner in self: partner.risk_payment_return = AccountInvoice.read_group( - [('id', '=', partner.id), + [('partner_id', '=', partner.id), ('returned_payment', '=', True), ('state', '=', 'open'), ], diff --git a/partner_payment_return_risk/tests/__init__.py b/partner_payment_return_risk/tests/__init__.py new file mode 100644 index 000000000..c150b4ca9 --- /dev/null +++ b/partner_payment_return_risk/tests/__init__.py @@ -0,0 +1,5 @@ +# -*- coding: utf-8 -*- +# Copyright 2017 Carlos Dauden +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +from . import test_payment_return_risk diff --git a/partner_payment_return_risk/tests/test_payment_return_risk.py b/partner_payment_return_risk/tests/test_payment_return_risk.py new file mode 100644 index 000000000..70dcae599 --- /dev/null +++ b/partner_payment_return_risk/tests/test_payment_return_risk.py @@ -0,0 +1,38 @@ +# -*- coding: utf-8 -*- +# Copyright 2017 Carlos Dauden +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +from openerp.tests import common + + +class TestPartnerPaymentReturnRisk(common.SavepointCase): + + @classmethod + def setUpClass(cls): + super(TestPartnerPaymentReturnRisk, cls).setUpClass() + cls.partner = cls.env['res.partner'].create({ + 'name': 'Test partner', + 'risk_payment_return_include': True, + 'risk_payment_return_limit': 50.0, + }) + cls.user_type = cls.env.ref('account.data_account_type_revenue') + cls.invoice = cls.env['account.invoice'].create({ + 'partner_id': cls.partner.id, + 'invoice_line_ids': [(0, 0, { + 'name': 'Product Test', + 'quantity': 1.0, + 'uom_id': cls.env.ref('product.product_uom_unit').id, + 'price_unit': 100.0, + 'account_id': cls.env['account.account'].search([ + ('user_type_id', '=', cls.user_type.id)], limit=1).id, + })] + }) + + def test_payment_return_risk(self): + self.invoice.signal_workflow('invoice_open') + # Partner risk is zero because invoice is not returned + self.assertAlmostEqual(self.partner.risk_payment_return, 0.0) + # We simulate that the invoice is returned + self.invoice.returned_payment = True + # Partner risk has increased + self.assertAlmostEqual(self.partner.risk_payment_return, 100.0)