Skip to content

Commit

Permalink
[IMP] sale_order_type: Find sale order type based on the products of …
Browse files Browse the repository at this point in the history
…the sale order (OCA#770)
  • Loading branch information
SimoRubi authored and chienandalu committed Dec 21, 2020
1 parent db958a0 commit bc47665
Show file tree
Hide file tree
Showing 20 changed files with 363 additions and 31 deletions.
26 changes: 20 additions & 6 deletions sale_order_type/README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,15 @@ You can see sale types as lines of business.
You are able to select a sales order type by partner so that when you add a
partner to a sales order it will get the related info to it.

Rules can also be associated with sale order types.

Inside each rule, you can select any number of products and/or product categories.

In the sale order form you can find the matching order type by clicking on the button *Find by rule* placed near the *Type* field.
If the rule does not match *by product*, product categories are checked.

The sale order types and the rules are inspected based on the value of their *sequence* field.

**Table of contents**

.. contents::
Expand All @@ -45,16 +54,20 @@ Configuration

To configure Sale Order Types you need to:

#. Go to **Sales > Configuration > Sales Orders Types**
#. Create a new sale order type with all the settings you want
1. Go to **Sales > Configuration > Sales Orders Types**
2. Create a new sale order type with all the settings you want

Usage
=====

#. Go to **Sales > Sales Orders** and create a new sale order. Select the new
type you have created before and all settings will be propagated.
#. You can also define a type for a particular partner if you go to *Sales &
Purchases* and set a sale order type.
* Go to **Sales > Sales Orders** and create a new sale order. Select the new type you have created before and all settings will be propagated.
* You can also define a type for a particular partner if you go to *Sales & Purchases* and set a sale order type.
* You can also find the matching order type by clicking on the button *Find by rule* placed near the *Type* field

Known issues / Roadmap
======================

* Manage the order of *sale.order.type.rule* similar to *product.pricelist.item* (see field *applied_on*) instead of using *sequence*.

Bug Tracker
===========
Expand Down Expand Up @@ -95,6 +108,7 @@ Contributors
* `Agile Business Group <https://www.agilebg.com>`_

* Lorenzo Battistini <lorenzo.battistini@agilebg.com>
* Simone Rubino <simone.rubino@agilebg.com>

* `Niboo <https://www.niboo.be/>`_

Expand Down
1 change: 1 addition & 0 deletions sale_order_type/__manifest__.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
"security/security.xml",
"views/sale_order_view.xml",
"views/sale_order_type_view.xml",
"views/sale_order_type_rule_view.xml",
"views/account_invoice_view.xml",
"views/res_partner_view.xml",
"data/default_type.xml",
Expand Down
1 change: 1 addition & 0 deletions sale_order_type/models/__init__.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).

from . import sale_order_type
from . import sale_order_type_rule
from . import sale_order
from . import sale_order_line
from . import res_partner
Expand Down
12 changes: 11 additions & 1 deletion sale_order_type/models/account_invoice.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,16 @@ def _onchange_partner_id(self):
@api.onchange('sale_type_id')
def onchange_sale_type_id(self):
if self.sale_type_id.payment_term_id:
self.payment_term = self.sale_type_id.payment_term_id.id
self.payment_term_id = self.sale_type_id.payment_term_id.id
if self.sale_type_id.journal_id:
self.journal_id = self.sale_type_id.journal_id.id

@api.multi
def match_order_type(self):
order_types = self.env['sale.order.type'].search([])
for invoice in self:
for order_type in order_types:
if order_type.matches_invoice(invoice):
invoice.sale_type_id = order_type
invoice.onchange_sale_type_id()
break
10 changes: 10 additions & 0 deletions sale_order_type/models/sale_order.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,16 @@ def onchange_type_id(self):
line_vals.update({"route_id": order_type.route_id.id})
order.order_line.update(line_vals)

@api.multi
def match_order_type(self):
order_types = self.env['sale.order.type'].search([])
for order in self:
for order_type in order_types:
if order_type.matches_order(order):
order.type_id = order_type
order.onchange_type_id()
break

@api.model
def create(self, vals):
if vals.get('name', '/') == '/'and vals.get('type_id'):
Expand Down
19 changes: 19 additions & 0 deletions sale_order_type/models/sale_order_type.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
class SaleOrderTypology(models.Model):
_name = 'sale.order.type'
_description = 'Type of sale order'
_order = 'sequence'

