Browse Source

[9.0][IMP] partner_financial_risk: Improve performance (#385)

* [9.0][IMP] partner_financial_risk: Improve performance

* [9.0][IMP] partner_financial_risk: Improve tests and partner hierarchy

* [9.0][IMP] partner_stock_risk: Test
pull/330/head
Carlos Dauden 8 years ago
committed by Rafael Blasco
parent
commit
f2237b71bc
  1. 2
      partner_financial_risk/models/account_invoice.py
  2. 69
      partner_financial_risk/models/res_partner.py
  3. 80
      partner_financial_risk/tests/test_partner_financial_risk.py

2
partner_financial_risk/models/account_invoice.py

@ -13,7 +13,7 @@ class AccountInvoice(models.Model):
if self.env.context.get('bypass_risk', False):
return self.signal_workflow('invoice_open')
for invoice in self:
partner = invoice.partner_id
partner = invoice.partner_id.commercial_partner_id
exception_msg = ""
if partner.risk_exception:
exception_msg = _("Financial risk exceeded.\n")

69
partner_financial_risk/models/res_partner.py

@ -62,32 +62,54 @@ class ResPartner(models.Model):
is_editable = self.env.user.has_group(
'base.group_sale_manager') or self.env.user.has_group(
'account.group_account_manager')
for partner in self:
for partner in self.filtered('customer'):
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')
'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')
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:
return # pragma: no cover
max_date = self._max_risk_date_due()
for partner in self:
invoices_out = partner.invoice_ids.filtered(
lambda x: x.type in ['out_invoice', 'out_refund'])
invoices = invoices_out.filtered(
lambda x: x.state in ['draft', 'proforma', 'proforma2'])
partner.risk_invoice_draft = sum(invoices.mapped('amount_total'))
invoices = invoices_out.filtered(
lambda x: x.state == 'open' and x.date_due >= max_date)
partner.risk_invoice_open = sum(invoices.mapped('residual'))
invoices = invoices_out.filtered(
lambda x: x.state == 'open' and x.date_due < max_date)
partner.risk_invoice_unpaid = sum(invoices.mapped('residual'))
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'])],
['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')
@api.multi
@api.depends('credit', 'risk_invoice_open', 'risk_invoice_unpaid')
@api.depends('credit', 'risk_invoice_open', 'risk_invoice_unpaid',
'child_ids.credit', 'child_ids.risk_invoice_open',
'child_ids.risk_invoice_unpaid')
def _compute_risk_account_amount(self):
for partner in self:
for partner in self.filtered('customer'):
partner.risk_account_amount = (
partner.credit - partner.risk_invoice_open -
partner.risk_invoice_unpaid)
@ -96,7 +118,7 @@ class ResPartner(models.Model):
@api.depends(lambda x: x._get_depends_compute_risk_exception())
def _compute_risk_exception(self):
risk_field_list = self._risk_field_list()
for partner in self:
for partner in self.filtered('customer'):
amount = 0.0
for risk_field in risk_field_list:
field_value = getattr(partner, risk_field[0], 0.0)
@ -106,7 +128,7 @@ class ResPartner(models.Model):
if getattr(partner, risk_field[2], False):
amount += field_value
partner.risk_total = amount
if amount > partner.credit_limit:
if partner.credit_limit and amount > partner.credit_limit:
partner.risk_exception = True
@api.model
@ -129,12 +151,11 @@ class ResPartner(models.Model):
@api.model
def _get_depends_compute_risk_exception(self):
# TODO: Improve code without performance loss
tuple_list = self._risk_field_list()
res = [x[0] for x in tuple_list]
res.extend([x[1] for x in tuple_list])
res.extend([x[2] for x in tuple_list])
res.append('credit_limit')
res = []
for x in self._risk_field_list():
res.extend((x[0], x[1], x[2], 'child_ids.%s' % x[0],
'child_ids.%s' % x[1], 'child_ids.%s' % x[2]))
res.extend(('credit_limit', 'child_ids.credit_limit'))
return res
@api.model

80
partner_financial_risk/tests/test_partner_financial_risk.py

