From 158bc9a0513de3e03a4c5af6ba35c38c6729e705 Mon Sep 17 00:00:00 2001 From: Carlos Dauden Date: Mon, 9 Oct 2017 00:50:24 +0200 Subject: [PATCH] [9.0][FIX] partner_financial_risk: Invoice refunds add risk. (#476) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * [9.0][FIX] partner_financial_risk: Invoice refunds add risk. Date_maturity change * [9.0][FIX] partner_financial_risk: Recompute when invoice_unpaid_margin change * [9.0][IMP] partner_financial_risk: Improve heritability * [9.0][IMP] partner_payment_return_risk: Unify with base method and split amount * [9.0][IMP] partner_financial_risk: Improve code. Include archived contacts * [9.0][WIP] partner_financial_risk: Different model in read_group list * [9.0][WIP] partner_financial_risk: Invoices amount from account.move.line * [9.0][WIP] partner_financial_risk: Change "©" to Copyright * [9.0][IMP] partner_financial_risk: invoice_unpaid_margin in depends * [9.0][IMP] partner_financial_risk: Descriptions and translation --- partner_financial_risk/__openerp__.py | 4 +- .../data/partner_financial_risk_data.xml | 4 +- partner_financial_risk/i18n/es.po | 205 +++++++++++++---- .../models/account_invoice.py | 2 +- partner_financial_risk/models/res_company.py | 6 +- partner_financial_risk/models/res_config.py | 2 +- partner_financial_risk/models/res_partner.py | 214 ++++++++++++------ .../tests/test_partner_financial_risk.py | 59 +++-- .../views/account_invoice_view.xml | 2 +- .../views/res_config_view.xml | 2 +- .../views/res_partner_view.xml | 7 +- .../wizard/parner_risk_exceeded.py | 2 +- .../wizard/partner_risk_exceeded_view.xml | 2 +- partner_payment_return_risk/README.rst | 2 +- partner_payment_return_risk/i18n/es.po | 30 +-- .../models/res_partner.py | 50 ++-- .../tests/test_payment_return_risk.py | 83 +++++-- .../views/res_partner_view.xml | 2 +- 18 files changed, 492 insertions(+), 186 deletions(-) diff --git a/partner_financial_risk/__openerp__.py b/partner_financial_risk/__openerp__.py index c38b2eae7..427a07019 100644 --- a/partner_financial_risk/__openerp__.py +++ b/partner_financial_risk/__openerp__.py @@ -1,11 +1,11 @@ # -*- coding: utf-8 -*- -# © 2016 Carlos Dauden +# Copyright 2016 Carlos Dauden # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). { 'name': 'Partner Financial Risk', 'summary': 'Manage partner risk', - 'version': '9.0.1.0.2', + 'version': '9.0.2.0.0', 'category': 'Sales Management', 'license': 'AGPL-3', 'author': 'Tecnativa, Odoo Community Association (OCA)', diff --git a/partner_financial_risk/data/partner_financial_risk_data.xml b/partner_financial_risk/data/partner_financial_risk_data.xml index 709db5ce4..9c8b70759 100644 --- a/partner_financial_risk/data/partner_financial_risk_data.xml +++ b/partner_financial_risk/data/partner_financial_risk_data.xml @@ -1,5 +1,5 @@ - @@ -12,4 +12,4 @@ - \ No newline at end of file + diff --git a/partner_financial_risk/i18n/es.po b/partner_financial_risk/i18n/es.po index b30a0361c..8fad7f8c4 100644 --- a/partner_financial_risk/i18n/es.po +++ b/partner_financial_risk/i18n/es.po @@ -1,7 +1,7 @@ # Translation of Odoo Server. # This file contains the translation of the following modules: # * partner_financial_risk -# +# # Translators: # Carlos Dauden , 2016 # Pedro M. Baeza , 2017 @@ -9,15 +9,22 @@ msgid "" msgstr "" "Project-Id-Version: partner-contact (9.0)\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2017-01-06 03:40+0000\n" -"PO-Revision-Date: 2017-01-05 18:28+0000\n" -"Last-Translator: Pedro M. Baeza \n" -"Language-Team: Spanish (http://www.transifex.com/oca/OCA-partner-contact-9-0/language/es/)\n" +"POT-Creation-Date: 2017-10-08 23:36+0200\n" +"PO-Revision-Date: 2017-10-08 23:39+0200\n" +"Last-Translator: Carlos Dauden \n" +"Language-Team: Spanish (http://www.transifex.com/oca/OCA-partner-contact-9-0/" +"language/es/)\n" +"Language: es\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: \n" -"Language: es\n" +"Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" +"X-Generator: Poedit 1.8.7.1\n" + +#. module: partner_financial_risk +#: model:ir.model.fields,field_description:partner_financial_risk.field_res_partner_move_line_ids +msgid "Account Moves" +msgstr "Apuntes contables" #. module: partner_financial_risk #: model:ir.ui.view,arch_db:partner_financial_risk.partner_risk_exceeded_wizard @@ -62,13 +69,13 @@ msgstr "Cliente" #. module: partner_financial_risk #: model:ir.model.fields,help:partner_financial_risk.field_account_config_settings_invoice_unpaid_margin #: model:ir.model.fields,help:partner_financial_risk.field_res_company_invoice_unpaid_margin -msgid "Days after due date to set an invoice as unpaid" -msgstr "Días después de la fecha de vencimiento para considerar una factura como impagada" - -#. module: partner_financial_risk -#: model:ir.model.fields,help:partner_financial_risk.field_res_partner_risk_account_amount -msgid "Difference between accounting credit and rest of totals" -msgstr "Diferencia entre el saldo contable y el resto de totales" +msgid "" +"Days after due date to set an invoice as unpaid.The change of this field " +"recompute all partners risk,be patient." +msgstr "" +"Días posteriores a la fecha de vencimiento para establecer una factura como " +"impagada. El cambio de este campo recalculará el riesgo de todos los " +"clientes, tenga paciencia." #. module: partner_financial_risk #: model:ir.model.fields,field_description:partner_financial_risk.field_partner_risk_exceeded_wiz_display_name @@ -98,12 +105,64 @@ msgid "Financial risk exceeded.\n" msgstr "Riesgo financiero excedido.\n" #. module: partner_financial_risk -#: model:ir.model.fields,help:partner_financial_risk.field_res_partner_risk_account_amount_include #: model:ir.model.fields,help:partner_financial_risk.field_res_partner_risk_invoice_draft_include -#: model:ir.model.fields,help:partner_financial_risk.field_res_partner_risk_invoice_open_include -#: model:ir.model.fields,help:partner_financial_risk.field_res_partner_risk_invoice_unpaid_include msgid "Full risk computation" -msgstr "Cómputo de riesgo total" +msgstr "Computar en riesgo total." + +#. module: partner_financial_risk +#: model:ir.model.fields,help:partner_financial_risk.field_res_partner_risk_account_amount_unpaid_include +msgid "" +"Full risk computation.\n" +"Residual amount of move lines not reconciled with distinct account that is " +"set as partner receivable and date maturity exceeded, considering Due Margin " +"set in account settings." +msgstr "" +"Computar en riesgo total.\n" +"Importe residual de apuntes no conciliados con cuenta distinta a la " +"establecida como cuenta a cobrar del cliente y fecha vencimiento excedida, " +"teniendo en cuenta los días de margen establecidos en la configuración de " +"contabilidad." + +#. module: partner_financial_risk +#: model:ir.model.fields,help:partner_financial_risk.field_res_partner_risk_account_amount_include +msgid "" +"Full risk computation.\n" +"Residual amount of move lines not reconciled with distinct account that is " +"set as partner receivable and date maturity not exceeded, considering Due " +"Margin set in account settings." +msgstr "" +"Computar en riesgo total.\n" +"Importe residual de apuntes no conciliados con cuenta distinta a la " +"establecida como cuenta a cobrar del cliente y fecha vencimiento no " +"excedida, teniendo en cuenta los días de margen establecidos en la " +"configuración de contabilidad." + +#. module: partner_financial_risk +#: model:ir.model.fields,help:partner_financial_risk.field_res_partner_risk_invoice_unpaid_include +msgid "" +"Full risk computation.\n" +"Residual amount of move lines not reconciled with the same account that is " +"set as partner receivable and date maturity exceeded, considering Due Margin " +"set in account settings." +msgstr "" +"Computar en riesgo total.\n" +"Importe residual de apuntes no conciliados con cuenta igual a la establecida " +"como cuenta a cobrar del cliente y fecha vencimiento excedida, teniendo en " +"cuenta los días de margen establecidos en la configuración de contabilidad." + +#. module: partner_financial_risk +#: model:ir.model.fields,help:partner_financial_risk.field_res_partner_risk_invoice_open_include +msgid "" +"Full risk computation.\n" +"Residual amount of move lines not reconciled with the same account that is " +"set as partner receivable and date maturity not exceeded, considering Due " +"Margin set in account settings." +msgstr "" +"Computar en riesgo total.\n" +"Importe residual de apuntes no conciliados con cuenta igual a la establecida " +"como cuenta a cobrar del cliente y fecha vencimiento no excedida, teniendo " +"en cuenta los días de margen establecidos en la configuración de " +"contabilidad." #. module: partner_financial_risk #: model:ir.ui.view,arch_db:partner_financial_risk.res_partner_view_risk @@ -122,18 +181,23 @@ msgstr "Incluir facturas borrador" #. module: partner_financial_risk #: model:ir.model.fields,field_description:partner_financial_risk.field_res_partner_risk_invoice_open_include -msgid "Include Open Invoices" -msgstr "Incluir facturas abiertas" +msgid "Include Open Invoices/Principal Balance" +msgstr "Incluir facturas/saldo principal abierto" #. module: partner_financial_risk #: model:ir.model.fields,field_description:partner_financial_risk.field_res_partner_risk_account_amount_include -msgid "Include Other Account Amount" -msgstr "Incluir otros saldos contables" +msgid "Include Other Account Open Amount" +msgstr "Incluir otro saldo contable abierto" + +#. module: partner_financial_risk +#: model:ir.model.fields,field_description:partner_financial_risk.field_res_partner_risk_account_amount_unpaid_include +msgid "Include Other Account Unpaid Amount" +msgstr "Incluir otro saldo contable impagado" #. module: partner_financial_risk #: model:ir.model.fields,field_description:partner_financial_risk.field_res_partner_risk_invoice_unpaid_include -msgid "Include Unpaid Invoices" -msgstr "Incluir facturas impagadas" +msgid "Include Unpaid Invoices/Principal Balance" +msgstr "Incluir facturas/saldo principal impagado" #. module: partner_financial_risk #: model:ir.ui.view,arch_db:partner_financial_risk.res_partner_view_risk @@ -150,6 +214,11 @@ msgstr "Factura" msgid "It Indicate if partner risk exceeded" msgstr "Indica si se ha excedido el riesgo" +#. module: partner_financial_risk +#: model:ir.model,name:partner_financial_risk.model_account_move_line +msgid "Journal Item" +msgstr "Apunte contable" + #. module: partner_financial_risk #: model:ir.model.fields,field_description:partner_financial_risk.field_partner_risk_exceeded_wiz___last_update msgid "Last Modified on" @@ -172,18 +241,23 @@ msgstr "Límite en facturas borrador" #. module: partner_financial_risk #: model:ir.model.fields,field_description:partner_financial_risk.field_res_partner_risk_invoice_open_limit -msgid "Limit In Open Invoices" -msgstr "Límite en facturas abiertas" +msgid "Limit In Open Invoices/Principal Balance" +msgstr "Límite en factures/saldo principal abierto" #. module: partner_financial_risk #: model:ir.model.fields,field_description:partner_financial_risk.field_res_partner_risk_invoice_unpaid_limit -msgid "Limit In Unpaid Invoices" -msgstr "Límite en facturas impagadas" +msgid "Limit In Unpaid Invoices/Principal Balance" +msgstr "Límite en factures/saldo principal impagado" #. module: partner_financial_risk #: model:ir.model.fields,field_description:partner_financial_risk.field_res_partner_risk_account_amount_limit -msgid "Limit Other Account Amount" -msgstr "Límite en otros saldos contables" +msgid "Limit Other Account Open Amount" +msgstr "Límite en otro saldo contable abierto" + +#. module: partner_financial_risk +#: model:ir.model.fields,field_description:partner_financial_risk.field_res_partner_risk_account_amount_unpaid_limit +msgid "Limit Other Account Unpaid Amount" +msgstr "Límite en otro saldo contable impagado" #. module: partner_financial_risk #: model:ir.model.fields,field_description:partner_financial_risk.field_account_config_settings_invoice_unpaid_margin @@ -196,11 +270,6 @@ msgstr "Margen vencimiento" msgid "Object" msgstr "Objeto" -#. module: partner_financial_risk -#: model:ir.model.fields,field_description:partner_financial_risk.field_res_partner_risk_account_amount -msgid "Other Account Amount" -msgstr "Otros saldos contables" - #. module: partner_financial_risk #: model:ir.model,name:partner_financial_risk.model_res_partner msgid "Partner" @@ -212,19 +281,52 @@ msgstr "Empresa" msgid "Partner risk exceeded" msgstr "Empresa con riesgo excedido" +#. module: partner_financial_risk +#: model:ir.model.fields,help:partner_financial_risk.field_res_partner_risk_account_amount_unpaid +msgid "" +"Residual amount of move lines not reconciled with distinct account that is " +"set as partner receivable and date maturity exceeded, considering Due Margin " +"set in account settings." +msgstr "" +"Importe residual de apuntes no conciliados con cuenta distinta a la " +"establecida como cuenta a cobrar del cliente y fecha vencimiento excedida, " +"teniendo en cuenta los días de margen establecidos en la configuración de " +"contabilidad." + +#. module: partner_financial_risk +#: model:ir.model.fields,help:partner_financial_risk.field_res_partner_risk_account_amount +msgid "" +"Residual amount of move lines not reconciled with distinct account that is " +"set as partner receivable and date maturity not exceeded, considering Due " +"Margin set in account settings." +msgstr "" +"Importe residual de apuntes no conciliados con cuenta distinta a la " +"establecida como cuenta a cobrar del cliente y fecha vencimiento no " +"excedida, teniendo en cuenta los días de margen establecidos en la " +"configuración de contabilidad." + #. module: partner_financial_risk #: model:ir.model.fields,help:partner_financial_risk.field_res_partner_risk_invoice_unpaid msgid "" -"Residual amount of invoices in Open state and the date due is exceeded, " -"considering Unpaid Margin set in account settings" -msgstr "Importe pendiente en facturas abiertas cuya fecha de vencimiento se ha excedido, considerando el margen de días establecido en configuración de contabilidad" +"Residual amount of move lines not reconciled with the same account that is " +"set as partner receivable and date maturity exceeded, considering Due Margin " +"set in account settings." +msgstr "" +"Importe residual de apuntes no conciliados con cuenta igual a la establecida " +"como cuenta a cobrar del cliente y fecha vencimiento excedida, teniendo en " +"cuenta los días de margen establecidos en la configuración de contabilidad." #. module: partner_financial_risk #: model:ir.model.fields,help:partner_financial_risk.field_res_partner_risk_invoice_open msgid "" -"Residual amount of invoices in Open state and the date due is not exceeded, " -"considering Due Margin set in account settings" -msgstr "Importe pendiente en facturas abiertas cuya fecha de vencimiento no se ha excedido, considerando el margen de días establecido en configuración de contabilidad" +"Residual amount of move lines not reconciled with the same account that is " +"set as partner receivable and date maturity not exceeded, considering Due " +"Margin set in account settings." +msgstr "" +"Importe residual de apuntes no conciliados con cuenta igual a la establecida " +"como cuenta a cobrar del cliente y fecha vencimiento no excedida, teniendo " +"en cuenta los días de margen establecidos en la configuración de " +"contabilidad." #. module: partner_financial_risk #: model:ir.model.fields,field_description:partner_financial_risk.field_res_partner_risk_exception @@ -243,6 +345,7 @@ msgstr "Riesgo excedido" #. module: partner_financial_risk #: model:ir.model.fields,help:partner_financial_risk.field_res_partner_risk_account_amount_limit +#: model:ir.model.fields,help:partner_financial_risk.field_res_partner_risk_account_amount_unpaid_limit #: model:ir.model.fields,help:partner_financial_risk.field_res_partner_risk_invoice_draft_limit #: model:ir.model.fields,help:partner_financial_risk.field_res_partner_risk_invoice_open_limit #: model:ir.model.fields,help:partner_financial_risk.field_res_partner_risk_invoice_unpaid_limit @@ -265,7 +368,7 @@ msgid "The partner has exceeded his risk" msgstr "La empresa ha excedido su riesgo" #. module: partner_financial_risk -#: code:addons/partner_financial_risk/models/account_invoice.py:28 +#: code:addons/partner_financial_risk/models/account_invoice.py:30 #, python-format msgid "This invoice exceeds the financial risk.\n" msgstr "Esta factura excede el riesgo financiero.\n" @@ -283,8 +386,18 @@ msgstr "Total facturas borrador" #. module: partner_financial_risk #: model:ir.model.fields,field_description:partner_financial_risk.field_res_partner_risk_invoice_open -msgid "Total Open Invoices" -msgstr "Total facturas borrador abiertas" +msgid "Total Open Invoices/Principal Balance" +msgstr "Total facturas/saldo principal abierto" + +#. module: partner_financial_risk +#: model:ir.model.fields,field_description:partner_financial_risk.field_res_partner_risk_account_amount +msgid "Total Other Account Open Amount" +msgstr "Total otro saldo contable abierto" + +#. module: partner_financial_risk +#: model:ir.model.fields,field_description:partner_financial_risk.field_res_partner_risk_account_amount_unpaid +msgid "Total Other Account Unpaid Amount" +msgstr "Total otro saldo contable impagado" #. module: partner_financial_risk #: model:ir.model.fields,field_description:partner_financial_risk.field_res_partner_risk_total @@ -293,8 +406,8 @@ msgstr "Riesgo total" #. module: partner_financial_risk #: model:ir.model.fields,field_description:partner_financial_risk.field_res_partner_risk_invoice_unpaid -msgid "Total Unpaid Invoices" -msgstr "Total facturas impagadas" +msgid "Total Unpaid Invoices/Principal Balance" +msgstr "Total facturas/saldo principal impagado" #. module: partner_financial_risk #: model:ir.model.fields,help:partner_financial_risk.field_res_partner_risk_invoice_draft diff --git a/partner_financial_risk/models/account_invoice.py b/partner_financial_risk/models/account_invoice.py index 843d60718..657b3b957 100644 --- a/partner_financial_risk/models/account_invoice.py +++ b/partner_financial_risk/models/account_invoice.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -# © 2016 Carlos Dauden +# Copyright 2016 Carlos Dauden # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). from openerp import api, models, _ diff --git a/partner_financial_risk/models/res_company.py b/partner_financial_risk/models/res_company.py index 667764ef3..b48a87da0 100644 --- a/partner_financial_risk/models/res_company.py +++ b/partner_financial_risk/models/res_company.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -# © 2016 Carlos Dauden +# Copyright 2016 Carlos Dauden # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). from openerp import fields, models @@ -10,4 +10,6 @@ class ResCompany(models.Model): invoice_unpaid_margin = fields.Integer( string="Maturity Margin", - help="Days after due date to set an invoice as unpaid") + help="Days after due date to set an invoice as unpaid." + "The change of this field recompute all partners risk," + "be patient.") diff --git a/partner_financial_risk/models/res_config.py b/partner_financial_risk/models/res_config.py index 213eca0a1..9c57296ed 100644 --- a/partner_financial_risk/models/res_config.py +++ b/partner_financial_risk/models/res_config.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -# © 2016 Carlos Dauden +# Copyright 2016 Carlos Dauden # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). from openerp import fields, models diff --git a/partner_financial_risk/models/res_partner.py b/partner_financial_risk/models/res_partner.py index f4e2297bb..f5a875b68 100644 --- a/partner_financial_risk/models/res_partner.py +++ b/partner_financial_risk/models/res_partner.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -# © 2016 Carlos Dauden +# Copyright 2016 Carlos Dauden # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). from datetime import datetime @@ -10,6 +10,11 @@ from openerp import api, fields, models class ResPartner(models.Model): _inherit = 'res.partner' + move_line_ids = fields.One2many( + comodel_name='account.move.line', + inverse_name='partner_id', + string='Account Moves' + ) risk_invoice_draft_include = fields.Boolean( string='Include Draft Invoices', help='Full risk computation') risk_invoice_draft_limit = fields.Monetary( @@ -18,34 +23,68 @@ class ResPartner(models.Model): compute='_compute_risk_invoice', store=True, string='Total Draft Invoices', help='Total amount of invoices in Draft or Pro-forma state') + risk_invoice_open_include = fields.Boolean( - string='Include Open Invoices', help='Full risk computation') + string='Include Open Invoices/Principal Balance', + help='Full risk computation.\n' + 'Residual amount of move lines not reconciled with the same ' + 'account that is set as partner receivable and date maturity ' + 'not exceeded, considering Due Margin set in account settings.') risk_invoice_open_limit = fields.Monetary( - string='Limit In Open Invoices', help='Set 0 if it is not locked') + string='Limit In Open Invoices/Principal Balance', + help='Set 0 if it is not locked') risk_invoice_open = fields.Monetary( - compute='_compute_risk_invoice', store=True, - string='Total Open Invoices', - help='Residual amount of invoices in Open state and the date due is ' - 'not exceeded, considering Due Margin set in account ' - 'settings') + compute='_compute_risk_account_amount', store=True, + string='Total Open Invoices/Principal Balance', + help='Residual amount of move lines not reconciled with the same ' + 'account that is set as partner receivable and date maturity ' + 'not exceeded, considering Due Margin set in account settings.') risk_invoice_unpaid_include = fields.Boolean( - string='Include Unpaid Invoices', help='Full risk computation') + string='Include Unpaid Invoices/Principal Balance', + help='Full risk computation.\n' + 'Residual amount of move lines not reconciled with the same ' + 'account that is set as partner receivable and date maturity ' + 'exceeded, considering Due Margin set in account settings.') risk_invoice_unpaid_limit = fields.Monetary( - string='Limit In Unpaid Invoices', help='Set 0 if it is not locked') + string='Limit In Unpaid Invoices/Principal Balance', + help='Set 0 if it is not locked') risk_invoice_unpaid = fields.Monetary( - compute='_compute_risk_invoice', store=True, - string='Total Unpaid Invoices', - help='Residual amount of invoices in Open state and the date due is ' - 'exceeded, considering Unpaid Margin set in account settings') + compute='_compute_risk_account_amount', store=True, + string='Total Unpaid Invoices/Principal Balance', + help='Residual amount of move lines not reconciled with the same ' + 'account that is set as partner receivable and date maturity ' + 'exceeded, considering Due Margin set in account settings.') risk_account_amount_include = fields.Boolean( - string='Include Other Account Amount', help='Full risk computation') + string='Include Other Account Open Amount', + help='Full risk computation.\n' + 'Residual amount of move lines not reconciled with distinct ' + 'account that is set as partner receivable and date maturity ' + 'not exceeded, considering Due Margin set in account settings.') risk_account_amount_limit = fields.Monetary( - string='Limit Other Account Amount', help='Set 0 if it is not locked') + string='Limit Other Account Open Amount', + help='Set 0 if it is not locked') risk_account_amount = fields.Monetary( - compute='_compute_risk_account_amount', - string='Other Account Amount', - help='Difference between accounting credit and rest of totals') + compute='_compute_risk_account_amount', store=True, + string='Total Other Account Open Amount', + help='Residual amount of move lines not reconciled with distinct ' + 'account that is set as partner receivable and date maturity ' + 'not exceeded, considering Due Margin set in account settings.') + risk_account_amount_unpaid_include = fields.Boolean( + string='Include Other Account Unpaid Amount', + help='Full risk computation.\n' + 'Residual amount of move lines not reconciled with distinct ' + 'account that is set as partner receivable and date maturity ' + 'exceeded, considering Due Margin set in account settings.') + risk_account_amount_unpaid_limit = fields.Monetary( + string='Limit Other Account Unpaid Amount', + help='Set 0 if it is not locked') + risk_account_amount_unpaid = fields.Monetary( + compute='_compute_risk_account_amount', store=True, + string='Total Other Account Unpaid Amount', + help='Residual amount of move lines not reconciled with distinct ' + 'account that is set as partner receivable and date maturity ' + 'exceeded, considering Due Margin set in account settings.') risk_total = fields.Monetary( compute='_compute_risk_exception', @@ -67,53 +106,94 @@ class ResPartner(models.Model): partner.risk_allow_edit = is_editable @api.multi - @api.depends('invoice_ids', 'invoice_ids.state', - 'invoice_ids.amount_total', 'invoice_ids.residual', - 'invoice_ids.company_id.invoice_unpaid_margin', - 'child_ids.invoice_ids', 'child_ids.invoice_ids.state', - 'child_ids.invoice_ids.amount_total', - 'child_ids.invoice_ids.residual', - 'child_ids.invoice_ids.company_id.invoice_unpaid_margin') + @api.depends( + 'invoice_ids', 'invoice_ids.state', + 'invoice_ids.amount_total', + 'child_ids.invoice_ids', 'child_ids.invoice_ids.state', + 'child_ids.invoice_ids.amount_total') def _compute_risk_invoice(self): - def sum_group(group, field): - return sum([x[field] for x in group if - x['partner_id'][0] in partner_ids]) - customers = self.filtered('customer') - if not customers: + all_partners_and_children = {} + all_partner_ids = [] + for partner in self.filtered('customer'): + all_partners_and_children[partner] = self.with_context( + active_test=False).search([('id', 'child_of', partner.id)]).ids + all_partner_ids += all_partners_and_children[partner] + if not all_partner_ids: return # pragma: no cover - max_date = self._max_risk_date_due() - AccountInvoice = self.env['account.invoice'] - partners = customers | customers.mapped('child_ids') - domain = [('type', 'in', ['out_invoice', 'out_refund']), - ('partner_id', 'in', partners.ids)] - draft_group = AccountInvoice.read_group( - domain + [('state', 'in', ['draft', 'proforma', 'proforma2'])], + total_group = self.env['account.invoice'].sudo().read_group( + [('type', 'in', ['out_invoice', 'out_refund']), + ('state', 'in', ['draft', 'proforma', 'proforma2']), + ('partner_id', 'in', self.ids)], ['partner_id', 'amount_total'], ['partner_id']) - open_group = AccountInvoice.read_group( - domain + [('state', '=', 'open'), ('date_due', '>=', max_date)], - ['partner_id', 'residual'], - ['partner_id']) - unpaid_group = AccountInvoice.read_group( - domain + [('state', '=', 'open'), '|', - ('date_due', '=', False), ('date_due', '<', max_date)], - ['partner_id', 'residual'], - ['partner_id']) - for partner in customers: - partner_ids = (partner | partner.child_ids).ids - partner.risk_invoice_draft = sum_group(draft_group, 'amount_total') - partner.risk_invoice_open = sum_group(open_group, 'residual') - partner.risk_invoice_unpaid = sum_group(unpaid_group, 'residual') + for partner, child_ids in all_partners_and_children.items(): + partner.risk_invoice_draft = sum( + x['amount_total'] + for x in total_group if x['partner_id'][0] in child_ids) + + @api.model + def _risk_account_groups(self): + max_date = self._max_risk_date_due() + return { + 'open': { + 'domain': [('reconciled', '=', False), + ('account_id.internal_type', '=', 'receivable'), + ('date_maturity', '>=', max_date)], + 'fields': ['partner_id', 'account_id', 'amount_residual'], + 'group_by': ['partner_id', 'account_id'] + }, + 'unpaid': { + 'domain': [('reconciled', '=', False), + ('account_id.internal_type', '=', 'receivable'), + ('date_maturity', '<', max_date)], + 'fields': ['partner_id', 'account_id', 'amount_residual'], + 'group_by': ['partner_id', 'account_id'] + } + } @api.multi - @api.depends('credit', 'risk_invoice_open', 'risk_invoice_unpaid', - 'child_ids.credit', 'child_ids.risk_invoice_open', - 'child_ids.risk_invoice_unpaid') + @api.depends('move_line_ids.amount_residual', + 'move_line_ids.date_maturity', + 'company_id.invoice_unpaid_margin') def _compute_risk_account_amount(self): - for partner in self.filtered('customer'): - partner.risk_account_amount = ( - partner.credit - partner.risk_invoice_open - - partner.risk_invoice_unpaid) + AccountMoveLine = self.env['account.move.line'].sudo() + customers = self.filtered(lambda x: x.customer and not x.parent_id) + if not customers: + return + groups = self._risk_account_groups() + for key, group in groups.iteritems(): + group['read_group'] = AccountMoveLine.read_group( + group['domain'] + [('partner_id', 'in', customers.ids)], + group['fields'], + group['group_by'], + lazy=False, + ) + for partner in customers: + partner.update(partner._prepare_risk_account_vals(groups)) + + @api.multi + def _prepare_risk_account_vals(self, groups): + vals = { + 'risk_invoice_open': 0.0, + 'risk_invoice_unpaid': 0.0, + 'risk_account_amount': 0.0, + 'risk_account_amount_unpaid': 0.0, + } + for reg in groups['open']['read_group']: + if reg['partner_id'][0] != self.id: + continue + if self.property_account_receivable_id.id == reg['account_id'][0]: + vals['risk_invoice_open'] += reg['amount_residual'] + else: + vals['risk_account_amount'] += reg['amount_residual'] + for reg in groups['unpaid']['read_group']: + if reg['partner_id'][0] != self.id: + continue # pragma: no cover + if self.property_account_receivable_id.id == reg['account_id'][0]: + vals['risk_invoice_unpaid'] += reg['amount_residual'] + else: + vals['risk_account_amount_unpaid'] += reg['amount_residual'] + return vals @api.multi @api.depends(lambda x: x._get_depends_compute_risk_exception()) @@ -148,6 +228,8 @@ class ResPartner(models.Model): 'risk_invoice_unpaid_include'), ('risk_account_amount', 'risk_account_amount_limit', 'risk_account_amount_include'), + ('risk_account_amount_unpaid', 'risk_account_amount_unpaid_limit', + 'risk_account_amount_unpaid_include'), ] @api.model @@ -161,12 +243,16 @@ class ResPartner(models.Model): @api.model def process_unpaid_invoices(self): - today = fields.Date.today() + max_date = self._max_risk_date_due() ConfigParameter = self.env['ir.config_parameter'] last_check = ConfigParameter.get_param( 'partner_financial_risk.last_check', default='2016-01-01') - invoices = self.env['account.invoice'].search([ - ('date_due', '>=', last_check), ('date_due', '<', today)]) - invoices.mapped('partner_id')._compute_risk_invoice() - ConfigParameter.set_param('partner_financial_risk.last_check', today) + move_lines = self.env['account.move.line'].search([ + ('reconciled', '=', False), + ('account_id.internal_type', '=', 'receivable'), + ('date_maturity', '>=', last_check), + ('date_maturity', '<', max_date)]) + move_lines.mapped('partner_id')._compute_risk_account_amount() + ConfigParameter.set_param( + 'partner_financial_risk.last_check', max_date) return True diff --git a/partner_financial_risk/tests/test_partner_financial_risk.py b/partner_financial_risk/tests/test_partner_financial_risk.py index d03a93641..241fbff77 100644 --- a/partner_financial_risk/tests/test_partner_financial_risk.py +++ b/partner_financial_risk/tests/test_partner_financial_risk.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -# © 2016 Carlos Dauden +# Copyright 2016 Carlos Dauden # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). from openerp.tests.common import SavepointCase @@ -11,17 +11,8 @@ class TestPartnerFinancialRisk(SavepointCase): def setUpClass(cls): super(TestPartnerFinancialRisk, cls).setUpClass() cls.env.user.groups_id |= cls.env.ref('base.group_sale_manager') - cls.partner = cls.env['res.partner'].create({ - 'name': 'Partner test', - 'customer': True, - }) - cls.invoice_address = cls.env['res.partner'].create({ - 'name': 'Partner test invoice', - 'parent_id': cls.partner.id, - 'type': 'invoice', - }) type_revenue = cls.env.ref('account.data_account_type_revenue') - type_payable = cls.env.ref('account.data_account_type_payable') + type_receivable = cls.env.ref('account.data_account_type_receivable') tax_group_taxes = cls.env.ref('account.tax_group_taxes') cls.account_sale = cls.env['account.account'].create({ 'name': 'Sale', @@ -32,9 +23,25 @@ class TestPartnerFinancialRisk(SavepointCase): cls.account_customer = cls.env['account.account'].create({ 'name': 'Customer', 'code': 'XX_430', - 'user_type_id': type_payable.id, + 'user_type_id': type_receivable.id, + 'reconcile': True, + }) + cls.other_account_customer = cls.env['account.account'].create({ + 'name': 'Other Account Customer', + 'code': 'XX_431', + 'user_type_id': type_receivable.id, 'reconcile': True, }) + cls.partner = cls.env['res.partner'].create({ + 'name': 'Partner test', + 'customer': True, + 'property_account_receivable_id': cls.account_customer.id, + }) + cls.invoice_address = cls.env['res.partner'].create({ + 'name': 'Partner test invoice', + 'parent_id': cls.partner.id, + 'type': 'invoice', + }) cls.journal_sale = cls.env['account.journal'].create({ 'name': 'Test journal for sale', 'type': 'sale', @@ -70,7 +77,8 @@ class TestPartnerFinancialRisk(SavepointCase): self.assertAlmostEqual(self.partner.risk_total, 550.0) self.invoice.signal_workflow('invoice_open') self.assertAlmostEqual(self.partner.risk_invoice_draft, 0.0) - self.assertFalse(self.invoice.date_due) + line = self.invoice.move_id.line_ids.filtered(lambda x: x.debit != 0.0) + line.date_maturity = '2017-01-01' self.partner.risk_invoice_unpaid_include = True self.assertAlmostEqual(self.partner.risk_total, 550.0) self.partner.credit_limit = 100.0 @@ -109,3 +117,28 @@ class TestPartnerFinancialRisk(SavepointCase): self.assertEqual(self.env['ir.config_parameter'].get_param( 'partner_financial_risk.last_check'), fields.Date.today()) + + def test_other_account_amount(self): + self.move = self.env['account.move'].create({ + 'journal_id': self.journal_sale.id, + 'date': fields.Date.today(), + 'line_ids': [ + (0, 0, { + 'name': 'Debit line', + 'partner_id': self.partner.id, + 'account_id': self.other_account_customer.id, + 'debit': 100, + }), + (0, 0, { + 'name': 'Credit line', + 'partner_id': self.partner.id, + 'account_id': self.account_sale.id, + 'credit': 100, + }), + ], + }) + self.assertAlmostEqual(self.partner.risk_account_amount, 100.0) + line = self.move.line_ids.filtered(lambda x: x.debit != 0.0) + line.date_maturity = '2017-01-01' + self.assertAlmostEqual(self.partner.risk_account_amount, 0.0) + self.assertAlmostEqual(self.partner.risk_account_amount_unpaid, 100.0) diff --git a/partner_financial_risk/views/account_invoice_view.xml b/partner_financial_risk/views/account_invoice_view.xml index 273b507d0..177b344dc 100644 --- a/partner_financial_risk/views/account_invoice_view.xml +++ b/partner_financial_risk/views/account_invoice_view.xml @@ -1,5 +1,5 @@ - diff --git a/partner_financial_risk/views/res_config_view.xml b/partner_financial_risk/views/res_config_view.xml index 30158e6c7..faea3f750 100644 --- a/partner_financial_risk/views/res_config_view.xml +++ b/partner_financial_risk/views/res_config_view.xml @@ -1,5 +1,5 @@ - diff --git a/partner_financial_risk/views/res_partner_view.xml b/partner_financial_risk/views/res_partner_view.xml index f3bf24d2b..f3880f33b 100644 --- a/partner_financial_risk/views/res_partner_view.xml +++ b/partner_financial_risk/views/res_partner_view.xml @@ -1,5 +1,5 @@ - @@ -26,6 +26,9 @@ + + @@ -39,6 +42,8 @@ attrs="{'readonly': [('risk_allow_edit', '=', False)]}"/> + diff --git a/partner_financial_risk/wizard/parner_risk_exceeded.py b/partner_financial_risk/wizard/parner_risk_exceeded.py index e110569b5..4531d2ced 100644 --- a/partner_financial_risk/wizard/parner_risk_exceeded.py +++ b/partner_financial_risk/wizard/parner_risk_exceeded.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -# © 2016 Carlos Dauden +# Copyright 2016 Carlos Dauden # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). from openerp import api, fields, models, _ diff --git a/partner_financial_risk/wizard/partner_risk_exceeded_view.xml b/partner_financial_risk/wizard/partner_risk_exceeded_view.xml index 5f1b19648..1bf3edeaf 100644 --- a/partner_financial_risk/wizard/partner_risk_exceeded_view.xml +++ b/partner_financial_risk/wizard/partner_risk_exceeded_view.xml @@ -1,5 +1,5 @@ - diff --git a/partner_payment_return_risk/README.rst b/partner_payment_return_risk/README.rst index 1b376a392..b3c689351 100644 --- a/partner_payment_return_risk/README.rst +++ b/partner_payment_return_risk/README.rst @@ -63,4 +63,4 @@ 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 +To contribute to this module, please visit https://odoo-community.org. diff --git a/partner_payment_return_risk/i18n/es.po b/partner_payment_return_risk/i18n/es.po index f10d66e0f..88962ce06 100644 --- a/partner_payment_return_risk/i18n/es.po +++ b/partner_payment_return_risk/i18n/es.po @@ -6,21 +6,25 @@ 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" +"POT-Creation-Date: 2017-10-08 23:50+0200\n" +"PO-Revision-Date: 2017-10-08 23:53+0200\n" +"Last-Translator: Carlos Dauden \n" "Language-Team: \n" +"Language: es_ES\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" +msgid "" +"Full risk computation.\n" +"Residual amount of move lines not reconciled with returned lines related." +msgstr "" +"Computar en riesgo total.\n" +"Importe residual de apuntes no conciliados relacionados con apuntes devueltos." #. module: partner_payment_return_risk #: model:ir.model.fields,field_description:partner_payment_return_risk.field_res_partner_risk_payment_return_include @@ -37,6 +41,11 @@ msgstr "Límite en pagos devueltos" msgid "Partner" msgstr "Empresa" +#. module: partner_payment_return_risk +#: model:ir.model.fields,help:partner_payment_return_risk.field_res_partner_risk_payment_return +msgid "Residual amount of move lines not reconciled with returned lines related." +msgstr "Importe residual de apuntes no conciliados relacionados con apuntes devueltos." + #. 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" @@ -44,10 +53,5 @@ 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" +msgid "Total Payments Returns" +msgstr "Total pagos devueltos" diff --git a/partner_payment_return_risk/models/res_partner.py b/partner_payment_return_risk/models/res_partner.py index dc2481fec..16ccba941 100644 --- a/partner_payment_return_risk/models/res_partner.py +++ b/partner_payment_return_risk/models/res_partner.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -# © 2016 Carlos Dauden +# Copyright 2016 Carlos Dauden # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). from openerp import api, fields, models @@ -9,27 +9,43 @@ class ResPartner(models.Model): _inherit = 'res.partner' risk_payment_return_include = fields.Boolean( - string='Include Payments Returns', help='Full risk computation') + string='Include Payments Returns', + help='Full risk computation.\n' + 'Residual amount of move lines not reconciled with returned ' + 'lines related.') 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') + compute='_compute_risk_account_amount', store=True, + string='Total Payments Returns', + help='Residual amount of move lines not reconciled with returned ' + 'lines related.') + + @api.model + def _risk_account_groups(self): + res = super(ResPartner, self)._risk_account_groups() + res['open']['domain'] += [ + ('partial_reconcile_returned_ids', '=', False), + ] + res['unpaid']['domain'] += [ + ('partial_reconcile_returned_ids', '=', False), + ] + res['returned'] = { + 'domain': [('reconciled', '=', False), + ('account_id.internal_type', '=', 'receivable'), + ('partial_reconcile_returned_ids', '!=', False)], + 'fields': ['partner_id', 'account_id', 'amount_residual'], + 'group_by': ['partner_id', 'account_id'] + } + return res @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: - partner.risk_payment_return = AccountInvoice.read_group( - [('partner_id', '=', partner.id), - ('returned_payment', '=', True), - ('state', '=', 'open'), - ], - ['residual'], - [] - )[0]['residual'] + def _prepare_risk_account_vals(self, groups): + vals = super(ResPartner, self)._prepare_risk_account_vals(groups) + vals['risk_payment_return'] = sum( + reg['amount_residual'] for reg in groups['returned']['read_group'] + if reg['partner_id'][0] == self.id) + return vals @api.model def _risk_field_list(self): diff --git a/partner_payment_return_risk/tests/test_payment_return_risk.py b/partner_payment_return_risk/tests/test_payment_return_risk.py index 70dcae599..9385191f0 100644 --- a/partner_payment_return_risk/tests/test_payment_return_risk.py +++ b/partner_payment_return_risk/tests/test_payment_return_risk.py @@ -6,33 +6,80 @@ 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.journal = cls.env['account.journal'].create({ + 'name': 'Test Sales Journal', + 'code': 'tVEN', + 'type': 'sale', + 'update_posted': True, + }) + cls.bank_journal = cls.env['account.journal'].create({ + 'name': 'Test Bank Journal', + 'code': 'BANK', + 'type': 'bank', + 'update_posted': True, + }) + cls.account_type = cls.env['account.account.type'].create({ + 'name': 'Test', + 'type': 'receivable', + }) + cls.account = cls.env['account.account'].create({ + 'name': 'Test account', + 'code': 'TEST', + 'user_type_id': cls.account_type.id, + 'reconcile': True, }) - cls.user_type = cls.env.ref('account.data_account_type_revenue') + cls.account_income = cls.env['account.account'].create({ + 'name': 'Test income account', + 'code': 'INCOME', + 'user_type_id': cls.env['account.account.type'].create( + {'name': 'Test income'}).id, + }) + cls.partner = cls.env['res.partner'].create({'name': 'Test'}) cls.invoice = cls.env['account.invoice'].create({ + 'journal_id': cls.journal.id, + 'account_id': cls.account.id, + 'company_id': cls.env.user.company_id.id, + 'currency_id': cls.env.user.company_id.currency_id.id, '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, + 'account_id': cls.account_income.id, + 'name': 'Test line', + 'price_unit': 50, + 'quantity': 10, })] }) + cls.reason = cls.env['payment.return.reason'].create({ + 'code': 'RTEST', + 'name': 'Reason Test' + }) + cls.invoice.signal_workflow('invoice_open') + cls.receivable_line = cls.invoice.move_id.line_ids.filtered( + lambda x: x.account_id.internal_type == 'receivable') + # Invert the move to simulate the payment + cls.payment_move = cls.invoice.move_id.copy({ + 'journal_id': cls.bank_journal.id + }) + for move_line in cls.payment_move.line_ids: + move_line.with_context(check_move_validity=False).write({ + 'debit': move_line.credit, 'credit': move_line.debit}) + cls.payment_line = cls.payment_move.line_ids.filtered( + lambda x: x.account_id.internal_type == 'receivable') + # Reconcile both + (cls.receivable_line | cls.payment_line).reconcile() + # Create payment return + cls.payment_return = cls.env['payment.return'].create( + {'journal_id': cls.bank_journal.id, + 'line_ids': [ + (0, 0, {'partner_id': cls.partner.id, + 'move_line_ids': [(6, 0, cls.payment_line.ids)], + 'amount': cls.payment_line.credit})]}) 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) + self.payment_return.action_confirm() + self.assertAlmostEqual(self.partner.risk_payment_return, 500.0) + self.payment_return.action_cancel() + self.assertAlmostEqual(self.partner.risk_payment_return, 0.0) diff --git a/partner_payment_return_risk/views/res_partner_view.xml b/partner_payment_return_risk/views/res_partner_view.xml index 1349f131c..64fd72985 100644 --- a/partner_payment_return_risk/views/res_partner_view.xml +++ b/partner_payment_return_risk/views/res_partner_view.xml @@ -1,5 +1,5 @@ -