Skip to content
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
15 changes: 10 additions & 5 deletions sale_elaboration/README.rst
Original file line number Diff line number Diff line change
@@ -1,7 +1,3 @@
.. image:: https://odoo-community.org/readme-banner-image
:target: https://odoo-community.org/get-involved?utm_source=readme
:alt: Odoo Community Association

================
Sale Elaboration
================
Expand All @@ -17,7 +13,7 @@ Sale Elaboration
.. |badge1| image:: https://img.shields.io/badge/maturity-Production%2FStable-green.png
:target: https://odoo-community.org/page/development-status
:alt: Production/Stable
.. |badge2| image:: https://img.shields.io/badge/license-AGPL--3-blue.png
.. |badge2| image:: https://img.shields.io/badge/licence-AGPL--3-blue.png
:target: http://www.gnu.org/licenses/agpl-3.0-standalone.html
:alt: License: AGPL-3
.. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fsale--workflow-lightgray.png?logo=github
Expand Down Expand Up @@ -75,6 +71,15 @@ To configure this module you need to:
You can define elaboration profiles to limit the elaborations that can
be selected for each product.

To set the profile globally for a product category:

1. Go to *Inventory > Configuration > Product Categories* and choose
one.
2. In the **Logistics** sections, you can set the desired **Elaboration
profile**.

If you want to set an specific elaboration profile for a product:

1. Go to *Sale > Configuration > Elaborations > Sale Elaboration
Profile*.
2. Create a new record.
Expand Down
1 change: 1 addition & 0 deletions sale_elaboration/__manifest__.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
"reports/report_base.xml",
"reports/report_deliveryslip.xml",
"reports/report_picking_operations.xml",
"views/product_category_views.xml",
],
"demo": ["demo/sale_elaboration_demo.xml"],
"pre_init_hook": "pre_init_hook",
Expand Down
1 change: 1 addition & 0 deletions sale_elaboration/models/__init__.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
from . import product
from . import product_category
from . import product_elaboration
from . import product_elaboration_mixin
from . import product_elaboration_profile
Expand Down
5 changes: 4 additions & 1 deletion sale_elaboration/models/product.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,8 @@ class ProductProduct(models.Model):
_inherit = "product.product"

elaboration_profile_id = fields.Many2one(
comodel_name="product.elaboration.profile", ondelete="restrict"
comodel_name="product.elaboration.profile",
ondelete="restrict",
help="Keep this field empty to use the default value from the product "
"category.",
)
11 changes: 11 additions & 0 deletions sale_elaboration/models/product_category.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# Copyright 2025 Moduon Team S.L. <info@moduon.team>
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
from odoo import fields, models


class ProductCategory(models.Model):
_inherit = "product.category"

elaboration_profile_id = fields.Many2one(
comodel_name="product.elaboration.profile", string="Elaboration Profile"
)
2 changes: 2 additions & 0 deletions sale_elaboration/models/product_template.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ class ProductTemplate(models.Model):
compute="_compute_elaboration_profile_id",
inverse="_inverse_elaboration_profile_id",
store=True,
help="Keep this field empty to use the default value from the product "
"category.",
)

@api.depends("product_variant_ids", "product_variant_ids.elaboration_profile_id")
Expand Down
13 changes: 12 additions & 1 deletion sale_elaboration/models/sale_order.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,8 @@ class SaleOrderLine(models.Model):
date_order = fields.Datetime(related="order_id.date_order", string="Date")
route_id = fields.Many2one(compute="_compute_route_id", store=True, readonly=False)
elaboration_profile_id = fields.Many2one(
related="product_id.elaboration_profile_id"
comodel_name="product.elaboration.profile",
compute="_compute_elaboration_profile_id",
)
elaboration_price_unit = fields.Float(
"Elab. Price", compute="_compute_elaboration_price_unit", store=True
Expand All @@ -59,6 +60,16 @@ class SaleOrderLine(models.Model):
help=("Dummy field to be able to find prepared lines"),
)