@api.model
def _get_domain_sequence_id(self):
Expand Down Expand Up @@ -39,6 +40,7 @@ def default_picking_policy(self):
related='warehouse_id.company_id', store=True, readonly=True)
payment_term_id = fields.Many2one('account.payment.term', 'Payment Term')
pricelist_id = fields.Many2one('product.pricelist', 'Pricelist')
<<<<<<< HEAD
incoterm_id = fields.Many2one('account.incoterms', 'Incoterm')
route_id = fields.Many2one(
"stock.location.route",
Expand All @@ -47,3 +49,20 @@ def default_picking_policy(self):
ondelete="restrict",
check_company=True,
)
=======
incoterm_id = fields.Many2one('stock.incoterms', 'Incoterm')
sequence = fields.Integer(default=10)
rule_ids = fields.One2many(
comodel_name='sale.order.type.rule', inverse_name='order_type_id',
copy=True)

@api.multi
def matches_order(self, order):
self.ensure_one()
return any(rule.matches_order(order) for rule in self.rule_ids)

@api.multi
def matches_invoice(self, invoice):
self.ensure_one()
return any(rule.matches_invoice(invoice) for rule in self.rule_ids)
>>>>>>> aadd9f72... [IMP] sale_order_type: Find sale order type based on the products of the sale order (#770)
58 changes: 58 additions & 0 deletions sale_order_type/models/sale_order_type_rule.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
# Copyright 2018 Simone Rubino - Agile Business Group
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).

from odoo import api, fields, models


class SaleOrderTypeRule(models.Model):
_name = 'sale.order.type.rule'
_order = 'sequence'

name = fields.Char(required=True)
sequence = fields.Integer(default=10)
order_type_id = fields.Many2one(
comodel_name='sale.order.type', ondelete='cascade')
product_ids = fields.Many2many(
comodel_name='product.product',
string='Products')
product_category_ids = fields.Many2many(
comodel_name='product.category',
string='Product categories')

@api.multi
def matches_order(self, order):
"""Return True if the rule matches the order,
False otherwise"""
self.ensure_one()
order_products = order.order_line.mapped('product_id')
return self.matches_products(order_products) \
or self.matches_product_categories(
order_products.mapped('categ_id'))

@api.multi
def matches_products(self, products):
"""Return True if the rule matches any of the products,
False otherwise"""
self.ensure_one()
return self.product_ids and any(
[rule_product in products
for rule_product in self.product_ids])

@api.multi
def matches_product_categories(self, categories):
"""Return True if the rule matches any of the categories,
False otherwise"""
self.ensure_one()
return self.product_category_ids and any(
[rule_category in categories
for rule_category in self.product_category_ids])

@api.multi
def matches_invoice(self, invoice):
"""Return True if the rule matches the invoice,
False otherwise"""
self.ensure_one()
invoice_products = invoice.invoice_line_ids.mapped('product_id')
return self.matches_products(invoice_products) \
or self.matches_product_categories(
invoice_products.mapped('categ_id'))
4 changes: 2 additions & 2 deletions sale_order_type/readme/CONFIGURE.rst
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
To configure Sale Order Types you need to:

#. Go to **Sales > Configuration > Sales Orders Types**
#. Create a new sale order type with all the settings you want
1. Go to **Sales > Configuration > Sales Orders Types**
2. Create a new sale order type with all the settings you want
1 change: 1 addition & 0 deletions sale_order_type/readme/CONTRIBUTORS.rst
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
* `Agile Business Group <https://www.agilebg.com>`_

* Lorenzo Battistini <lorenzo.battistini@agilebg.com>
* Simone Rubino <simone.rubino@agilebg.com>

* `Niboo <https://www.niboo.be/>`_

Expand Down
9 changes: 9 additions & 0 deletions sale_order_type/readme/DESCRIPTION.rst
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,12 @@ You can see sale types as lines of business.

You are able to select a sales order type by partner so that when you add a
partner to a sales order it will get the related info to it.

Rules can also be associated with sale order types.

Inside each rule, you can select any number of products and/or product categories.

In the sale order form you can find the matching order type by clicking on the button *Find by rule* placed near the *Type* field.
If the rule does not match *by product*, product categories are checked.

