Skip to content
Open
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
89 changes: 89 additions & 0 deletions product_attribute_line_template/README.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
===============================
Product Attribute Line Template
===============================

..
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! This file is generated by oca-gen-addon-readme !!
!! changes will be overwritten. !!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! source digest: sha256:442c166d037d324d30693cffb34a4daf1095d195adc9d35b42d7ba595cec53d9
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

.. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png
:target: https://odoo-community.org/page/development-status
:alt: Beta
.. |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%2Fproduct--attribute-lightgray.png?logo=github
:target: https://github.com/OCA/product-attribute/tree/18.0/product_attribute_line_template
:alt: OCA/product-attribute
.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png
:target: https://translation.odoo-community.org/projects/product-attribute-18-0/product-attribute-18-0-product_attribute_line_template
:alt: Translate me on Weblate
.. |badge5| image:: https://img.shields.io/badge/runboat-Try%20me-875A7B.png
:target: https://runboat.odoo-community.org/builds?repo=OCA/product-attribute&target_branch=18.0
:alt: Try me on Runboat

|badge1| |badge2| |badge3| |badge4| |badge5|

This module allows defining reusable attribute templates and applying
them to products in order to quickly generate attribute lines (without
values).

**Table of contents**

.. contents::
:local:

Usage
=====

1. Go to *Settings > Attribute Templates*.
2. Create one or more attribute templates.
3. Open a product.
4. Select one or more templates in the **Attribute Templates** field.
5. The corresponding attribute lines will be automatically added.

Bug Tracker
===========

Bugs are tracked on `GitHub Issues <https://github.com/OCA/product-attribute/issues>`_.
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
`feedback <https://github.com/OCA/product-attribute/issues/new?body=module:%20product_attribute_line_template%0Aversion:%2018.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**>`_.

Do not contact contributors directly about support or help with technical issues.

Credits
=======

Authors
-------

* Tecnativa

Contributors
------------

- `Tecnativa <https://www.tecnativa.com>`__:

- Pilar Vargas

Maintainers
-----------

This module is maintained by the OCA.

.. image:: https://odoo-community.org/logo.png
:alt: Odoo Community Association
:target: https://odoo-community.org

OCA, or the Odoo Community Association, is a nonprofit organization whose
mission is to support the collaborative development of Odoo features and
promote its widespread use.

This module is part of the `OCA/product-attribute <https://github.com/OCA/product-attribute/tree/18.0/product_attribute_line_template>`_ project on GitHub.

You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.
1 change: 1 addition & 0 deletions product_attribute_line_template/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
from . import models
23 changes: 23 additions & 0 deletions product_attribute_line_template/__manifest__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# Copyright 2026 Tecnativa - Pilar Vargas
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).

{
"name": "Product Attribute Line Template",
"version": "18.0.1.0.0",
"category": "Product",
"summary": "Define attribute-line templates and apply them to products",
"author": "Tecnativa, Odoo Community Association (OCA)",
"website": "https://github.com/OCA/product-attribute",
"license": "AGPL-3",
"depends": [
"sale_management",
],
"data": [
"security/security.xml",
"security/ir.model.access.csv",
"views/product_attribute_template_views.xml",
"views/product_template_views.xml",
],
"installable": True,
"application": False,
}
2 changes: 2 additions & 0 deletions product_attribute_line_template/models/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
from . import product_attribute_template
from . import product_template
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
# Copyright 2026 Tecnativa - Pilar Vargas
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).

from odoo import fields, models


class ProductAttributeTemplate(models.Model):
_name = "product.attribute.template"
_description = "Product Attribute Template"
_order = "name"

name = fields.Char(required=True, translate=True)
active = fields.Boolean(default=True)
company_id = fields.Many2one(
"res.company",
string="Company",
default=lambda self: self.env.company,
help="Leave empty to make it available for all companies.",
)
line_ids = fields.One2many(
"product.attribute.template.line",
"template_id",
string="Attributes",
copy=True,
)