@api.depends("product_id")
def _compute_elaboration_profile_id(self):
"""Order of applicability: product profile > category profile > no profile"""
self.elaboration_profile_id = False
for line in self.filtered("product_id"):
line.elaboration_profile_id = (
line.product_id.elaboration_profile_id
or line.product_id.categ_id.elaboration_profile_id
)

def get_elaboration_stock_route(self):
self.ensure_one()
return self.elaboration_ids.route_ids[:1]
Expand Down
7 changes: 7 additions & 0 deletions sale_elaboration/readme/CONFIGURE.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,13 @@ To configure this module you need to:
You can define elaboration profiles to limit the elaborations that can be
selected for each product.

To set the profile globally for a product category:

1. Go to *Inventory > Configuration > Product Categories* and choose one.
2. In the **Logistics** sections, you can set the desired **Elaboration profile**.

If you want to set an specific elaboration profile for a product:

1. Go to *Sale \> Configuration \> Elaborations \> Sale Elaboration Profile*.
2. Create a new record.
3. Select the elaborations included to the profile.
Expand Down
38 changes: 20 additions & 18 deletions sale_elaboration/static/description/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="generator" content="Docutils: https://docutils.sourceforge.io/" />
<title>README.rst</title>
<title>Sale Elaboration</title>
<style type="text/css">

