diff --git a/modules/purchase/view/purchase_line_form.xml b/modules/purchase/view/purchase_line_form.xml
index 5d80677..0fab1be 100755
--- a/modules/purchase/view/purchase_line_form.xml
+++ b/modules/purchase/view/purchase_line_form.xml
@@ -19,6 +19,9 @@ this repository contains the full copyright notices and license terms. -->
+
+
+
diff --git a/modules/purchase_trade/purchase.py b/modules/purchase_trade/purchase.py
index 03c0993..4b3dc27 100755
--- a/modules/purchase_trade/purchase.py
+++ b/modules/purchase_trade/purchase.py
@@ -2,6 +2,7 @@
# this repository contains the full copyright notices and license terms.
from functools import wraps
from trytond.model import ModelSingleton, ModelSQL, ModelView, fields
+from trytond.i18n import gettext
from trytond.report import Report
from trytond.pool import Pool, PoolMeta
from trytond.pyson import Bool, Eval, Id, If, PYSONEncoder
@@ -483,6 +484,42 @@ class Line(metaclass=PoolMeta):
})
premium = fields.Numeric("Premium/Discount",digits='unit')
fee_ = fields.Many2One('fee.fee',"Fee")
+
+ attributes = fields.Dict('product.attribute', 'Attributes',
+ domain=[
+ ('sets', '=', Eval('product._parent_template', {}).get('attribute_set',
+ Eval('attribute_set', -1))),
+ ],
+ states={
+ 'readonly': (~Eval('attribute_set')
+ & ~Eval('product._parent_template', {}).get('attribute_set')),
+ },
+ depends={'product.template'},
+ help="Add attributes to the variant.")
+
+ attributes_name = fields.Function(fields.Char(
+ "Attributes Name",
+ states={
+ 'invisible': ~Eval('attribute_set'),
+ }),
+ 'on_change_with_attributes_name')
+
+ @fields.depends('product', 'attributes')
+ def on_change_with_attributes_name(self, name=None):
+ if not self.product.attribute_set or not self.attributes:
+ return
+
+ def key(attribute):
+ return getattr(attribute, 'sequence', attribute.name)
+
+ values = []
+ for attribute in sorted(self.product.attribute_set.attributes, key=key):
+ if attribute.name in self.attributes:
+ value = self.attributes[attribute.name]
+ values.append(gettext('product_attribute.msg_label_value',
+ label=attribute.string,
+ value=attribute.format(value)))
+ return " | ".join(filter(None, values))
@classmethod
def default_price_type(cls):