_sql_constraints = [
(
"name_company_uniq",
"unique(name, company_id)",
"A template with the same name already exists for this company.",
)
]


class ProductAttributeTemplateLine(models.Model):
_name = "product.attribute.template.line"
_description = "Product Attribute Template Line"
_order = "sequence, id"

sequence = fields.Integer(default=10)
template_id = fields.Many2one(
"product.attribute.template",
required=True,
ondelete="cascade",
)
attribute_id = fields.Many2one(
"product.attribute",
string="Attribute",
required=True,
help="Attribute to be added to the product when applying this template.",
)

_sql_constraints = [
(
"template_attribute_uniq",
"unique(template_id, attribute_id)",
"This attribute is already included in the template.",
)
]
35 changes: 35 additions & 0 deletions product_attribute_line_template/models/product_template.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
# Copyright 2026 Tecnativa - Pilar Vargas
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).

from odoo import api, fields, models


class ProductTemplate(models.Model):
_inherit = "product.template"

attribute_template_id = fields.Many2one(
"product.attribute.template",
string="Apply attribute template",
help=(
"Select a template to add its attributes to the product. "
"The selection is cleared after applying."
),
)

@api.onchange("attribute_template_id")
def _onchange_attribute_template_id(self):
for product in self:
template = product.attribute_template_id
if not template:
continue
existing_attr_ids = set(
product.attribute_line_ids.mapped("attribute_id").ids
)
for line in template.line_ids.sorted("sequence"):
attr_id = line.attribute_id.id
if attr_id not in existing_attr_ids:
product.attribute_line_ids += self.env[
"product.template.attribute.line"
].new({"attribute_id": attr_id})
existing_attr_ids.add(attr_id)
product.attribute_template_id = False
3 changes: 3 additions & 0 deletions product_attribute_line_template/pyproject.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[build-system]
requires = ["whool"]
build-backend = "whool.buildapi"
3 changes: 3 additions & 0 deletions product_attribute_line_template/readme/CONTRIBUTORS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
- [Tecnativa](https://www.tecnativa.com):

> - Pilar Vargas
2 changes: 2 additions & 0 deletions product_attribute_line_template/readme/DESCRIPTION.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
This module allows defining reusable attribute templates and applying them
to products in order to quickly generate attribute lines (without values).
5 changes: 5 additions & 0 deletions product_attribute_line_template/readme/USAGE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
1. Go to *Settings > Attribute Templates*.
2. Create one or more attribute templates.
3. Open a product.
4. Select one or more templates in the **Attribute Templates** field.
5. The corresponding attribute lines will be automatically added.
3 changes: 3 additions & 0 deletions product_attribute_line_template/security/ir.model.access.csv
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
access_product_attribute_template_manager,product.attribute.template manager,model_product_attribute_template,product.group_product_manager,1,1,1,1
access_product_attribute_template_line_manager,product.attribute.template.line manager,model_product_attribute_template_line,product.group_product_manager,1,1,1,1
20 changes: 20 additions & 0 deletions product_attribute_line_template/security/security.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<?xml version="1.0" encoding="utf-8" ?>
<odoo>
<record id="rule_product_attribute_template_company" model="ir.rule">
<field name="name">Attribute templates: multi-company</field>
<field name="model_id" ref="model_product_attribute_template" />
<field
name="domain_force"
>['|', ('company_id', '=', False), ('company_id', 'in', company_ids)]</field>
<field name="groups" eval="[(4, ref('product.group_product_manager'))]" />
</record>

<record id="rule_product_attribute_template_line_company" model="ir.rule">
<field name="name">Attribute template lines: multi-company</field>
<field name="model_id" ref="model_product_attribute_template_line" />
<field name="domain_force">
['|', ('template_id.company_id', '=', False), ('template_id.company_id', 'in', company_ids)]
</field>
<field name="groups" eval="[(4, ref('product.group_product_manager'))]" />
</record>
</odoo>
Loading
Loading