Browse Source

[FIX] partner_financial_risk: Invoice refunds add risk

- Refunds adds partner risk instead of reduce.
- If date_maturity changes to previous today date "never" compute partner risk.
pull/470/head
Carlos Dauden 7 years ago
committed by David
parent
commit
37c112897e
  1. 2
      partner_financial_risk/__manifest__.py
  2. 2
      partner_financial_risk/data/partner_financial_risk_data.xml
  3. 205
      partner_financial_risk/i18n/es.po
  4. 2
      partner_financial_risk/models/account_invoice.py
  5. 7
      partner_financial_risk/models/res_company.py
  6. 2
      partner_financial_risk/models/res_config.py
  7. 225
      partner_financial_risk/models/res_partner.py
  8. 71
      partner_financial_risk/tests/test_partner_financial_risk.py
  9. 2
      partner_financial_risk/views/res_config_view.xml
  10. 2
      partner_financial_risk/views/res_partner_view.xml
  11. 2
      partner_financial_risk/wizard/parner_risk_exceeded.py
  12. 2
      partner_financial_risk/wizard/partner_risk_exceeded_view.xml

2
partner_financial_risk/__manifest__.py

@ -1,5 +1,5 @@
# -*- coding: utf-8 -*-
# © 2016 Carlos Dauden <carlos.dauden@tecnativa.com>
# Copyright 2016 Carlos Dauden <carlos.dauden@tecnativa.com>
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
{

2
partner_financial_risk/data/partner_financial_risk_data.xml

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- © 2016 Carlos Dauden <carlos.dauden@tecnativa.com>
<!-- Copyright 2016 Carlos Dauden <carlos.dauden@tecnativa.com>
License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl-3). -->
<odoo>
<record id="ir_cron_due_invoice_every_day" model="ir.cron">

205
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 <carlos.dauden@tecnativa.com>, 2016
# Pedro M. Baeza <pedro.baeza@gmail.com>, 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 <pedro.baeza@gmail.com>\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 <carlos.dauden@tecnativa.com>\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

2
partner_financial_risk/models/account_invoice.py

@ -1,5 +1,5 @@
# -*- coding: utf-8 -*-
# © 2016 Carlos Dauden <carlos.dauden@tecnativa.com>
# Copyright 2016 Carlos Dauden <carlos.dauden@tecnativa.com>
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
from odoo import _, api, models

7
partner_financial_risk/models/res_company.py

@ -1,5 +1,5 @@
# -*- coding: utf-8 -*-
# © 2016 Carlos Dauden <carlos.dauden@tecnativa.com>
# Copyright 2016 Carlos Dauden <carlos.dauden@tecnativa.com>
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
from odoo import fields, models
@ -10,4 +10,7 @@ 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.",
)

2
partner_financial_risk/models/res_config.py

@ -1,5 +1,5 @@
# -*- coding: utf-8 -*-
# © 2016 Carlos Dauden <carlos.dauden@tecnativa.com>
# Copyright 2016 Carlos Dauden <carlos.dauden@tecnativa.com>
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
from odoo import fields, models

225
partner_financial_risk/models/res_partner.py

@ -10,6 +10,11 @@ from odoo 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(
@ -19,34 +24,77 @@ class ResPartner(models.Model):
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',
string='Total Risk', help='Sum of total risk included')
@ -65,53 +113,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())
@ -146,6 +235,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
@ -159,12 +250,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

71
partner_financial_risk/tests/test_partner_financial_risk.py

@ -2,28 +2,17 @@
# Copyright 2016 Carlos Dauden <carlos.dauden@tecnativa.com>
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
from odoo.tests import common
from odoo.tests.common import SavepointCase
from odoo import fields
class TestPartnerFinancialRisk(common.SavepointCase):
class TestPartnerFinancialRisk(SavepointCase):
@classmethod
def setUpClass(cls):
super(TestPartnerFinancialRisk, cls).setUpClass()
cls.env.user.groups_id |= cls.env.ref(
'account.group_account_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',
})
cls.env.user.groups_id |= cls.env.ref('account.group_account_manager')
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',
@ -34,10 +23,25 @@ class TestPartnerFinancialRisk(common.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.property_account_payable_id = cls.account_customer.id
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',
@ -57,11 +61,12 @@ class TestPartnerFinancialRisk(common.SavepointCase):
'account_id': cls.account_customer.id,
'type': 'out_invoice',
'journal_id': cls.journal_sale.id,
'payment_term_id': False,
'invoice_line_ids': [(0, 0, {
'name': 'Test product',
'account_id': cls.account_sale.id,
'price_unit': 50.0,
'quantity': 10.0,
'price_unit': 50,
'quantity': 10,
'invoice_line_tax_ids': [(6, 0, [cls.tax.id])],
})],
})
@ -72,7 +77,8 @@ class TestPartnerFinancialRisk(common.SavepointCase):
self.assertAlmostEqual(self.partner.risk_total, 550.0)
self.invoice.action_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
@ -111,3 +117,28 @@ class TestPartnerFinancialRisk(common.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)

2
partner_financial_risk/views/res_config_view.xml

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- © 2016 Carlos Dauden <carlos.dauden@tecnativa.com>
<!-- Copyright 2016 Carlos Dauden <carlos.dauden@tecnativa.com>
License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl-3). -->
<odoo>

2
partner_financial_risk/views/res_partner_view.xml

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- © 2016 Carlos Dauden <carlos.dauden@tecnativa.com>
<!-- Copyright 2016 Carlos Dauden <carlos.dauden@tecnativa.com>
License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl-3). -->
<odoo>

2
partner_financial_risk/wizard/parner_risk_exceeded.py

@ -1,5 +1,5 @@
# -*- coding: utf-8 -*-
# © 2016 Carlos Dauden <carlos.dauden@tecnativa.com>
# Copyright 2016 Carlos Dauden <carlos.dauden@tecnativa.com>
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
from odoo import _, api, fields, models

2
partner_financial_risk/wizard/partner_risk_exceeded_view.xml

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- © 2016 Carlos Dauden <carlos.dauden@tecnativa.com>
<!-- Copyright 2016 Carlos Dauden <carlos.dauden@tecnativa.com>
License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl-3). -->
<odoo>
<record id="partner_risk_exceeded_wizard" model="ir.ui.view">

Loading…
Cancel
Save