Browse Source

[BACKPORT][8.0] partner_sale_risk

pull/391/head
Andhitia Rama 8 years ago
parent
commit
f2f658fa11
  1. 3
      partner_sale_risk/README.rst
  2. 2
      partner_sale_risk/__openerp__.py
  3. 7
      partner_sale_risk/models/res_partner.py
  4. 60
      partner_sale_risk/models/sale.py
  5. 5
      partner_sale_risk/tests/__init__.py
  6. 138
      partner_sale_risk/tests/test_partner_sale_risk.py
  7. 6
      partner_sale_risk/views/res_partner_view.xml
  8. 8
      partner_sale_risk/views/sale_view.xml

3
partner_sale_risk/README.rst

@ -22,7 +22,7 @@ To use this module, you need to:
.. 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
:target: https://runbot.odoo-community.org/runbot/134/8.0
Bug Tracker
@ -42,6 +42,7 @@ Contributors
* Carlos Dauden <carlos.dauden@tecnativa.com>
* Pedro M. Baeza <pedro.baeza@tecnativa.com>
* Andhitia Rama <andhitia.r@gmail.com>
Maintainer

2
partner_sale_risk/__openerp__.py

@ -5,7 +5,7 @@
{
'name': 'Partner Sale Risk',
'summary': 'Manage partner risk in sales orders',
'version': '9.0.1.0.0',
'version': '8.0.1.0.0',
'category': 'Sales Management',
'license': 'AGPL-3',
'author': 'Tecnativa, Odoo Community Association (OCA)',

7
partner_sale_risk/models/res_partner.py

@ -10,9 +10,9 @@ class ResPartner(models.Model):
risk_sale_order_include = fields.Boolean(
string='Include Sales Orders', help='Full risk computation')
risk_sale_order_limit = fields.Monetary(
risk_sale_order_limit = fields.Float(
string='Limit Sales Orders', help='Set 0 if it is not locked')
risk_sale_order = fields.Monetary(
risk_sale_order = fields.Float(
compute='_compute_risk_sale_order', store=True,
string='Total Sales Orders Not Invoiced',
help='Total not invoiced of sales orders in Sale Order state')
@ -25,7 +25,8 @@ class ResPartner(models.Model):
customers = self.filtered('customer')
partners = customers | customers.mapped('child_ids')
orders_group = self.env['sale.order'].read_group(
[('state', '=', 'sale'), ('partner_id', 'in', partners.ids)],
[('state', 'not in', ['draft', 'sent', 'cancel', 'done']),
('partner_id', 'in', partners.ids)],
['partner_id', 'invoice_pending_amount'],
['partner_id'])
for partner in customers:

60
partner_sale_risk/models/sale.py

@ -8,18 +8,23 @@ from openerp import api, fields, models, _
class SaleOrder(models.Model):
_inherit = 'sale.order'
invoice_amount = fields.Monetary(
invoice_amount = fields.Float(
compute='_compute_invoice_amount', store=True)
invoice_pending_amount = fields.Monetary(
invoice_pending_amount = fields.Float(
compute='_compute_invoice_amount', store=True)
@api.multi
@api.depends('state', 'order_line.invoice_lines.invoice_id.amount_total')
@api.depends('state',
'invoice_ids',
'invoice_ids.amount_total',
'order_line.invoice_lines.invoice_id.amount_total')
def _compute_invoice_amount(self):
AccountInvoice = self.env['account.invoice']
for order in self.filtered(lambda x: x.state == 'sale'):
for order in self:
order.invoice_pending_amount = order.amount_total
invoice_ids = order.order_line.mapped('invoice_lines').mapped(
'invoice_id').ids
invoice_ids += order.mapped('invoice_ids').ids
if not invoice_ids:
continue
amount = AccountInvoice.read_group(
@ -33,27 +38,28 @@ class SaleOrder(models.Model):
order.invoice_pending_amount = order.amount_total - amount
@api.multi
def action_confirm(self):
def action_button_confirm(self):
if not self.env.context.get('bypass_risk', False):
partner = self.partner_id.commercial_partner_id
exception_msg = ""
if partner.risk_exception:
exception_msg = _("Financial risk exceeded.\n")
elif partner.risk_sale_order_limit and (
(partner.risk_sale_order + self.amount_total) >
partner.risk_sale_order_limit):
exception_msg = _(
"This sale order exceeds the sales orders risk.\n")
elif partner.risk_sale_order_include and (
(partner.risk_total + self.amount_total) >
partner.credit_limit):
exception_msg = _(
"This sale order exceeds the financial risk.\n")
if exception_msg:
return self.env['partner.risk.exceeded.wiz'].create({
'exception_msg': exception_msg,
'partner_id': partner.id,
'origin_reference': '%s,%s' % (self._model, self.id),
'continue_method': 'action_confirm',
}).action_show()
return super(SaleOrder, self).action_confirm()
for order in self:
partner = order.partner_id.commercial_partner_id
exception_msg = ""
if partner.risk_exception:
exception_msg = _("Financial risk exceeded.\n")
elif partner.risk_sale_order_limit and (
(partner.risk_sale_order + self.amount_total) >
partner.risk_sale_order_limit):
exception_msg = _(
"This sale order exceeds the sales orders risk.\n")
elif partner.risk_sale_order_include and (
(partner.risk_total + self.amount_total) >
partner.credit_limit):
exception_msg = _(
"This sale order exceeds the financial risk.\n")
if exception_msg:
return self.env['partner.risk.exceeded.wiz'].create({
'exception_msg': exception_msg,
'partner_id': partner.id,
'origin_reference': '%s,%s' % (self._model, self.id),
'continue_method': 'action_button_confirm',
}).action_show()
return super(SaleOrder, self).action_button_confirm()

5
partner_sale_risk/tests/__init__.py

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

138
partner_sale_risk/tests/test_partner_sale_risk.py

@ -6,6 +6,7 @@ from openerp.tests.common import TransactionCase
class TestPartnerSaleRisk(TransactionCase):
def setUp(self):
super(TestPartnerSaleRisk, self).setUp()
self.env.user.groups_id |= self.env.ref('base.group_sale_manager')
@ -25,29 +26,122 @@ class TestPartnerSaleRisk(TransactionCase):
'product_uom': self.product.uom_id.id,
'price_unit': 100.0})],
})
self.wizard = self.env[
"sale.advance.payment.inv"]
def test_sale_order(self):
self.sale_order.action_confirm()
self.assertAlmostEqual(self.partner.risk_sale_order, 100.0)
self.assertFalse(self.partner.risk_exception)
self.partner.risk_sale_order_limit = 99.0
self.assertTrue(self.partner.risk_exception)
sale_order2 = self.sale_order.copy()
wiz_dic = sale_order2.action_confirm()
def test_sale_order_1(self):
"""
Scenario:
* 1 sale order @ 100 EUR
* Manual invoice policy
* Invoice all
* Risk sale order not include
* No invoice risk
Expected result:
* Sale order can be confirm
* Invoice can be validate
"""
self.sale_order.action_button_confirm()
self.assertEqual(
self.sale_order.state,
"manual")
wizard = self.wizard.with_context({
"active_ids": [self.sale_order.id]}).\
create({
"advance_payment_method": "all"})
wizard.create_invoices()
self.sale_order.invoice_ids.signal_workflow("invoice_open")
def test_sale_order_2(self):
"""
Scenario:
* 1 sale order @ 100 EUR
* Manual invoice policy
* Invoice all
* Sale Order Limit == 75 EUR
* Risk sale order not include
* No invoice risk
Expected result:
* Sale order exceeds the sale order risk raised
"""
self.partner.write({
"risk_sale_order_limit": 75.0,
"credit_limit": 150.0,
})
wiz_dic = self.sale_order.action_button_confirm()
wiz = self.env[wiz_dic['res_model']].browse(wiz_dic['res_id'])
self.assertEqual(wiz.exception_msg, "Financial risk exceeded.\n")
self.partner.risk_sale_order_limit = 150.0
wiz_dic = sale_order2.action_confirm()
self.assertEqual(
wiz.exception_msg,
"This sale order exceeds the sales orders risk.\n")
def test_sale_order_3(self):
"""
Scenario:
* 1 sale order @ 100 EUR
* Manual invoice policy
* Invoice all
* Sale Order Limit == 100 EUR
* Credit Limit == 75 EUR
* Risk sale order include
* No invoice risk
Expected result:
* Sale order exceeds the financial risk raised
"""
self.partner.write({
"risk_sale_order_limit": 115.0,
"credit_limit": 75.0,
"risk_sale_order_include": True,
})
wiz_dic = self.sale_order.action_button_confirm()
wiz = self.env[wiz_dic['res_model']].browse(wiz_dic['res_id'])
self.assertEqual(wiz.exception_msg,
"This sale order exceeds the sales orders risk.\n")
self.partner.risk_sale_order_limit = 0.0
self.partner.risk_sale_order_include = True
self.partner.credit_limit = 100.0
wiz_dic = sale_order2.action_confirm()
self.assertEqual(
wiz.exception_msg,
"This sale order exceeds the financial risk.\n")
def test_sale_order_4(self):
"""
Scenario:
* Sale Order Limit == 100 EUR
* Credit Limit == 75 EUR
* Risk sale order include
* Invoice draft include
* Sale order #1 @ 100 EUR
* Manual invoice policy
* Invoice percentace 0.75
* Sale order #2 @ 100 EUR
* Confirm using bypass risk
* Sale order #3 @ 100 EUR
* Confirm using bypass risk
Expected result:
* Financial risk exceeded raised
"""
self.partner.write({
"risk_sale_order_limit": 150.0,
"credit_limit": 100.0,
"risk_sale_order_include": True,
"risk_invoice_draft_include": True,
})
self.sale_order.action_button_confirm()
self.assertEqual(
self.sale_order.state,
"manual")
sale_order2 = self.sale_order.copy()
sale_order2.order_line[0].write({'price_unit': 10.0})
sale_order2.with_context(bypass_risk=True).action_button_confirm()
self.assertTrue(
self.sale_order.partner_id.risk_exception)
sale_order3 = self.sale_order.copy()
sale_order3.order_line[0].write({'price_unit': 10.0})
wiz_dic = sale_order3.with_context(
bypass_risk=False).action_button_confirm()
wiz = self.env[wiz_dic['res_model']].browse(wiz_dic['res_id'])
self.assertEqual(wiz.exception_msg,
"This sale order exceeds the financial risk.\n")
self.assertTrue(self.partner.risk_allow_edit)
wiz.button_continue()
self.assertAlmostEqual(self.partner.risk_sale_order, 200.0)
self.assertEqual(
wiz.exception_msg,
"Financial risk exceeded.\n")

6
partner_sale_risk/views/res_partner_view.xml

@ -1,7 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- © 2016 Carlos Dauden <carlos.dauden@tecnativa.com>
License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl-3). -->
<odoo>
<openerp>
<data>
<record id="res_partner_view_risk" model="ir.ui.view">
<field name="name">res.partner.view.risk</field>
<field name="model">res.partner</field>
@ -18,4 +19,5 @@
</field>
</field>
</record>
</odoo>
</data>
</openerp>

8
partner_sale_risk/views/sale_view.xml

@ -1,16 +1,18 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- © 2016 Carlos Dauden <carlos.dauden@tecnativa.com>
License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl-3). -->
<odoo>
<openerp>
<data>
<record id="view_order_form_invoice_amount" model="ir.ui.view">
<field name="name">sale.order.form.invoice.amount</field>
<field name="model">sale.order</field>
<field name="inherit_id" ref="sale.view_order_form"/>
<field name="arch" type="xml">
<field name="fiscal_position_id" position="after">
<field name="fiscal_position" position="after">
<field name="invoice_amount"/>
<field name="invoice_pending_amount"/>
</field>
</field>
</record>
</odoo>
</data>
</openerp>
Loading…
Cancel
Save