Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[11.0][IMP] sale_order_type: Find sale order type based on the products of the sale order #770

Merged
merged 3 commits into from
Feb 1, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 21 additions & 7 deletions sale_order_type/README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ Sale Order Type
|badge1| |badge2| |badge3| |badge4| |badge5|

This module adds a typology for the sales orders. In each different type, you
can define, invoicing and refunding journal, a warehouse, a sequence,
can define: invoicing and refunding journal, a warehouse, a sequence,
the shipping policy, the invoicing policy, a payment term, a pricelist
and an incoterm.

Expand All @@ -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.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Case 1

  • 1 sale order with 2 product
  • Each of that 2 products are in 2 different rules of 2 different sale_order_type

Product 1 -> Sale order type 1
Product 2 -> Sale order type 2

Sale Order TEST has product 1 + product 2

Which is the result?

Copy link
Member Author

@SimoRubi SimoRubi Jan 17, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi, thanks for your review!
As stated few lines below, the order types are inspected following the order of their sequence field, so:
0. Suppose Type 1 has sequence 1 and Type 2 has sequence 2;

  1. Type 1 is inspected: does this match the current order?
    1. Does any rule of type 1 match any product in the order?
      *. Yes -> choose type 1 and exit
      *. No -> go on
    2. Does any rule of type 1 match any product category in the order?
      *. (same as above)
  2. Repeat step 1 for the following order types

At least this is the behavior I tried to describe in the README, if that is not clear enough I can add an example.

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
3 changes: 2 additions & 1 deletion sale_order_type/__manifest__.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

{
"name": "Sale Order Type",
"version": "11.0.1.3.0",
"version": "11.0.1.4.0",
"category": "Sales Management",
"author": "Grupo Vermon,"
"AvanzOSC,"
Expand All @@ -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 res_partner
from . import account_invoice
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 @@ -24,6 +24,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 @@ -36,6 +36,16 @@ def onchange_type_id(self):
if order.type_id.incoterm_id:
order.incoterm = order.type_id.incoterm_id.id

@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
15 changes: 15 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 @@ -40,3 +41,17 @@ def default_picking_policy(self):
payment_term_id = fields.Many2one('account.payment.term', 'Payment Term')
pricelist_id = fields.Many2one('product.pricelist', 'Pricelist')
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)
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
11 changes: 10 additions & 1 deletion sale_order_type/readme/DESCRIPTION.rst
Original file line number Diff line number Diff line change
@@ -1,9 +1,18 @@
This module adds a typology for the sales orders. In each different type, you
can define, invoicing and refunding journal, a warehouse, a sequence,
can define: invoicing and refunding journal, a warehouse, a sequence,
the shipping policy, the invoicing policy, a payment term, a pricelist
and an incoterm.

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
46 changes: 29 additions & 17 deletions sale_order_type/static/description/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -369,22 +369,28 @@ <h1 class="title">Sale Order Type</h1>
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->
<p><a class="reference external" href="https://odoo-community.org/page/development-status"><img alt="Beta" src="https://img.shields.io/badge/maturity-Beta-yellow.png" /></a> <a class="reference external" href="http://www.gnu.org/licenses/agpl-3.0-standalone.html"><img alt="License: AGPL-3" src="https://img.shields.io/badge/licence-AGPL--3-blue.png" /></a> <a class="reference external" href="https://github.com/OCA/sale-workflow/tree/11.0/sale_order_type"><img alt="OCA/sale-workflow" src="https://img.shields.io/badge/github-OCA%2Fsale--workflow-lightgray.png?logo=github" /></a> <a class="reference external" href="https://translation.odoo-community.org/projects/sale-workflow-11-0/sale-workflow-11-0-sale_order_type"><img alt="Translate me on Weblate" src="https://img.shields.io/badge/weblate-Translate%20me-F47D42.png" /></a> <a class="reference external" href="https://runbot.odoo-community.org/runbot/167/11.0"><img alt="Try me on Runbot" src="https://img.shields.io/badge/runbot-Try%20me-875A7B.png" /></a></p>
<p>This module adds a typology for the sales orders. In each different type, you
can define, invoicing and refunding journal, a warehouse, a sequence,
can define: invoicing and refunding journal, a warehouse, a sequence,
the shipping policy, the invoicing policy, a payment term, a pricelist
and an incoterm.</p>
<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:%2011.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 @@ -459,7 +471,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
2 changes: 1 addition & 1 deletion sale_order_type/tests/test_sale_order_type.py
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ def test_invoice_onchange_type(self):
sale_type = self.sale_type
invoice = self.invoice_model.new({'sale_type_id': sale_type.id})
invoice.onchange_sale_type_id()
self.assertTrue(invoice.payment_term == sale_type.payment_term_id.id)
self.assertTrue(invoice.payment_term_id == sale_type.payment_term_id)
self.assertTrue(invoice.journal_id == sale_type.journal_id)

def test_invoice_onchange_partner(self):
Expand Down
Loading