Skip to content

Commit 4eeb34f

Browse files
committed
[ADD] product_packaging_template: allow to configure packaging at product.template level
1 parent e80a17c commit 4eeb34f

19 files changed

+864
-0
lines changed
Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
==========================
2+
Product Packaging Template
3+
==========================
4+
5+
..
6+
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
7+
!! This file is generated by oca-gen-addon-readme !!
8+
!! changes will be overwritten. !!
9+
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
10+
!! source digest: sha256:05ed05917606253af93adef1e2c37e4249554220c75fac66caeb55644b3906a0
11+
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
12+
13+
.. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png
14+
:target: https://odoo-community.org/page/development-status
15+
:alt: Beta
16+
.. |badge2| image:: https://img.shields.io/badge/licence-AGPL--3-blue.png
17+
:target: http://www.gnu.org/licenses/agpl-3.0-standalone.html
18+
:alt: License: AGPL-3
19+
.. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fproduct--attribute-lightgray.png?logo=github
20+
:target: https://github.com/OCA/product-attribute/tree/18.0/product_packaging_template
21+
:alt: OCA/product-attribute
22+
.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png
23+
:target: https://translation.odoo-community.org/projects/product-attribute-18-0/product-attribute-18-0-product_packaging_template
24+
:alt: Translate me on Weblate
25+
.. |badge5| image:: https://img.shields.io/badge/runboat-Try%20me-875A7B.png
26+
:target: https://runboat.odoo-community.org/builds?repo=OCA/product-attribute&target_branch=18.0
27+
:alt: Try me on Runboat
28+
29+
|badge1| |badge2| |badge3| |badge4| |badge5|
30+
31+
Product packaging are defined at product variant level. It means that if
32+
a product template has 25 variants, and all of them are sold in the same
33+
packaging, one must define all the product.packaging one by one on the
34+
variants.
35+
36+
The aim of this module is to be able to define the product.packaging at
37+
template level. It will then create the product.packaging on all
38+
variants automatically.
39+
40+
Features
41+
--------
42+
43+
- When a product.packaging.template is created, create the
44+
product.packaging on all variants;
45+
- When a product.packaging.template is updated, update the
46+
product.packaging on all variants;
47+
- When a product.packaging.template is deleted, delete the
48+
product.packaging on all variants;
49+
- When a new product.variant is created, create all the
50+
product.packaging defined by the product.packaging.templates.
51+
52+
**Table of contents**
53+
54+
.. contents::
55+
:local:
56+
57+
Usage
58+
=====
59+
60+
To see the new table product.packaging.template on product.templates,
61+
one must have the special group "Products: Can manage packaging at
62+
template level".
63+
64+
Bug Tracker
65+
===========
66+
67+
Bugs are tracked on `GitHub Issues <https://github.com/OCA/product-attribute/issues>`_.
68+
In case of trouble, please check there if your issue has already been reported.
69+
If you spotted it first, help us to smash it by providing a detailed and welcomed
70+
`feedback <https://github.com/OCA/product-attribute/issues/new?body=module:%20product_packaging_template%0Aversion:%2018.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**>`_.
71+
72+
Do not contact contributors directly about support or help with technical issues.
73+
74+
Credits
75+
=======
76+
77+
Authors
78+
-------
79+
80+
* ACSONE SA/NV
81+
82+
Contributors
83+
------------
84+
85+
- Marie Lejeune <[email protected]>
86+
87+
Maintainers
88+
-----------
89+
90+
This module is maintained by the OCA.
91+
92+
.. image:: https://odoo-community.org/logo.png
93+
:alt: Odoo Community Association
94+
:target: https://odoo-community.org
95+
96+
OCA, or the Odoo Community Association, is a nonprofit organization whose
97+
mission is to support the collaborative development of Odoo features and
98+
promote its widespread use.
99+
100+
This module is part of the `OCA/product-attribute <https://github.com/OCA/product-attribute/tree/18.0/product_packaging_template>`_ project on GitHub.
101+
102+
You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
from . import models
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
# Copyright 2025 ACSONE SA/NV
2+
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
3+
4+
{
5+
"name": "Product Packaging Template",
6+
"summary": """Allows to define product packaging at template level""",
7+
"version": "18.0.1.0.0",
8+
"license": "AGPL-3",
9+
"author": "ACSONE SA/NV, Odoo Community Association (OCA)",
10+
"website": "https://github.com/OCA/product-attribute",
11+
"depends": [
12+
"product",
13+
],
14+
"data": [
15+
"security/groups.xml",
16+
"security/product_packaging_template.xml",
17+
"views/product_template.xml",
18+
"views/product_packaging_template.xml",
19+
],
20+
"installable": True,
21+
}
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
from . import product_packaging
2+
from . import product_packaging_template
3+
from . import product_product
4+
from . import product_template
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
# Copyright 2025 ACSONE SA/NV
2+
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
3+
4+
from odoo import fields, models
5+
6+
7+
class ProductPackaging(models.Model):
8+
_inherit = "product.packaging"
9+
10+
packaging_tmpl_id = fields.Many2one("product.packaging.template", readonly=True)
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
# Copyright 2025 ACSONE SA/NV
2+
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
3+
from odoo import api, fields, models
4+
5+
6+
class ProductPackagingTemplate(models.Model):
7+
_name = "product.packaging.template"
8+
_description = "Product Packaging Template"
9+
10+
name = fields.Char("Product Packaging", required=True)
11+
sequence = fields.Integer(
12+
default=1, help="The first in the sequence is the default one."
13+
)
14+
product_tmpl_id = fields.Many2one(
15+
"product.template",
16+
string="Product Template",
17+
check_company=True,
18+
required=True,
19+
ondelete="cascade",
20+
)
21+
qty = fields.Float(
22+
"Contained Quantity",
23+
default=1,
24+
digits="Product Unit of Measure",
25+
help="Quantity of products contained in the packaging.",
26+
)
27+
company_id = fields.Many2one("res.company", "Company", index=True)
28+
packaging_ids = fields.One2many("product.packaging", "packaging_tmpl_id")
29+
30+
@api.model_create_multi
31+
def create(self, vals_list):
32+
res = super().create(vals_list)
33+
for pt in res:
34+
pt.product_tmpl_id.product_variant_ids._create_packaging_from_template(
35+
template=pt
36+
)
37+
return res
38+
39+
def write(self, vals):
40+
"""
41+
Propagate changes on packages at variant level.
42+
"""
43+
res = super().write(vals)
44+
values_to_propagate = {
45+
key: vals[key] for key in {"name", "sequence", "qty"} if key in vals
46+
}
47+
if values_to_propagate:
48+
self.mapped("packaging_ids").write(values_to_propagate)
49+
return res
50+
51+
def unlink(self):
52+
self.mapped("packaging_ids").unlink()
53+
return super().unlink()
54+
55+
def _prepare_create_values_for_packaging(self):
56+
self.ensure_one()
57+
return {
58+
"name": self.name,
59+
"sequence": self.sequence,
60+
"qty": self.qty,
61+
"company_id": self.company_id.id,
62+
"packaging_tmpl_id": self.id,
63+
}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
# Copyright 2025 ACSONE SA/NV
2+
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
3+
4+
from odoo import api, models
5+
6+
7+
class ProductProduct(models.Model):
8+
_inherit = "product.product"
9+
10+
def _create_packaging_from_template(self, template):
11+
base_values = template._prepare_create_values_for_packaging()
12+
create_values = []
13+
for product in self:
14+
product_values = base_values.copy()
15+
product_values.update({"product_id": product.id})
16+
create_values.append(product_values)
17+
self.env["product.packaging"].create(create_values)
18+
19+
@api.model_create_multi
20+
def create(self, vals_list):
21+
"""
22+
Create all packaging from templates when creating a new variant
23+
"""
24+
res = super().create(vals_list)
25+
for variant in res:
26+
for pt in variant.product_tmpl_id.packaging_tmpl_ids:
27+
variant._create_packaging_from_template(template=pt)
28+
return res
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
# Copyright 2025 ACSONE SA/NV
2+
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
3+
4+
from odoo import fields, models
5+
6+
7+
class ProductTemplate(models.Model):
8+
_inherit = "product.template"
9+
10+
packaging_tmpl_ids = fields.One2many(
11+
"product.packaging.template", "product_tmpl_id"
12+
)
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
[build-system]
2+
requires = ["whool"]
3+
build-backend = "whool.buildapi"
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
- Marie Lejeune \<<[email protected]>\>

0 commit comments

Comments
 (0)