The sale order types and the rules are inspected based on the value of their *sequence* field.
1 change: 1 addition & 0 deletions sale_order_type/readme/ROADMAP.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
* Manage the order of *sale.order.type.rule* similar to *product.pricelist.item* (see field *applied_on*) instead of using *sequence*.
7 changes: 3 additions & 4 deletions sale_order_type/readme/USAGE.rst
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
#. Go to **Sales > Sales Orders** and create a new sale order. Select the new
type you have created before and all settings will be propagated.
#. You can also define a type for a particular partner if you go to *Sales &
Purchases* and set a sale order type.
* Go to **Sales > Sales Orders** and create a new sale order. Select the new type you have created before and all settings will be propagated.
* You can also define a type for a particular partner if you go to *Sales & Purchases* and set a sale order type.
* You can also find the matching order type by clicking on the button *Find by rule* placed near the *Type* field
3 changes: 3 additions & 0 deletions sale_order_type/security/ir.model.access.csv
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,6 @@ id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
access_sale_order_type_manager,access_sale_order_type_manager,model_sale_order_type,sales_team.group_sale_manager,1,1,1,1
access_sale_order_type_salesman,access_sale_order_type_salesman,model_sale_order_type,sales_team.group_sale_salesman,1,0,0,0
access_sale_order_type_account,access_sale_order_type_account,model_sale_order_type,account.group_account_invoice,1,0,0,0
access_sale_order_type_rule_manager,access_sale_order_type_rule_manager,model_sale_order_type_rule,sales_team.group_sale_manager,1,1,1,1
access_sale_order_type_rule_salesman,access_sale_order_type_rule_salesman,model_sale_order_type_rule,sales_team.group_sale_salesman,1,0,0,0
access_sale_order_type_rule_account,access_sale_order_type_rule_account,model_sale_order_type_rule,account.group_account_invoice,1,0,0,0
44 changes: 28 additions & 16 deletions sale_order_type/static/description/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -375,16 +375,22 @@ <h1 class="title">Sale Order Type</h1>
<p>You can see sale types as lines of business.</p>
<p>You are able to select a sales order type by partner so that when you add a
partner to a sales order it will get the related info to it.</p>
<p>Rules can also be associated with sale order types.</p>
<p>Inside each rule, you can select any number of products and/or product categories.</p>
<p>In the sale order form you can find the matching order type by clicking on the button <em>Find by rule</em> placed near the <em>Type</em> field.
If the rule does not match <em>by product</em>, product categories are checked.</p>
<p>The sale order types and the rules are inspected based on the value of their <em>sequence</em> field.</p>
<p><strong>Table of contents</strong></p>
<div class="contents local topic" id="contents">
<ul class="simple">
<li><a class="reference internal" href="#configuration" id="id1">Configuration</a></li>
<li><a class="reference internal" href="#usage" id="id2">Usage</a></li>
<li><a class="reference internal" href="#bug-tracker" id="id3">Bug Tracker</a></li>
<li><a class="reference internal" href="#credits" id="id4">Credits</a><ul>
<li><a class="reference internal" href="#authors" id="id5">Authors</a></li>
<li><a class="reference internal" href="#contributors" id="id6">Contributors</a></li>
<li><a class="reference internal" href="#maintainers" id="id7">Maintainers</a></li>
<li><a class="reference internal" href="#known-issues-roadmap" id="id3">Known issues / Roadmap</a></li>
<li><a class="reference internal" href="#bug-tracker" id="id4">Bug Tracker</a></li>
<li><a class="reference internal" href="#credits" id="id5">Credits</a><ul>
<li><a class="reference internal" href="#authors" id="id6">Authors</a></li>
<li><a class="reference internal" href="#contributors" id="id7">Contributors</a></li>
<li><a class="reference internal" href="#maintainers" id="id8">Maintainers</a></li>
</ul>
</li>
</ul>
Expand All @@ -399,25 +405,30 @@ <h1><a class="toc-backref" href="#id1">Configuration</a></h1>
</div>
<div class="section" id="usage">
<h1><a class="toc-backref" href="#id2">Usage</a></h1>
<ol class="arabic simple">
<li>Go to <strong>Sales &gt; Sales Orders</strong> and create a new sale order. Select the new
type you have created before and all settings will be propagated.</li>
<li>You can also define a type for a particular partner if you go to <em>Sales &amp;
Purchases</em> and set a sale order type.</li>
</ol>
<ul class="simple">
<li>Go to <strong>Sales &gt; Sales Orders</strong> and create a new sale order. Select the new type you have created before and all settings will be propagated.</li>
<li>You can also define a type for a particular partner if you go to <em>Sales &amp; Purchases</em> and set a sale order type.</li>
<li>You can also find the matching order type by clicking on the button <em>Find by rule</em> placed near the <em>Type</em> field</li>
</ul>
</div>
<div class="section" id="known-issues-roadmap">
<h1><a class="toc-backref" href="#id3">Known issues / Roadmap</a></h1>
<ul class="simple">
<li>Manage the order of <em>sale.order.type.rule</em> similar to <em>product.pricelist.item</em> (see field <em>applied_on</em>) instead of using <em>sequence</em>.</li>
</ul>
</div>
<div class="section" id="bug-tracker">
<h1><a class="toc-backref" href="#id3">Bug Tracker</a></h1>
<h1><a class="toc-backref" href="#id4">Bug Tracker</a></h1>
<p>Bugs are tracked on <a class="reference external" href="https://github.com/OCA/sale-workflow/issues">GitHub Issues</a>.
In case of trouble, please check there if your issue has already been reported.
If you spotted it first, help us smashing it by providing a detailed and welcomed
<a class="reference external" href="https://github.com/OCA/sale-workflow/issues/new?body=module:%20sale_order_type%0Aversion:%2012.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**">feedback</a>.</p>
<p>Do not contact contributors directly about support or help with technical issues.</p>
</div>
<div class="section" id="credits">
<h1><a class="toc-backref" href="#id4">Credits</a></h1>
<h1><a class="toc-backref" href="#id5">Credits</a></h1>
<div class="section" id="authors">
<h2><a class="toc-backref" href="#id5">Authors</a></h2>
<h2><a class="toc-backref" href="#id6">Authors</a></h2>
<ul class="simple">
<li>Grupo Vermon</li>
<li>AvanzOSC</li>
Expand All @@ -427,7 +438,7 @@ <h2><a class="toc-backref" href="#id5">Authors</a></h2>
</ul>
</div>
<div class="section" id="contributors">
<h2><a class="toc-backref" href="#id6">Contributors</a></h2>
<h2><a class="toc-backref" href="#id7">Contributors</a></h2>
<ul class="simple">
<li><a class="reference external" href="http://www.grupovermon.com">Vermon</a><ul>
<li>Carlos Sánchez Cifuentes &lt;<a class="reference external" href="mailto:csanchez&#64;grupovermon.com">csanchez&#64;grupovermon.com</a>&gt;</li>
Expand All @@ -442,6 +453,7 @@ <h2><a class="toc-backref" href="#id6">Contributors</a></h2>
</li>
<li><a class="reference external" href="https://www.agilebg.com">Agile Business Group</a><ul>
<li>Lorenzo Battistini &lt;<a class="reference external" href="mailto:lorenzo.battistini&#64;agilebg.com">lorenzo.battistini&#64;agilebg.com</a>&gt;</li>
<li>Simone Rubino &lt;<a class="reference external" href="mailto:simone.rubino&#64;agilebg.com">simone.rubino&#64;agilebg.com</a>&gt;</li>
</ul>
</li>
<li><a class="reference external" href="https://www.niboo.be/">Niboo</a><ul>
Expand All @@ -464,7 +476,7 @@ <h2><a class="toc-backref" href="#id6">Contributors</a></h2>
<p>Do not contact contributors directly about support or help with technical issues.</p>
</div>
<div class="section" id="maintainers">
<h2><a class="toc-backref" href="#id7">Maintainers</a></h2>
<h2><a class="toc-backref" href="#id8">Maintainers</a></h2>
<p>This module is maintained by the OCA.</p>
<a class="reference external image-reference" href="https://odoo-community.org"><img alt="Odoo Community Association" src="https://odoo-community.org/logo.png" /></a>
<p>OCA, or the Odoo Community Association, is a nonprofit organization whose
Expand Down
1 change: 1 addition & 0 deletions sale_order_type/tests/__init__.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# License AGPL-3 - See http://www.gnu.org/licenses/agpl-3.0.html

from . import test_sale_order_type
from . import test_sale_order_type_rule
Loading

0 comments on commit bc47665

Please sign in to comment.