@ -2,54 +2,86 @@
# © 2016 Carlos Dauden <carlos.dauden@tecnativa.com>
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
from openerp.tests.common import TransactionCase
from openerp.tests.common import SavepointCase
from openerp import fields
class TestPartnerFinancialRisk(TransactionCase):
def setUp(self):
super(TestPartnerFinancialRisk, self).setUp()
self.env.user.groups_id |= self.env.ref('base.group_sale_manager')
self.partner = self.env['res.partner'].create({
class TestPartnerFinancialRisk(SavepointCase):
@classmethod
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,
})
self.journal = self.env['account.journal'].create({
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')
tax_group_taxes = cls.env.ref('account.tax_group_taxes')
cls.account_sale = cls.env['account.account'].create({
'name': 'Sale',
'code': 'XX_700',
'user_type_id': type_revenue.id,
'reconcile': True,
})
cls.account_customer = cls.env['account.account'].create({
'name': 'Customer',
'code': 'XX_430',
'user_type_id': type_payable.id,
'reconcile': True,
})
cls.journal_sale = cls.env['account.journal'].create({
'name': 'Test journal for sale',
'type': 'sale',
'name': 'Test Sales',
'code': 'TSALE',
'default_debit_account_id': cls.account_sale.id,
'default_credit_account_id': cls.account_sale.id,
})
cls.tax = cls.env['account.tax'].create({
'name': 'Tax for sale 10%',
'type_tax_use': 'sale',
'tax_group_id': tax_group_taxes.id,
'amount_type': 'percent',
'amount': 10.0,
})
self.prod_account = self.env.ref('account.demo_coffee_machine_account')
self.inv_account = self.env.ref('account.demo_sale_of_land_account')
self.invoice = self.env['account.invoice'].create({
'journal_id': self.journal.id,
'company_id': self.env.user.company_id.id,
'currency_id': self.env.user.company_id.currency_id.id,
'partner_id': self.partner.id,
cls.invoice = cls.env['account.invoice'].create({
'partner_id': cls.partner.id,
'account_id': cls.account_customer.id,
'type': 'out_invoice',
'journal_id': cls.journal_sale.id,
'payment_term_id': False,
'invoice_line_ids': [(0, 0, {
'account_id': self.prod_account.id,
'name': 'Test line',
'name': 'Test product',
'account_id': cls.account_sale.id,
'price_unit': 50,
'quantity': 10,
})]
'invoice_line_tax_ids': [(6, 0, [cls.tax.id])],
})],
})
def test_invoices(self):
self.partner.risk_invoice_draft_include = True
self.assertAlmostEqual(self.partner.risk_invoice_draft, 500.0)
self.assertAlmostEqual(self.partner.risk_total, 500.0)
self.assertAlmostEqual(self.partner.risk_invoice_draft, 550.0)
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)
self.partner.risk_invoice_unpaid_include = True
self.assertAlmostEqual(self.partner.risk_total, 500.0)
self.assertAlmostEqual(self.partner.risk_total, 550.0)
self.partner.credit_limit = 100.0
self.assertTrue(self.partner.risk_exception)
self.partner.credit_limit = 1000.0
self.partner.credit_limit = 1100.0
self.assertFalse(self.partner.risk_exception)
self.partner.risk_invoice_unpaid_limit = 499.0
self.assertTrue(self.partner.risk_exception)
invoice2 = self.invoice.copy()
invoice2 = self.invoice.copy({'partner_id': self.invoice_address.id})
self.assertAlmostEqual(self.partner.risk_invoice_draft, 550.0)
self.assertAlmostEqual(self.partner.risk_invoice_unpaid, 550.0)
wiz_dic = invoice2.invoice_open()
wiz = self.env[wiz_dic['res_model']].browse(wiz_dic['res_id'])
self.assertEqual(wiz.exception_msg, "Financial risk exceeded.\n")
@ -71,7 +103,7 @@ class TestPartnerFinancialRisk(TransactionCase):
"This invoice exceeds the financial risk.\n")
self.assertAlmostEqual(self.partner.risk_invoice_open, 0.0)
wiz.button_continue()
self.assertAlmostEqual(self.partner.risk_invoice_open, 500.0)
self.assertAlmostEqual(self.partner.risk_invoice_open, 550.0)
self.assertTrue(self.partner.risk_allow_edit)
self.partner.process_unpaid_invoices()
self.assertEqual(self.env['ir.config_parameter'].get_param(

Loading…
Cancel
Save