/*
Expand Down Expand Up @@ -360,21 +360,16 @@
</style>
</head>
<body>
<div class="document">
<div class="document" id="sale-elaboration">
<h1 class="title">Sale Elaboration</h1>


<a class="reference external image-reference" href="https://odoo-community.org/get-involved?utm_source=readme">
<img alt="Odoo Community Association" src="https://odoo-community.org/readme-banner-image" />
</a>
<div class="section" id="sale-elaboration">
<h1>Sale Elaboration</h1>
<!-- !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! This file is generated by oca-gen-addon-readme !!
!! changes will be overwritten. !!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! source digest: sha256:cc865ea78ca02010b937cb1efe667a70e78a45925709c11885caa5c92452df3c
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->
<p><a class="reference external image-reference" href="https://odoo-community.org/page/development-status"><img alt="Production/Stable" src="https://img.shields.io/badge/maturity-Production%2FStable-green.png" /></a> <a class="reference external image-reference" href="http://www.gnu.org/licenses/agpl-3.0-standalone.html"><img alt="License: AGPL-3" src="https://img.shields.io/badge/license-AGPL--3-blue.png" /></a> <a class="reference external image-reference" href="https://github.com/OCA/sale-workflow/tree/18.0/sale_elaboration"><img alt="OCA/sale-workflow" src="https://img.shields.io/badge/github-OCA%2Fsale--workflow-lightgray.png?logo=github" /></a> <a class="reference external image-reference" href="https://translation.odoo-community.org/projects/sale-workflow-18-0/sale-workflow-18-0-sale_elaboration"><img alt="Translate me on Weblate" src="https://img.shields.io/badge/weblate-Translate%20me-F47D42.png" /></a> <a class="reference external image-reference" href="https://runboat.odoo-community.org/builds?repo=OCA/sale-workflow&amp;target_branch=18.0"><img alt="Try me on Runboat" src="https://img.shields.io/badge/runboat-Try%20me-875A7B.png" /></a></p>
<p><a class="reference external image-reference" href="https://odoo-community.org/page/development-status"><img alt="Production/Stable" src="https://img.shields.io/badge/maturity-Production%2FStable-green.png" /></a> <a class="reference external image-reference" 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 image-reference" href="https://github.com/OCA/sale-workflow/tree/18.0/sale_elaboration"><img alt="OCA/sale-workflow" src="https://img.shields.io/badge/github-OCA%2Fsale--workflow-lightgray.png?logo=github" /></a> <a class="reference external image-reference" href="https://translation.odoo-community.org/projects/sale-workflow-18-0/sale-workflow-18-0-sale_elaboration"><img alt="Translate me on Weblate" src="https://img.shields.io/badge/weblate-Translate%20me-F47D42.png" /></a> <a class="reference external image-reference" href="https://runboat.odoo-community.org/builds?repo=OCA/sale-workflow&amp;target_branch=18.0"><img alt="Try me on Runboat" src="https://img.shields.io/badge/runboat-Try%20me-875A7B.png" /></a></p>
<p>This module extends the functionality of sales orders to allow to set an
elaboration on lines that will add an extra order line with an
elaboration product linked to it when the delivery order is validated.</p>
Expand All @@ -401,13 +396,13 @@ <h1>Sale Elaboration</h1>
</ul>
</div>
<div class="section" id="use-cases-context">
<h2><a class="toc-backref" href="#toc-entry-1">Use Cases / Context</a></h2>
<h1><a class="toc-backref" href="#toc-entry-1">Use Cases / Context</a></h1>
<p>This module was created to meet the need of providing the customer with
products that are not transformed into something new, but rather require
a simple preparation process. Example: Scaling a fish</p>
</div>
<div class="section" id="configuration">
<h2><a class="toc-backref" href="#toc-entry-2">Configuration</a></h2>
<h1><a class="toc-backref" href="#toc-entry-2">Configuration</a></h1>
<p>To configure this module you need to:</p>
<ol class="arabic simple">
<li>Go to <em>Sale &gt; Configuration &gt; Elaborations &gt; Sale Elaboration</em>.</li>
Expand All @@ -422,6 +417,14 @@ <h2><a class="toc-backref" href="#toc-entry-2">Configuration</a></h2>
</ol>
<p>You can define elaboration profiles to limit the elaborations that can
be selected for each product.</p>
<p>To set the profile globally for a product category:</p>
<ol class="arabic simple">
<li>Go to <em>Inventory &gt; Configuration &gt; Product Categories</em> and choose
one.</li>
<li>In the <strong>Logistics</strong> sections, you can set the desired <strong>Elaboration
profile</strong>.</li>
</ol>
<p>If you want to set an specific elaboration profile for a product:</p>
<ol class="arabic simple">
<li>Go to <em>Sale &gt; Configuration &gt; Elaborations &gt; Sale Elaboration
Profile</em>.</li>
Expand All @@ -431,7 +434,7 @@ <h2><a class="toc-backref" href="#toc-entry-2">Configuration</a></h2>
</ol>
</div>
<div class="section" id="usage">
<h2><a class="toc-backref" href="#toc-entry-3">Usage</a></h2>
<h1><a class="toc-backref" href="#toc-entry-3">Usage</a></h1>
<ol class="arabic simple">
<li>Go to <em>Sale &gt; Quotations</em>.</li>
<li>Create a sales order.</li>
Expand All @@ -447,23 +450,23 @@ <h2><a class="toc-backref" href="#toc-entry-3">Usage</a></h2>
</ol>
</div>
<div class="section" id="bug-tracker">
<h2><a class="toc-backref" href="#toc-entry-4">Bug Tracker</a></h2>
<h1><a class="toc-backref" href="#toc-entry-4">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 to smash it by providing a detailed and welcomed
<a class="reference external" href="https://github.com/OCA/sale-workflow/issues/new?body=module:%20sale_elaboration%0Aversion:%2018.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">
<h2><a class="toc-backref" href="#toc-entry-5">Credits</a></h2>
<h1><a class="toc-backref" href="#toc-entry-5">Credits</a></h1>
<div class="section" id="authors">
<h3><a class="toc-backref" href="#toc-entry-6">Authors</a></h3>
<h2><a class="toc-backref" href="#toc-entry-6">Authors</a></h2>
<ul class="simple">
<li>Tecnativa</li>
</ul>
</div>
<div class="section" id="contributors">
<h3><a class="toc-backref" href="#toc-entry-7">Contributors</a></h3>
<h2><a class="toc-backref" href="#toc-entry-7">Contributors</a></h2>
<ul class="simple">
<li><a class="reference external" href="https://www.tecnativa.com">Tecnativa</a>:<ul>
<li>Sergio Teruel</li>
Expand All @@ -477,7 +480,7 @@ <h3><a class="toc-backref" href="#toc-entry-7">Contributors</a></h3>
</ul>
</div>
<div class="section" id="maintainers">
<h3><a class="toc-backref" href="#toc-entry-8">Maintainers</a></h3>
<h2><a class="toc-backref" href="#toc-entry-8">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" />
Expand All @@ -492,6 +495,5 @@ <h3><a class="toc-backref" href="#toc-entry-8">Maintainers</a></h3>
</div>
</div>
</div>
</div>
</body>
</html>
29 changes: 29 additions & 0 deletions sale_elaboration/tests/test_sale_elaboration.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
# Copyright 2018 Tecnativa - Sergio Teruel
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
from odoo import Command
from odoo.tests import Form, tagged

from odoo.addons.account.tests.common import AccountTestInvoicingCommon
Expand All @@ -11,9 +12,21 @@ class TestSaleElaboration(AccountTestInvoicingCommon):
def setUpClass(cls):
super().setUpClass()
cls.Elaboration = cls.env["product.elaboration"]
cls.ElaborationProfile = cls.env["product.elaboration.profile"]
cls.category_1 = cls.env["product.category"].create({"name": "Meat"})
cls.category_2 = cls.env["product.category"].create({"name": "Fish"})
cls.product = cls.env["product.product"].create(
{"name": "test", "tracking": "none", "list_price": 1000}
)
cls.product_2 = cls.env["product.product"].create(
{"name": "test 2", "tracking": "none", "list_price": 1000}
)
cls.product_3 = cls.env["product.product"].create(
{"name": "test 2", "tracking": "none", "list_price": 1000}
)
cls.product.categ_id = cls.category_1
cls.product_2.categ_id = cls.category_2
cls.product_3.categ_id = cls.category_1
cls.product_elaboration_A = cls.env["product.product"].create(
{
"name": "Product Elaboration A",
Expand Down Expand Up @@ -65,9 +78,25 @@ def setUpClass(cls):
"product_id": cls.product_elaboration_B.id,
}
)
cls.elaboration_profile_a = cls.ElaborationProfile.create(
{
"name": "Elaboration Profile A",
"elaboration_ids": [
Command.set([cls.elaboration_a.id, cls.elaboration_b.id])
],
}
)
cls.elaboration_profile_b = cls.ElaborationProfile.create(
{
"name": "Elaboration Profile B",
"elaboration_ids": [Command.set(cls.elaboration_a.ids)],
}
)
cls.product.elaboration_profile_id = cls.elaboration_profile_a
cls.order = cls._create_sale_order(
cls, [(cls.product, 10, [cls.elaboration_a])]
)
cls.category_1.elaboration_profile_id = cls.elaboration_profile_b

def _create_sale_order(self, products_info):
order_form = Form(self.env["sale.order"])
Expand Down
16 changes: 16 additions & 0 deletions sale_elaboration/views/product_category_views.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<?xml version="1.0" encoding="utf-8" ?>
<odoo>
<record
model="ir.ui.view"
id="sale_elaboration_product_category_view_form_inherit_elaboration_id"
>
<field name="name">product.category.view.form.sale.elaboration</field>
<field name="model">product.category</field>
<field name="inherit_id" ref="product.product_category_form_view" />
<field name="arch" type="xml">
<xpath expr="//group[@name='logistics']" position="inside">
<field name="elaboration_profile_id" />
</xpath>
</field>
</record>
</odoo>