Merge lp:~akretion-team/openerp-product-attributes/mixin-extraction into lp:~product-core-editors/openerp-product-attributes/7.0
- mixin-extraction
- Merge into 7.0
Status: | Merged |
---|---|
Merged at revision: | 206 |
Proposed branch: | lp:~akretion-team/openerp-product-attributes/mixin-extraction |
Merge into: | lp:~product-core-editors/openerp-product-attributes/7.0 |
Prerequisite: | lp:~akretion-team/openerp-product-attributes/polymorphic-relations |
Diff against target: |
1225 lines (+560/-341) 14 files modified
base_custom_attributes/__init__.py (+1/-3) base_custom_attributes/__openerp__.py (+6/-9) base_custom_attributes/custom_attributes.py (+148/-52) base_custom_attributes/custom_attributes_view.xml (+171/-226) base_custom_attributes/security/attribute_security.xml (+11/-0) base_custom_attributes/security/ir.model.access.csv (+9/-15) product_categ_attributes/__init__.py (+1/-0) product_categ_attributes/__openerp__.py (+42/-0) product_categ_attributes/product.py (+25/-0) product_categ_attributes/product_view.xml (+52/-0) product_custom_attributes/__init__.py (+2/-0) product_custom_attributes/__openerp__.py (+47/-0) product_custom_attributes/custom_attributes_view.xml (+44/-0) product_custom_attributes/product.py (+1/-36) |
To merge this branch: | bzr merge lp:~akretion-team/openerp-product-attributes/mixin-extraction |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Benoit Guillot - http://www.akretion.com (community) | test | Approve | |
Guewen Baconnier @ Camptocamp | code review, no test | Approve | |
Raphaël Valyi - http://www.akretion.com | Approve | ||
Review via email: mp+151333@code.launchpad.net |
Commit message
Description of the change
See commit messages:
no more code but but code is now split in two modules: product_
Guewen Baconnier @ Camptocamp (gbaconnier-c2c) wrote : | # |
Alexandre Fayolle - camptocamp (alexandre-fayolle-c2c) wrote : | # |
Raphael, Guewen, what is the status of this MP ?
Guewen Baconnier @ Camptocamp (gbaconnier-c2c) wrote : | # |
I'm fine to merge this proposal without changing the nitpickings.
But `openerp.
Raphaël, can you just change this please? The merge proposal can then be merged.
By the way, that's really nice to have extracted this behavior from the product models to a generic module.
Raphaël Valyi - http://www.akretion.com (rvalyi) wrote : | # |
Hello will do that as soon as possible (hopefully today), sorry for the
delay.
On Tue, Mar 19, 2013 at 4:49 AM, Guewen Baconnier @ Camptocamp <
<email address hidden>> wrote:
> Review: Needs Fixing
>
> I'm fine to merge this proposal without changing the nitpickings.
> But `openerp.
> Raphaël, can you just change this please? The merge proposal can then be
> merged.
>
> By the way, that's really nice to have extracted this behavior from the
> product models to a generic module.
> --
>
> https:/
> Your team OpenERP Community is subscribed to branch
> lp:openerp-product-attributes.
>
> _______
> Mailing list: https:/
> Post to : <email address hidden>
> Unsubscribe : https:/
> More help : https:/
>
Guewen Baconnier @ Camptocamp (gbaconnier-c2c) wrote : | # |
Thanks for the change
Guewen Baconnier @ Camptocamp (gbaconnier-c2c) wrote : | # |
I tried to merge lp:~akretion-team/openerp-product-attributes/polymorphic-relations, then this branch, but when I merge this one I have a conflict. Can you check why please?
- 205. By Raphaël Valyi - http://www.akretion.com
-
[IMP] Generalization of product_
custom_ attributes for OpenERP v7. See detailed logs for more information - 206. By Sébastien BEAU - http://www.akretion.com
-
[MERGE] update with stable branch
- 207. By Sébastien BEAU - http://www.akretion.com
-
[MERGE] merge view improvement from benoit branch
- 208. By Sébastien BEAU - http://www.akretion.com
-
[MERGE] merge Benoit branch for improving view, do some refactor due to the change done in mixing branch
- 209. By Sébastien BEAU - http://www.akretion.com
-
[TYPO] no change juste reorganise the code
- 210. By Sébastien BEAU - http://www.akretion.com
-
[REF] Continue refactor, move attribut set to abstract module
- 211. By Sébastien BEAU - http://www.akretion.com
-
[REF] base_custom_
attributes : refcator view and add model on set and group. Now the model of the attrbitue is filtred according to the model selected on the set or the group - 212. By Sébastien BEAU - http://www.akretion.com
-
[REF] continue refactor, now the abstract model base_custom_
attributs have some special option like force model, take a look in product_ custom_ attribut, just add {'force_model': 'our_model'} in the context and the model will be hide and automatically filled - 213. By Sébastien BEAU - http://www.akretion.com
-
[REF] rename custom.attribute into attribute.attribute
- 214. By Sébastien BEAU - http://www.akretion.com
-
[IMP] add a special group for advanced option
- 215. By Sébastien BEAU - http://www.akretion.com
-
[IMP] base_custom_
attribute: if the field have the type multiselect the option serialized is hide as we have no choice and the option have to be selected - 216. By Sébastien BEAU - http://www.akretion.com
-
[FIX] fix error due to previous merge
- 217. By Sébastien BEAU - http://www.akretion.com
-
[REF] Remove useless file
Sébastien BEAU - http://www.akretion.com (sebastien.beau) wrote : | # |
Hi all
I merge the improvement done by Benoit
https:/
https:/
I extract the attribut.set from the product custom module
I added the model on the group and the attibut set and it's propagated.
The model is also correctly filtred on the attributs
And I also did some other view improvement.
Let's merge it ;)
Raphaël Valyi - http://www.akretion.com (rvalyi) wrote : | # |
You rock Seb, this is really a pleasure to have this result now. Now we have both the killer ergnomy of product_
Raphaël Valyi - http://www.akretion.com (rvalyi) wrote : | # |
(Just to mention: I both tested and looked at the code)
Guewen Baconnier @ Camptocamp (gbaconnier-c2c) wrote : | # |
l.78 the import from `tools.translate` should be from `openerp.
once that fixed, I'll be ok for the merge
- 218. By Sébastien BEAU - http://www.akretion.com
-
[FIX] fix incorrect importing of translate tools _ Thanks to Guewen
Sébastien BEAU - http://www.akretion.com (sebastien.beau) wrote : | # |
Thanks Guewen for your remark. It's fix now.
Guewen Baconnier @ Camptocamp (gbaconnier-c2c) wrote : | # |
Thanks for the change
LGTM
- 219. By Benoit Guillot - http://www.akretion.com
-
[FIX] remove 'product' in base_custom_
atributeviews - 220. By Benoit Guillot - http://www.akretion.com
-
[FIX] clean imports, and fix encoding of strings
Benoit Guillot - http://www.akretion.com (benoit-guillot-z) wrote : | # |
I made fiew fixes.
debaetsr (rubendebaets) wrote : | # |
Hey,
I've read a lovely book recently, the author is admired by everyone, you should read the book too, that's for sure, here is the link <http://
Sincerely, ruben
Preview Diff
1 | === renamed directory 'product_custom_attributes' => 'base_custom_attributes' |
2 | === modified file 'base_custom_attributes/__init__.py' |
3 | --- product_custom_attributes/__init__.py 2012-08-03 14:33:51 +0000 |
4 | +++ base_custom_attributes/__init__.py 2013-06-18 16:21:29 +0000 |
5 | @@ -22,9 +22,7 @@ |
6 | |
7 | |
8 | import ir_model |
9 | -import product_attribute |
10 | -import product |
11 | -import wizard |
12 | +import custom_attributes |
13 | |
14 | |
15 | |
16 | |
17 | === modified file 'base_custom_attributes/__openerp__.py' |
18 | --- product_custom_attributes/__openerp__.py 2013-02-11 22:58:10 +0000 |
19 | +++ base_custom_attributes/__openerp__.py 2013-06-18 16:21:29 +0000 |
20 | @@ -1,7 +1,7 @@ |
21 | # -*- encoding: utf-8 -*- |
22 | ############################################################################### |
23 | # # |
24 | -# product_custom_attributes for OpenERP # |
25 | +# base_custom_attributes for OpenERP # |
26 | # Copyright (C) 2011 Akretion Benoît GUILLOT <benoit.guillot@akretion.com> # |
27 | # # |
28 | # This program is free software: you can redistribute it and/or modify # |
29 | @@ -22,23 +22,20 @@ |
30 | |
31 | |
32 | { |
33 | - 'name': 'product_custom_attributes', |
34 | + 'name': 'base_custom_attributes', |
35 | 'version': '0.1', |
36 | 'category': 'Generic Modules/Others', |
37 | 'license': 'AGPL-3', |
38 | - 'description': """This module adds the possibility to easily create custom fields on products. |
39 | -Each product can be linked to an attribute set (like camera, fridge...). |
40 | -Each attribute has custom fields (for example, you don't need the same field for a frigde and a camera). |
41 | + 'description': """This module adds the possibility to easily create custom attributes in any OpenERP business object. See the product_custom_attributes module for instance. |
42 | """, |
43 | 'author': 'Akretion', |
44 | 'website': 'http://www.akretion.com/', |
45 | - 'depends': ['product'], |
46 | + 'depends': ['base'], |
47 | 'init_xml': [], |
48 | 'update_xml': [ |
49 | 'security/ir.model.access.csv', |
50 | - 'product_attribute_view.xml', |
51 | - 'product_view.xml', |
52 | - 'wizard/open_product_by_attribute_set.xml', |
53 | + 'security/attribute_security.xml', |
54 | + 'custom_attributes_view.xml', |
55 | ], |
56 | 'demo_xml': [], |
57 | 'installable': True, |
58 | |
59 | === renamed file 'product_custom_attributes/product_attribute.py' => 'base_custom_attributes/custom_attributes.py' |
60 | --- product_custom_attributes/product_attribute.py 2013-06-13 16:55:06 +0000 |
61 | +++ base_custom_attributes/custom_attributes.py 2013-06-18 16:21:29 +0000 |
62 | @@ -1,8 +1,9 @@ |
63 | # -*- encoding: utf-8 -*- |
64 | ############################################################################### |
65 | # # |
66 | -# product_custom_attributes for OpenERP # |
67 | +# base_attribute.attributes for OpenERP # |
68 | # Copyright (C) 2011 Akretion Benoît GUILLOT <benoit.guillot@akretion.com> # |
69 | +# Copyright (C) 2013 Akretion Raphaël VALYI <raphael.valyi@akretion.com> # |
70 | # # |
71 | # This program is free software: you can redistribute it and/or modify # |
72 | # it under the terms of the GNU Affero General Public License as # |
73 | @@ -19,13 +20,13 @@ |
74 | # # |
75 | ############################################################################### |
76 | |
77 | -from openerp.osv import orm |
78 | -from openerp.osv import fields |
79 | +from openerp.osv import orm, fields |
80 | from openerp.osv.osv import except_osv |
81 | +from openerp.tools.translate import _ |
82 | from lxml import etree |
83 | -from openerp.tools.translate import _ |
84 | from unidecode import unidecode # Debian package python-unidecode |
85 | |
86 | + |
87 | class attribute_option(orm.Model): |
88 | _name = "attribute.option" |
89 | _description = "Attribute Option" |
90 | @@ -34,7 +35,7 @@ |
91 | _columns = { |
92 | 'name': fields.char('Name', size=128, translate=True, required=True), |
93 | 'value_ref': fields.reference('Reference', selection=[], size=128), |
94 | - 'attribute_id': fields.many2one('product.attribute', 'Product Attribute', required=True), |
95 | + 'attribute_id': fields.many2one('attribute.attribute', 'Product Attribute', required=True), |
96 | 'sequence': fields.integer('Sequence'), |
97 | } |
98 | |
99 | @@ -45,12 +46,13 @@ |
100 | else: |
101 | return True |
102 | |
103 | + |
104 | class attribute_option_wizard(orm.TransientModel): |
105 | _name = "attribute.option.wizard" |
106 | _rec_name = 'attribute_id' |
107 | |
108 | _columns = { |
109 | - 'attribute_id': fields.many2one('product.attribute', 'Product Attribute', required=True), |
110 | + 'attribute_id': fields.many2one('attribute.attribute', 'Product Attribute', required=True), |
111 | } |
112 | |
113 | _defaults = { |
114 | @@ -61,7 +63,7 @@ |
115 | return True |
116 | |
117 | def create(self, cr, uid, vals, context=None): |
118 | - attr_obj = self.pool.get("product.attribute") |
119 | + attr_obj = self.pool.get("attribute.attribute") |
120 | attr = attr_obj.browse(cr, uid, vals['attribute_id']) |
121 | op_ids = [op.id for op in attr.option_ids] |
122 | opt_obj = self.pool.get("attribute.option") |
123 | @@ -80,7 +82,7 @@ |
124 | def fields_view_get(self, cr, uid, view_id=None, view_type='form', context=None, toolbar=False, submenu=False): |
125 | res = super(attribute_option_wizard, self).fields_view_get(cr, uid, view_id, view_type, context, toolbar, submenu) |
126 | if view_type == 'form' and context and context.get("attribute_id"): |
127 | - attr_obj = self.pool.get("product.attribute") |
128 | + attr_obj = self.pool.get("attribute.attribute") |
129 | model_id = attr_obj.read(cr, uid, [context.get("attribute_id")], ['relation_model_id'])[0]['relation_model_id'][0] |
130 | relation = self.pool.get("ir.model").read(cr, uid, [model_id], ["model"])[0]["model"] |
131 | res['fields'].update({'option_ids': { |
132 | @@ -99,11 +101,47 @@ |
133 | return res |
134 | |
135 | |
136 | -class product_attribute(orm.Model): |
137 | - _name = "product.attribute" |
138 | - _description = "Product Attribute" |
139 | +class attribute_attribute(orm.Model): |
140 | + _name = "attribute.attribute" |
141 | + _description = "Attribute" |
142 | _inherits = {'ir.model.fields': 'field_id'} |
143 | |
144 | + def _build_attribute_field(self, cr, uid, page, attribute, context=None): |
145 | + parent = etree.SubElement(page, 'group', colspan="2", col="4") |
146 | + kwargs = {'name': "%s" % attribute.name} |
147 | + if attribute.ttype in ['many2many', 'text']: |
148 | + parent = etree.SubElement(parent, 'group', colspan="2", col="4") |
149 | + sep = etree.SubElement(parent, |
150 | + 'separator', |
151 | + string="%s" % attribute.field_description, |
152 | + colspan="4") |
153 | + |
154 | + kwargs['nolabel'] = "1" |
155 | + if attribute.ttype in ['many2one', 'many2many']: |
156 | + if attribute.relation_model_id: |
157 | + if attribute.domain: |
158 | + kwargs['domain'] = attribute.domain |
159 | + else: |
160 | + ids = [op.value_ref.id for op in attribute.option_ids] |
161 | + kwargs['domain'] = "[('id', 'in', %s)]" % ids |
162 | + else: |
163 | + kwargs['domain'] = "[('attribute_id', '=', %s)]" % attribute.attribute_id.id |
164 | + field = etree.SubElement(parent, 'field', **kwargs) |
165 | + orm.setup_modifiers(field, self.fields_get(cr, uid, attribute.name, context)) |
166 | + return parent |
167 | + |
168 | + def _build_attributes_notebook(self, cr, uid, attribute_group_ids, context=None): |
169 | + notebook = etree.Element('notebook', name="attributes_notebook", colspan="4") |
170 | + toupdate_fields = [] |
171 | + grp_obj = self.pool.get('attribute.group') |
172 | + for group in grp_obj.browse(cr, uid, attribute_group_ids, context=context): |
173 | + page = etree.SubElement(notebook, 'page', string=group.name.capitalize()) |
174 | + for attribute in group.attribute_ids: |
175 | + if attribute.name not in toupdate_fields: |
176 | + toupdate_fields.append(attribute.name) |
177 | + self._build_attribute_field(cr, uid, page, attribute, context=context) |
178 | + return notebook, toupdate_fields |
179 | + |
180 | def relation_model_id_change(self, cr, uid, ids, relation_model_id, option_ids, context=None): |
181 | "removed selected options as they would be inconsistent" |
182 | return {'value': {'option_ids': [(2, i[1]) for i in option_ids]}} |
183 | @@ -147,6 +185,17 @@ |
184 | [vals.get('relation_model_id')], ['model'])[0]['model'] |
185 | else: |
186 | relation = 'attribute.option' |
187 | + |
188 | + if vals['attribute_type'] == 'select': |
189 | + vals['ttype'] = 'many2one' |
190 | + vals['relation'] = relation |
191 | + elif vals['attribute_type'] == 'multiselect': |
192 | + vals['ttype'] = 'many2many' |
193 | + vals['relation'] = relation |
194 | + vals['serialized'] = True |
195 | + else: |
196 | + vals['ttype'] = vals['attribute_type'] |
197 | + |
198 | if vals.get('serialized'): |
199 | field_obj = self.pool.get('ir.model.fields') |
200 | serialized_ids = field_obj.search(cr, uid, |
201 | @@ -156,56 +205,56 @@ |
202 | vals['serialization_field_id'] = serialized_ids[0] |
203 | else: |
204 | f_vals = { |
205 | - 'name': 'x_custom_json_attrs', |
206 | - 'field_description': 'Serialized JSON Attributes', |
207 | + 'name': u'x_custom_json_attrs', |
208 | + 'field_description': u'Serialized JSON Attributes', |
209 | 'ttype': 'serialized', |
210 | 'model_id': vals['model_id'], |
211 | } |
212 | vals['serialization_field_id'] = field_obj.create(cr, uid, f_vals, {'manual': True}) |
213 | - if vals['attribute_type'] == 'select': |
214 | - vals['ttype'] = 'many2one' |
215 | - vals['relation'] = relation |
216 | - elif vals['attribute_type'] == 'multiselect': |
217 | - vals['ttype'] = 'many2many' |
218 | - vals['relation'] = relation |
219 | - if not vals.get('serialized'): |
220 | - raise except_osv(_('Create Error'), _("The field serialized should be ticked for a multiselect field !")) |
221 | - else: |
222 | - vals['ttype'] = vals['attribute_type'] |
223 | vals['state'] = 'manual' |
224 | - return super(product_attribute, self).create(cr, uid, vals, context) |
225 | + return super(attribute_attribute, self).create(cr, uid, vals, context) |
226 | |
227 | def onchange_field_description(self, cr, uid, ids, field_description, context=None): |
228 | - name = 'x_' |
229 | + name = u'x_' |
230 | if field_description: |
231 | - name = unidecode('x_%s' % field_description.replace(' ', '_').lower()) |
232 | + name = unidecode(u'x_%s' % field_description.replace(' ', '_').lower()) |
233 | return {'value' : {'name' : name}} |
234 | |
235 | def onchange_name(self, cr, uid, ids, name, context=None): |
236 | + res = {} |
237 | if not name.startswith('x_'): |
238 | - name = 'x_%s' % name |
239 | - return {'value' : {'name' : unidecode(name)}} |
240 | - |
241 | - |
242 | -class attribute_location(orm.Model): |
243 | - _name = "attribute.location" |
244 | - _description = "Attribute Location" |
245 | - _order="sequence" |
246 | - _inherits = {'product.attribute': 'attribute_id'} |
247 | - |
248 | - |
249 | - def _get_attribute_loc_from_group(self, cr, uid, ids, context=None): |
250 | - return self.pool.get('attribute.location').search(cr, uid, [('attribute_group_id', 'in', ids)], context=context) |
251 | - |
252 | - _columns = { |
253 | - 'attribute_id': fields.many2one('product.attribute', 'Product Attribute', required=True, ondelete="cascade"), |
254 | - 'attribute_set_id': fields.related('attribute_group_id', 'attribute_set_id', type='many2one', relation='attribute.set', string='Attribute Set', readonly=True, |
255 | -store={ |
256 | - 'attribute.group': (_get_attribute_loc_from_group, ['attribute_set_id'], 10), |
257 | - }), |
258 | - 'attribute_group_id': fields.many2one('attribute.group', 'Attribute Group', required=True), |
259 | - 'sequence': fields.integer('Sequence'), |
260 | - } |
261 | + name = u'x_%s' % name |
262 | + else: |
263 | + name = u'%s' % name |
264 | + res = {'value' : {'name' : unidecode(name)}} |
265 | + |
266 | + #FILTER ON MODEL |
267 | + model_domain = [] |
268 | + model_name = context.get('force_model') |
269 | + if not model_name: |
270 | + model_id = context.get('default_model_id') |
271 | + if model_id: |
272 | + model = self.pool['ir.model'].browse(cr, uid, model_id, context=context) |
273 | + model_name = model.model |
274 | + if model_name: |
275 | + model_obj = self.pool[model_name] |
276 | + allowed_model = [x for x in model_obj._inherits] + [model_name] |
277 | + res['domain'] = {'model_id': [['model', 'in', allowed_model]]} |
278 | + |
279 | + return res |
280 | + |
281 | + def _get_default_model(self, cr, uid, context=None): |
282 | + if context and context.get('force_model'): |
283 | + model_id = self.pool['ir.model'].search(cr, uid, [ |
284 | + ['model', '=', context['force_model']] |
285 | + ], context=context) |
286 | + if model_id: |
287 | + return model_id[0] |
288 | + return None |
289 | + |
290 | + _defaults = { |
291 | + 'model_id': _get_default_model |
292 | + } |
293 | |
294 | |
295 | class attribute_group(orm.Model): |
296 | @@ -215,9 +264,10 @@ |
297 | |
298 | _columns = { |
299 | 'name': fields.char('Name', size=128, required=True), |
300 | + 'sequence': fields.integer('Sequence'), |
301 | 'attribute_set_id': fields.many2one('attribute.set', 'Attribute Set'), |
302 | 'attribute_ids': fields.one2many('attribute.location', 'attribute_group_id', 'Attributes'), |
303 | - 'sequence': fields.integer('Sequence'), |
304 | + 'model_id': fields.many2one('ir.model', 'Model', required=True), |
305 | } |
306 | |
307 | def create(self, cr, uid, vals, context=None): |
308 | @@ -226,6 +276,19 @@ |
309 | attribute[2]['attribute_set_id'] = vals['attribute_set_id'] |
310 | return super(attribute_group, self).create(cr, uid, vals, context) |
311 | |
312 | + def _get_default_model(self, cr, uid, context=None): |
313 | + if context and context.get('force_model'): |
314 | + model_id = self.pool['ir.model'].search(cr, uid, [ |
315 | + ['model', '=', context['force_model']] |
316 | + ], context=context) |
317 | + if model_id: |
318 | + return model_id[0] |
319 | + return None |
320 | + |
321 | + _defaults = { |
322 | + 'model_id': _get_default_model |
323 | + } |
324 | + |
325 | |
326 | class attribute_set(orm.Model): |
327 | _name = "attribute.set" |
328 | @@ -233,5 +296,38 @@ |
329 | _columns = { |
330 | 'name': fields.char('Name', size=128, required=True), |
331 | 'attribute_group_ids': fields.one2many('attribute.group', 'attribute_set_id', 'Attribute Groups'), |
332 | - } |
333 | - |
334 | + 'model_id': fields.many2one('ir.model', 'Model', required=True), |
335 | + } |
336 | + |
337 | + def _get_default_model(self, cr, uid, context=None): |
338 | + if context and context.get('force_model'): |
339 | + model_id = self.pool['ir.model'].search(cr, uid, [ |
340 | + ['model', '=', context['force_model']] |
341 | + ], context=context) |
342 | + if model_id: |
343 | + return model_id[0] |
344 | + return None |
345 | + |
346 | + _defaults = { |
347 | + 'model_id': _get_default_model |
348 | + } |
349 | + |
350 | +class attribute_location(orm.Model): |
351 | + _name = "attribute.location" |
352 | + _description = "Attribute Location" |
353 | + _order="sequence" |
354 | + _inherits = {'attribute.attribute': 'attribute_id'} |
355 | + |
356 | + |
357 | + def _get_attribute_loc_from_group(self, cr, uid, ids, context=None): |
358 | + return self.pool.get('attribute.location').search(cr, uid, [('attribute_group_id', 'in', ids)], context=context) |
359 | + |
360 | + _columns = { |
361 | + 'attribute_id': fields.many2one('attribute.attribute', 'Product Attribute', required=True, ondelete="cascade"), |
362 | + 'attribute_set_id': fields.related('attribute_group_id', 'attribute_set_id', type='many2one', relation='attribute.set', string='Attribute Set', readonly=True, |
363 | +store={ |
364 | + 'attribute.group': (_get_attribute_loc_from_group, ['attribute_set_id'], 10), |
365 | + }), |
366 | + 'attribute_group_id': fields.many2one('attribute.group', 'Attribute Group', required=True), |
367 | + 'sequence': fields.integer('Sequence'), |
368 | + } |
369 | |
370 | === renamed file 'product_custom_attributes/product_attribute_view.xml' => 'base_custom_attributes/custom_attributes_view.xml' |
371 | --- product_custom_attributes/product_attribute_view.xml 2013-02-28 20:39:39 +0000 |
372 | +++ base_custom_attributes/custom_attributes_view.xml 2013-06-18 16:21:29 +0000 |
373 | @@ -1,6 +1,6 @@ |
374 | <?xml version="1.0" encoding="utf-8"?> |
375 | <!-- |
376 | - product_custom_attributes for OpenERP |
377 | + base_custom_attributes for OpenERP |
378 | Copyright (C) 2011-2013 Akretion (http://www.akretion.com/) |
379 | @author: Benoît GUILLOT <benoit.guillot@akretion.com> |
380 | The licence is in the file __openerp__.py |
381 | @@ -10,37 +10,65 @@ |
382 | <data> |
383 | |
384 | <menuitem |
385 | - id="menu_attribute_in_config_product" name="Attributes" |
386 | - parent="product.prod_config_main" sequence="20"/> |
387 | + id="menu_attribute_in_admin" name="Attributes" |
388 | + parent="base.next_id_9" sequence="1"/> |
389 | + |
390 | + <!-- ATTRIBUTE SET VIEW --> |
391 | |
392 | <record id="attribute_set_form_view" model="ir.ui.view"> |
393 | <field name="name">attribute.set.form</field> |
394 | <field name="model">attribute.set</field> |
395 | <field name="arch" type="xml"> |
396 | <form string="Attribute Set"> |
397 | - <field name="name" colspan="4"/> |
398 | - <field name="attribute_group_ids" colspan="4" > |
399 | - <form string="Attribute Groups"> |
400 | - <field name="name" /> |
401 | - <field name="sequence" /> |
402 | - <field name="attribute_ids" colspan="4"> |
403 | - <form string="Attribute Location"> |
404 | - <field name="attribute_id" /> |
405 | - <field name="sequence" /> |
406 | - </form> |
407 | - <tree string="Attribute Location"> |
408 | - <field name="attribute_id" /> |
409 | - </tree> |
410 | - </field> |
411 | - </form> |
412 | - <tree string="Attribute Groups"> |
413 | - <field name="name" /> |
414 | - </tree> |
415 | + <field name="name"/> |
416 | + <field name="model_id" invisible="context.get('force_model')"/> |
417 | + <field name="attribute_group_ids" colspan="4" |
418 | + context="{'default_model_id': model_id, 'from_attribute_set':True}"> |
419 | </field> |
420 | </form> |
421 | </field> |
422 | </record> |
423 | |
424 | + <record id="attribute_set_tree_view" model="ir.ui.view"> |
425 | + <field name="name">attribute.set.tree</field> |
426 | + <field name="model">attribute.set</field> |
427 | + <field name="arch" type="xml"> |
428 | + <tree string="Attribute Set" > |
429 | + <field name="name" /> |
430 | + <field name="model_id" /> |
431 | + </tree> |
432 | + </field> |
433 | + </record> |
434 | + |
435 | + <record id="view_attribute_set_search" model="ir.ui.view"> |
436 | + <field name="name">attribute.set.list</field> |
437 | + <field name="model">attribute.set</field> |
438 | + <field name="arch" type="xml"> |
439 | + <search string="Search Attribute Sets"> |
440 | + <field name="name"/> |
441 | + <field name="model_id" /> |
442 | + </search> |
443 | + </field> |
444 | + </record> |
445 | + |
446 | + <record id="attribute_set_form_action" model="ir.actions.act_window"> |
447 | + <field name="name">Attribute Sets</field> |
448 | + <field name="res_model">attribute.set</field> |
449 | + <field name="view_type">form</field> |
450 | + <field name="view_mode">tree,form</field> |
451 | + <field name="search_view_id" ref="view_attribute_set_search"/> |
452 | + <field name="context">{"search_default_user_id":uid}</field> |
453 | + <field name="help"></field> |
454 | + </record> |
455 | + |
456 | + <menuitem |
457 | + action="attribute_set_form_action" id="menu_attribute_set_action" |
458 | + parent="menu_attribute_in_admin" sequence="10"/> |
459 | + |
460 | + |
461 | + |
462 | + <!-- ATTRIBUTE GROUP VIEW --> |
463 | + |
464 | <record id="attribute_group_form_view" model="ir.ui.view"> |
465 | <field name="name">attribute.group.form</field> |
466 | <field name="model">attribute.group</field> |
467 | @@ -48,253 +76,168 @@ |
468 | <form string="Attribute Group"> |
469 | <field name="name" /> |
470 | <field name="sequence" /> |
471 | - <field name="attribute_set_id" /> |
472 | + <field name="model_id" invisible="context.get('from_attribute_set') or context.get('force_model')"/> |
473 | + <field name="attribute_set_id" invisible="context.get('from_attribute_set')"/> |
474 | <field name="attribute_ids" colspan="4" nolabel="1"> |
475 | <form string="Attribute Location"> |
476 | - <field name="attribute_id" /> |
477 | + <field name="attribute_id" context="{'default_model_id': parent.model_id}"/> |
478 | <field name="sequence" /> |
479 | </form> |
480 | - <tree string="Attribute Location"> |
481 | - <field name="attribute_id" /> |
482 | + <tree string="Attribute Location" editable="top"> |
483 | + <field name="attribute_id" context="{'default_model_id': parent.model_id}"/> |
484 | + <field name="sequence" /> |
485 | </tree> |
486 | </field> |
487 | </form> |
488 | </field> |
489 | </record> |
490 | |
491 | - <record id="attribute_location_form_view" model="ir.ui.view"> |
492 | - <field name="name">attribute.location.form</field> |
493 | - <field name="model">attribute.location</field> |
494 | + <record id="attribute_group_tree_view" model="ir.ui.view"> |
495 | + <field name="name">attribute.group.tree</field> |
496 | + <field name="model">attribute.group</field> |
497 | <field name="arch" type="xml"> |
498 | - <form string="Attribute Location"> |
499 | - <field name="attribute_id" /> |
500 | + <tree string="Attribute Group"> |
501 | + <field name="name" /> |
502 | <field name="sequence" /> |
503 | - <field name="attribute_group_id" /> |
504 | - <field name="attribute_set_id" /> |
505 | - </form> |
506 | - </field> |
507 | - </record> |
508 | - |
509 | - <record id="product_attribute_form_view" model="ir.ui.view"> |
510 | - <field name="name">product.attribute.form</field> |
511 | - <field name="model">product.attribute</field> |
512 | - <field name="arch" type="xml"> |
513 | - <form string="Product Attribute"> |
514 | + <field name="attribute_set_id" invisible="context.get('from_attribute_set')"/> |
515 | + <field name="model_id" invisible="context.get('from_attribute_set')"/> |
516 | + </tree> |
517 | + </field> |
518 | + </record> |
519 | + |
520 | + <record id="view_attribute_group_search" model="ir.ui.view"> |
521 | + <field name="name">attribute.group.list</field> |
522 | + <field name="model">attribute.group</field> |
523 | + <field name="arch" type="xml"> |
524 | + <search string="Search Attribute Groups"> |
525 | + <field name="name"/> |
526 | + <field name="attribute_set_id"/> |
527 | + <field name="model_id" /> |
528 | + </search> |
529 | + </field> |
530 | + </record> |
531 | + |
532 | + |
533 | + <record id="attribute_group_form_action" model="ir.actions.act_window"> |
534 | + <field name="name">Attribute Groups</field> |
535 | + <field name="res_model">attribute.group</field> |
536 | + <field name="view_type">form</field> |
537 | + <field name="view_mode">tree,form</field> |
538 | + <field name="context">{"search_default_user_id":uid}</field> |
539 | + <field name="help"></field> |
540 | + </record> |
541 | + |
542 | + <menuitem |
543 | + action="attribute_group_form_action" id="menu_attribute_group_action" |
544 | + parent="menu_attribute_in_admin" sequence="20"/> |
545 | + |
546 | + <!-- ATTRIBUTE VIEW --> |
547 | + |
548 | + <record id="attribute_attribute_form_view" model="ir.ui.view"> |
549 | + <field name="name">attribute.attribute.form</field> |
550 | + <field name="model">attribute.attribute</field> |
551 | + <field name="arch" type="xml"> |
552 | + <form string="Attribute"> |
553 | <field name="field_description" on_change="onchange_field_description(field_description, context)"/> |
554 | <field name="name" attrs="{'readonly':[('create_date', '!=', False)]}" on_change="onchange_name(name, context)"/> |
555 | <field name="attribute_type" /> |
556 | <field name="model_id" /> |
557 | - <field name="serialized" /> |
558 | + <field name="serialized" attrs="{'invisible':[('attribute_type', '=', 'multiselect')]}"/> |
559 | <field name="size" attrs="{'invisible':[('attribute_type', '!=', 'char')]}"/> |
560 | <field name="translate" attrs="{'invisible':[('attribute_type', 'not in', ('char', 'text'))]}"/> |
561 | <newline /> |
562 | <group colspan="4" attrs="{'invisible':[('attribute_type', 'not in', ['select', 'multiselect'])]}"> |
563 | - <field name="relation_model_id" on_change="relation_model_id_change(relation_model_id, option_ids, context)"/> |
564 | - <field name="domain" attrs="{'invisible':[('relation_model_id', '=', False)]}"/> |
565 | - <group colspan="4" attrs="{'invisible':[('domain', '!=', False)]}"> |
566 | - <button name="button_add_options" attrs="{'invisible':[('relation_model_id', '=', False)]}" type="object" string="Change Options"/> |
567 | - <field name="option_ids" colspan="4" nolabel="1"> |
568 | - <tree string="Attribute Options" editable="top"> |
569 | - <field name="sequence" invisible="1"/> |
570 | - <field name="name" on_change="name_change(name, parent.relation_model_id, context)"/> |
571 | - </tree> |
572 | - </field> |
573 | - </group> |
574 | + <group groups="base.group_advanced_attribute"> |
575 | + <field name="relation_model_id" on_change="relation_model_id_change(relation_model_id, option_ids, context)"/> |
576 | + <field name="domain" attrs="{'invisible':[('relation_model_id', '=', False)]}"/> |
577 | + <button name="button_add_options" attrs="{'invisible':[('relation_model_id', '=', False), ('domain', '!=', False)]}" type="object" string="Load Options"/> |
578 | + </group> |
579 | + <field name="option_ids" colspan="4" nolabel="1"> |
580 | + <tree string="Attribute Options" editable="top"> |
581 | + <field name="sequence" invisible="1"/> |
582 | + <field name="name" on_change="name_change(name, parent.relation_model_id, context)"/> |
583 | + </tree> |
584 | + </field> |
585 | </group> |
586 | <field name="create_date" invisible="1"/> |
587 | </form> |
588 | </field> |
589 | </record> |
590 | - |
591 | - <record id="attribute_option_wizard_form_view" model="ir.ui.view"> |
592 | - <field name="name">attribute.option.wizard</field> |
593 | - <field name="model">attribute.option.wizard</field> |
594 | - <field name="arch" type="xml"> |
595 | - <form string="Options Wizard" col="6"> |
596 | - <field name="attribute_id" invisible="1" colspan="2"/> |
597 | - <separator string="options_placeholder"/> |
598 | - <button special="cancel" string="Cancel" icon="gtk-cancel"/> |
599 | - <button name="validate" string="Validate" type="object" icon="gtk-convert"/> |
600 | - </form> |
601 | - </field> |
602 | - </record> |
603 | - |
604 | + |
605 | + <record id="attribute_attribute_tree_view" model="ir.ui.view"> |
606 | + <field name="name">attribute.attribute.tree</field> |
607 | + <field name="model">attribute.attribute</field> |
608 | + <field name="arch" type="xml"> |
609 | + <tree string="Attribute"> |
610 | + <field name="name" /> |
611 | + <field name="attribute_type" /> |
612 | + </tree> |
613 | + </field> |
614 | + </record> |
615 | + |
616 | + <record id="view_attribute_attribute_search" model="ir.ui.view"> |
617 | + <field name="name">attribute.attribute.list</field> |
618 | + <field name="model">attribute.attribute</field> |
619 | + <field name="arch" type="xml"> |
620 | + <search string="Search Attributes"> |
621 | + <field name="name"/> |
622 | + </search> |
623 | + </field> |
624 | + </record> |
625 | + |
626 | + <record id="attribute_attribute_form_action" model="ir.actions.act_window"> |
627 | + <field name="name">Attributes</field> |
628 | + <field name="res_model">attribute.attribute</field> |
629 | + <field name="view_type">form</field> |
630 | + <field name="view_mode">tree,form</field> |
631 | + <field name="search_view_id" ref="view_attribute_attribute_search"/> |
632 | + <field name="context">{"search_default_user_id":uid}</field> |
633 | + <field name="help"></field> |
634 | + </record> |
635 | + <menuitem |
636 | + action="attribute_attribute_form_action" id="menu_attribute_attribute_action" |
637 | + parent="menu_attribute_in_admin" sequence="30"/> |
638 | + |
639 | + <!-- ATTRIBUTE OPTION VIEW --> |
640 | <record id="attribute_option_form_view" model="ir.ui.view"> |
641 | <field name="name">attribute.option.form</field> |
642 | <field name="model">attribute.option</field> |
643 | <field name="arch" type="xml"> |
644 | <form string="Attribute Option" col="6"> |
645 | - <field name="value_ref" colspan="2"/> |
646 | + <field name="name" colspan="2"/> |
647 | + <field name="value_ref" colspan="2" groups="base.group_advanced_attribute"/> |
648 | <field name="sequence" colspan="2"/> |
649 | <field name="attribute_id" colspan="2"/> |
650 | </form> |
651 | </field> |
652 | </record> |
653 | - |
654 | - <record id="attribute_set_tree_view" model="ir.ui.view"> |
655 | - <field name="name">attribute.set.tree</field> |
656 | - <field name="model">attribute.set</field> |
657 | - <field name="arch" type="xml"> |
658 | - <tree string="Attribute Set" > |
659 | - <field name="name" /> |
660 | - </tree> |
661 | - </field> |
662 | - </record> |
663 | - |
664 | - <record id="attribute_group_tree_view" model="ir.ui.view"> |
665 | - <field name="name">attribute.group.tree</field> |
666 | - <field name="model">attribute.group</field> |
667 | - <field name="arch" type="xml"> |
668 | - <tree string="Attribute Group"> |
669 | - <field name="name" /> |
670 | - <field name="sequence" /> |
671 | - <field name="attribute_set_id" /> |
672 | - </tree> |
673 | - </field> |
674 | - </record> |
675 | - |
676 | - <record id="attribute_location_tree_view" model="ir.ui.view"> |
677 | - <field name="name">attribute.location.tree</field> |
678 | - <field name="model">attribute.location</field> |
679 | - <field name="arch" type="xml"> |
680 | - <tree string="Attribute Location"> |
681 | - <field name="attribute_id" /> |
682 | - <field name="sequence" /> |
683 | - <field name="attribute_set_id" /> |
684 | - <field name="attribute_group_id" /> |
685 | - </tree> |
686 | - </field> |
687 | - </record> |
688 | - |
689 | - <record id="product_attribute_tree_view" model="ir.ui.view"> |
690 | - <field name="name">product.attribute.tree</field> |
691 | - <field name="model">product.attribute</field> |
692 | - <field name="arch" type="xml"> |
693 | - <tree string="Product Attribute"> |
694 | - <field name="name" /> |
695 | - <field name="attribute_type" /> |
696 | - </tree> |
697 | - </field> |
698 | - </record> |
699 | - |
700 | - <record id="prio_attribute_option_tree_view" model="ir.ui.view"> |
701 | - <field name="name">attribute.option.tree.prio</field> |
702 | - <field name="model">attribute.option</field> |
703 | - <field eval="1" name="priority"/> |
704 | - <field name="arch" type="xml"> |
705 | - <tree string="Attribute Option"> |
706 | - <field name="value_ref" /> |
707 | - </tree> |
708 | - </field> |
709 | - </record> |
710 | - |
711 | + |
712 | <record id="attribute_option_tree_view" model="ir.ui.view"> |
713 | <field name="name">attribute.option.tree</field> |
714 | <field name="model">attribute.option</field> |
715 | <field eval="20" name="priority"/> |
716 | <field name="arch" type="xml"> |
717 | <tree string="Attribute Option"> |
718 | + <field name="name" /> |
719 | <field name="sequence" /> |
720 | - <field name="value_ref" /> |
721 | + <field name="value_ref" groups="base.group_advanced_attribute"/> |
722 | <field name="attribute_id" /> |
723 | </tree> |
724 | </field> |
725 | </record> |
726 | |
727 | - <record id="view_attribute_set_search" model="ir.ui.view"> |
728 | - <field name="name">attribute.set.list</field> |
729 | - <field name="model">attribute.set</field> |
730 | - <field name="arch" type="xml"> |
731 | - <search string="Search Attribute Sets"> |
732 | - <field name="name"/> |
733 | - </search> |
734 | - </field> |
735 | - </record> |
736 | - |
737 | - <record id="view_attribute_group_search" model="ir.ui.view"> |
738 | - <field name="name">attribute.group.list</field> |
739 | - <field name="model">attribute.group</field> |
740 | - <field name="arch" type="xml"> |
741 | - <search string="Search Attribute Groups"> |
742 | - <field name="name"/> |
743 | - <field name="attribute_set_id"/> |
744 | - </search> |
745 | - </field> |
746 | - </record> |
747 | - |
748 | - <record id="view_attribute_location_search" model="ir.ui.view"> |
749 | - <field name="name">attribute.location.list</field> |
750 | - <field name="model">attribute.location</field> |
751 | - <field name="arch" type="xml"> |
752 | - <search string="Search Attribute Locations"> |
753 | - <field name="name"/> |
754 | - <field name="attribute_set_id"/> |
755 | - <field name="attribute_group_id"/> |
756 | - </search> |
757 | - </field> |
758 | - </record> |
759 | - |
760 | - <record id="view_product_attribute_search" model="ir.ui.view"> |
761 | - <field name="name">product.attribute.list</field> |
762 | - <field name="model">product.attribute</field> |
763 | - <field name="arch" type="xml"> |
764 | - <search string="Search Product Attributes"> |
765 | - <field name="name"/> |
766 | - </search> |
767 | - </field> |
768 | - </record> |
769 | - |
770 | <record id="view_attribute_option_search" model="ir.ui.view"> |
771 | <field name="name">attribute.option.list</field> |
772 | <field name="model">attribute.option</field> |
773 | <field name="arch" type="xml"> |
774 | <search string="Search Attribute Options"> |
775 | - <field name="value_ref" /> |
776 | + <field name="name" /> |
777 | + <field name="value_ref" groups="base.group_advanced_attribute"/> |
778 | <field name="attribute_id"/> |
779 | </search> |
780 | </field> |
781 | </record> |
782 | |
783 | - <record id="attribute_set_form_action" model="ir.actions.act_window"> |
784 | - <field name="name">Attribute Sets</field> |
785 | - <field name="res_model">attribute.set</field> |
786 | - <field name="view_type">form</field> |
787 | - <field name="view_mode">tree,form</field> |
788 | - <field name="search_view_id" ref="view_attribute_set_search"/> |
789 | - <field name="context">{"search_default_user_id":uid}</field> |
790 | - <field name="help"></field> |
791 | - </record> |
792 | - |
793 | - <record id="attribute_group_form_action" model="ir.actions.act_window"> |
794 | - <field name="name">Attribute Groups</field> |
795 | - <field name="res_model">attribute.group</field> |
796 | - <field name="view_type">form</field> |
797 | - <field name="view_mode">tree,form</field> |
798 | - <field name="search_view_id" ref="view_attribute_group_search"/> |
799 | - <field name="context">{"search_default_user_id":uid}</field> |
800 | - <field name="help"></field> |
801 | - </record> |
802 | - |
803 | - <record id="attribute_location_form_action" model="ir.actions.act_window"> |
804 | - <field name="name">Attribute Locations</field> |
805 | - <field name="res_model">attribute.location</field> |
806 | - <field name="view_type">form</field> |
807 | - <field name="view_mode">tree,form</field> |
808 | - <field name="search_view_id" ref="view_attribute_location_search"/> |
809 | - <field name="context">{"search_default_user_id":uid}</field> |
810 | - <field name="help"></field> |
811 | - </record> |
812 | - |
813 | - <record id="product_attribute_form_action" model="ir.actions.act_window"> |
814 | - <field name="name">Product Attributes</field> |
815 | - <field name="res_model">product.attribute</field> |
816 | - <field name="view_type">form</field> |
817 | - <field name="view_mode">tree,form</field> |
818 | - <field name="search_view_id" ref="view_product_attribute_search"/> |
819 | - <field name="context">{"search_default_user_id":uid}</field> |
820 | - <field name="help"></field> |
821 | - </record> |
822 | - |
823 | <record id="attribute_option_form_action" model="ir.actions.act_window"> |
824 | <field name="name">Attribute Options</field> |
825 | <field name="res_model">attribute.option</field> |
826 | @@ -306,21 +249,23 @@ |
827 | <field name="help"></field> |
828 | </record> |
829 | |
830 | - <menuitem |
831 | - action="attribute_set_form_action" id="menu_attribute_set_action" |
832 | - parent="product_custom_attributes.menu_attribute_in_config_product" sequence="1"/> |
833 | - <menuitem |
834 | - action="attribute_group_form_action" id="menu_attribute_group_action" |
835 | - parent="product_custom_attributes.menu_attribute_in_config_product" sequence="2"/> |
836 | - <menuitem |
837 | - action="attribute_location_form_action" id="menu_attribute_location_action" |
838 | - parent="product_custom_attributes.menu_attribute_in_config_product" sequence="3"/> |
839 | - <menuitem |
840 | - action="product_attribute_form_action" id="menu_product_attribute_action" |
841 | - parent="product_custom_attributes.menu_attribute_in_config_product" sequence="4"/> |
842 | - <menuitem |
843 | - action="attribute_option_form_action" id="menu_attribute_option_action" |
844 | - parent="product_custom_attributes.menu_attribute_in_config_product" sequence="5"/> |
845 | + <menuitem |
846 | + action="attribute_option_form_action" id="menu_attribute_option_action" |
847 | + parent="menu_attribute_in_admin" sequence="40"/> |
848 | + |
849 | + <!-- ATTRIBUTE OPTION WIZARD --> |
850 | + <record id="attribute_option_wizard_form_view" model="ir.ui.view"> |
851 | + <field name="name">attribute.option.wizard</field> |
852 | + <field name="model">attribute.option.wizard</field> |
853 | + <field name="arch" type="xml"> |
854 | + <form string="Options Wizard" col="6"> |
855 | + <field name="attribute_id" invisible="1" colspan="2"/> |
856 | + <separator string="options_placeholder"/> |
857 | + <button special="cancel" string="Cancel" icon="gtk-cancel"/> |
858 | + <button name="validate" string="Validate" type="object" icon="gtk-convert"/> |
859 | + </form> |
860 | + </field> |
861 | + </record> |
862 | |
863 | </data> |
864 | </openerp> |
865 | |
866 | === added file 'base_custom_attributes/security/attribute_security.xml' |
867 | --- base_custom_attributes/security/attribute_security.xml 1970-01-01 00:00:00 +0000 |
868 | +++ base_custom_attributes/security/attribute_security.xml 2013-06-18 16:21:29 +0000 |
869 | @@ -0,0 +1,11 @@ |
870 | +<?xml version="1.0" encoding="utf-8"?> |
871 | +<openerp> |
872 | +<data noupdate="0"> |
873 | + |
874 | + <record id="base.group_advanced_attribute" model="res.groups"> |
875 | + <field name="name">Advanced Attribute Option</field> |
876 | + <field name="category_id" ref="base.module_category_hidden"/> |
877 | + </record> |
878 | + |
879 | +</data> |
880 | +</openerp> |
881 | |
882 | === modified file 'base_custom_attributes/security/ir.model.access.csv' |
883 | --- product_custom_attributes/security/ir.model.access.csv 2013-02-11 22:58:10 +0000 |
884 | +++ base_custom_attributes/security/ir.model.access.csv 2013-06-18 16:21:29 +0000 |
885 | @@ -1,16 +1,10 @@ |
886 | "id","name","model_id:id","group_id:id","perm_read","perm_write","perm_create","perm_unlink" |
887 | -"access_product_custom_attributes_attribute_set_salemanager","product_custom_attributes_attribute_set","product_custom_attributes.model_attribute_set","base.group_sale_manager",1,1,1,1 |
888 | -"access_product_custom_attributes_attribute_group_salemanager","product_custom_attributes_attribute_group","product_custom_attributes.model_attribute_group","base.group_sale_manager",1,1,1,1 |
889 | -"access_product_custom_attributes_attribute_location_salemanager","product_custom_attributes_attribute_location","product_custom_attributes.model_attribute_location","base.group_sale_manager",1,1,1,1 |
890 | -"access_product_custom_attributes_product_attribute_salemanager","product_custom_attributes_product_attribute","product_custom_attributes.model_product_attribute","base.group_sale_manager",1,1,1,1 |
891 | -"access_product_custom_attributes_attribute_option_salemanager","product_custom_attributes_attribute_option","product_custom_attributes.model_attribute_option","base.group_sale_manager",1,1,1,1 |
892 | -"access_product_custom_attributes_attribute_set_manager","product_custom_attributes_attribute_set","product_custom_attributes.model_attribute_set","product.group_product_variant",1,1,1,1 |
893 | -"access_product_custom_attributes_attribute_group_manager","product_custom_attributes_attribute_group","product_custom_attributes.model_attribute_group","product.group_product_variant",1,1,1,1 |
894 | -"access_product_custom_attributes_attribute_location_manager","product_custom_attributes_attribute_location","product_custom_attributes.model_attribute_location","product.group_product_variant",1,1,1,1 |
895 | -"access_product_custom_attributes_product_attribute_manager","product_custom_attributes_product_attribute","product_custom_attributes.model_product_attribute","product.group_product_variant",1,1,1,1 |
896 | -"access_product_custom_attributes_attribute_option_manager","product_custom_attributes_attribute_option","product_custom_attributes.model_attribute_option","product.group_product_variant",1,1,1,1 |
897 | -"access_product_custom_attributes_attribute_set_user","product_custom_attributes_attribute_set","product_custom_attributes.model_attribute_set","base.group_user",1,0,0,0 |
898 | -"access_product_custom_attributes_attribute_group_user","product_custom_attributes_attribute_group","product_custom_attributes.model_attribute_group","base.group_user",1,0,0,0 |
899 | -"access_product_custom_attributes_attribute_location_user","product_custom_attributes_attribute_location","product_custom_attributes.model_attribute_location","base.group_user",1,0,0,0 |
900 | -"access_product_custom_attributes_product_attribute_user","product_custom_attributes_product_attribute","product_custom_attributes.model_product_attribute","base.group_user",1,0,0,0 |
901 | -"access_product_custom_attributes_attribute_option_user","product_custom_attributes_attribute_option","product_custom_attributes.model_attribute_option","base.group_user",1,0,0,0 |
902 | +"access_base_custom_attributes_attribute_group_salemanager","base_custom_attributes_attribute_group","base_custom_attributes.model_attribute_group","base.group_sale_manager",1,1,1,1 |
903 | +"access_base_custom_attributes_attribute_attribute_salemanager","base_custom_attributes_product_attribute","base_custom_attributes.model_attribute_attribute","base.group_sale_manager",1,1,1,1 |
904 | +"access_base_custom_attributes_attribute_option_salemanager","base_custom_attributes_attribute_option","base_custom_attributes.model_attribute_option","base.group_sale_manager",1,1,1,1 |
905 | +"access_base_custom_attributes_attribute_group_manager","base_custom_attributes_attribute_group","base_custom_attributes.model_attribute_group","base.group_no_one",1,1,1,1 |
906 | +"access_base_custom_attributes_attribute_attribute_manager","base_custom_attributes_attribute_attribute","base_custom_attributes.model_attribute_attribute","base.group_no_one",1,1,1,1 |
907 | +"access_base_custom_attributes_attribute_option_manager","base_custom_attributes_attribute_option","base_custom_attributes.model_attribute_option","base.group_no_one",1,1,1,1 |
908 | +"access_base_custom_attributes_attribute_group_user","base_custom_attributes_attribute_group","base_custom_attributes.model_attribute_group","base.group_user",1,0,0,0 |
909 | +"access_base_custom_attributes_attribute_attribute_user","base_custom_attributes_attribute_attribute","base_custom_attributes.model_attribute_attribute","base.group_user",1,0,0,0 |
910 | +"access_base_custom_attributes_attribute_option_user","base_custom_attributes_attribute_option","base_custom_attributes.model_attribute_option","base.group_user",1,0,0,0 |
911 | |
912 | === added directory 'product_categ_attributes' |
913 | === added file 'product_categ_attributes/__init__.py' |
914 | --- product_categ_attributes/__init__.py 1970-01-01 00:00:00 +0000 |
915 | +++ product_categ_attributes/__init__.py 2013-06-18 16:21:29 +0000 |
916 | @@ -0,0 +1,1 @@ |
917 | +import product |
918 | |
919 | === added file 'product_categ_attributes/__openerp__.py' |
920 | --- product_categ_attributes/__openerp__.py 1970-01-01 00:00:00 +0000 |
921 | +++ product_categ_attributes/__openerp__.py 2013-06-18 16:21:29 +0000 |
922 | @@ -0,0 +1,42 @@ |
923 | +# -*- encoding: utf-8 -*- |
924 | +############################################################################### |
925 | +# # |
926 | +# product_custom_attributes for OpenERP # |
927 | +# Copyright (C) 2013 Akretion Raphaël Valyi <raphael.valyi@akretion.com> # |
928 | +# # |
929 | +# This program is free software: you can redistribute it and/or modify # |
930 | +# it under the terms of the GNU Affero General Public License as # |
931 | +# published by the Free Software Foundation, either version 3 of the # |
932 | +# License, or (at your option) any later version. # |
933 | +# # |
934 | +# This program is distributed in the hope that it will be useful, # |
935 | +# but WITHOUT ANY WARRANTY; without even the implied warranty of # |
936 | +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # |
937 | +# GNU Affero General Public License for more details. # |
938 | +# # |
939 | +# You should have received a copy of the GNU Affero General Public License # |
940 | +# along with this program. If not, see <http://www.gnu.org/licenses/>. # |
941 | +# # |
942 | +############################################################################### |
943 | + |
944 | + |
945 | + |
946 | +{ |
947 | + 'name': 'product_categ_attributes', |
948 | + 'version': '0.1', |
949 | + 'category': 'Generic Modules/Others', |
950 | + 'license': 'AGPL-3', |
951 | + 'description': """Makes it possible to inherit product attributes from its categories |
952 | + """, |
953 | + 'author': 'Akretion', |
954 | + 'website': 'http://www.akretion.com/', |
955 | + 'depends': ['product_custom_attributes', 'product_m2mcategories'], |
956 | + 'init_xml': [], |
957 | + 'update_xml': [ |
958 | + "product_view.xml" |
959 | + ], |
960 | + 'demo_xml': [], |
961 | + 'installable': True, |
962 | + 'active': False, |
963 | +} |
964 | + |
965 | |
966 | === added file 'product_categ_attributes/product.py' |
967 | --- product_categ_attributes/product.py 1970-01-01 00:00:00 +0000 |
968 | +++ product_categ_attributes/product.py 2013-06-18 16:21:29 +0000 |
969 | @@ -0,0 +1,25 @@ |
970 | +from openerp.osv.orm import Model |
971 | +from openerp.osv import fields |
972 | +from openerp.osv.osv import except_osv |
973 | +from openerp.tools.translate import _ |
974 | + |
975 | + |
976 | +class product_category(Model): |
977 | + _inherit = "product.category" |
978 | + _columns = { |
979 | + 'attribute_group_ids': fields.many2many('attribute.group', 'categ_attr_grp_rel', 'categ_id', 'grp_id', 'Attribute Groups'), |
980 | + } |
981 | + |
982 | + |
983 | +class product_product(Model): |
984 | + _inherit = "product.product" |
985 | + |
986 | + def _attr_grp_ids(self, cr, uid, ids, field_names, arg=None, context=None): |
987 | + res = {} |
988 | + for product in self.browse(cr, uid, ids, context=context): |
989 | + grp_ids = [grp.id for grp in product.categ_id.attribute_group_ids] |
990 | + for categ in product.categ_ids: |
991 | + grp_ids += [grp.id for grp in categ.attribute_group_ids] |
992 | + res[product.id] = list(set(grp_ids)) |
993 | + return res |
994 | + |
995 | |
996 | === added file 'product_categ_attributes/product_view.xml' |
997 | --- product_categ_attributes/product_view.xml 1970-01-01 00:00:00 +0000 |
998 | +++ product_categ_attributes/product_view.xml 2013-06-18 16:21:29 +0000 |
999 | @@ -0,0 +1,52 @@ |
1000 | +<?xml version="1.0" encoding="utf-8"?> |
1001 | + |
1002 | +<openerp> |
1003 | + <data> |
1004 | + |
1005 | + <record model="ir.ui.view" id="product_categ_form_view"> |
1006 | + <field name="name">product_categ_form_view</field> |
1007 | + <field name="model">product.category</field> |
1008 | + <field name="inherit_id" ref="product.product_category_form_view" /> |
1009 | + <field name="arch" type="xml"> |
1010 | + <field name="type" position="after"> |
1011 | + <field name="attribute_group_ids"/> |
1012 | + </field> |
1013 | + </field> |
1014 | + </record> |
1015 | + |
1016 | + <record model="ir.ui.view" id="product_product_form_view_set_button"> |
1017 | + <field name="name">attributes.product.normal.form</field> |
1018 | + <field name="model">product.product</field> |
1019 | + <field name="inherit_id" ref="product_custom_attributes.product_product_form_view_set_button" /> |
1020 | + <field name="arch" type="xml"> |
1021 | + <field name="attribute_set_id" position="replace"> |
1022 | + </field> |
1023 | + <button name="open_attributes" position="replace"> |
1024 | + <button name="open_attributes" string="Open Attributes" type="object" icon="gtk-ok"/> |
1025 | + </button> |
1026 | + </field> |
1027 | + </record> |
1028 | + |
1029 | + <record id="attribute_group_form_view" model="ir.ui.view"> |
1030 | + <field name="name">attribute.group.form</field> |
1031 | + <field name="model">attribute.group</field> |
1032 | + <field name="inherit_id" ref="product_custom_attributes.attribute_group_form_view" /> |
1033 | + <field name="arch" type="xml"> |
1034 | + <field name="attribute_set_id" position="replace"> |
1035 | + </field> |
1036 | + </field> |
1037 | + </record> |
1038 | + |
1039 | + <record id="product_attributes_form_view" model="ir.ui.view"> |
1040 | + <field name="name">product_attributes_form_view</field> |
1041 | + <field name="model">product.product</field> |
1042 | + <field name="inherit_id" ref="product_custom_attributes.product_attributes_form_view" /> |
1043 | + <field name="arch" type="xml"> |
1044 | + <field name="attribute_set_id" position="replace"> |
1045 | + </field> |
1046 | + </field> |
1047 | + </record> |
1048 | + |
1049 | + </data> |
1050 | +</openerp> |
1051 | + |
1052 | |
1053 | === added directory 'product_custom_attributes' |
1054 | === added file 'product_custom_attributes/__init__.py' |
1055 | --- product_custom_attributes/__init__.py 1970-01-01 00:00:00 +0000 |
1056 | +++ product_custom_attributes/__init__.py 2013-06-18 16:21:29 +0000 |
1057 | @@ -0,0 +1,2 @@ |
1058 | +import product |
1059 | +import wizard |
1060 | |
1061 | === added file 'product_custom_attributes/__openerp__.py' |
1062 | --- product_custom_attributes/__openerp__.py 1970-01-01 00:00:00 +0000 |
1063 | +++ product_custom_attributes/__openerp__.py 2013-06-18 16:21:29 +0000 |
1064 | @@ -0,0 +1,47 @@ |
1065 | +# -*- encoding: utf-8 -*- |
1066 | +############################################################################### |
1067 | +# # |
1068 | +# product_custom_attributes for OpenERP # |
1069 | +# Copyright (C) 2011 Akretion Benoît GUILLOT <benoit.guillot@akretion.com> # |
1070 | +# # |
1071 | +# This program is free software: you can redistribute it and/or modify # |
1072 | +# it under the terms of the GNU Affero General Public License as # |
1073 | +# published by the Free Software Foundation, either version 3 of the # |
1074 | +# License, or (at your option) any later version. # |
1075 | +# # |
1076 | +# This program is distributed in the hope that it will be useful, # |
1077 | +# but WITHOUT ANY WARRANTY; without even the implied warranty of # |
1078 | +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # |
1079 | +# GNU Affero General Public License for more details. # |
1080 | +# # |
1081 | +# You should have received a copy of the GNU Affero General Public License # |
1082 | +# along with this program. If not, see <http://www.gnu.org/licenses/>. # |
1083 | +# # |
1084 | +############################################################################### |
1085 | + |
1086 | + |
1087 | + |
1088 | +{ |
1089 | + 'name': 'product_custom_attributes', |
1090 | + 'version': '0.1', |
1091 | + 'category': 'Generic Modules/Others', |
1092 | + 'license': 'AGPL-3', |
1093 | + 'description': """This module adds the possibility to easily create custom fields on products. |
1094 | +Each product can be linked to an attribute set (like camera, fridge...). |
1095 | +Each attribute has custom fields (for example, you don't need the same field for a frigde and a camera). |
1096 | +In particular it's used by the Magento Magentoerpconnect module to match the EAV flexibility of Magento. |
1097 | + """, |
1098 | + 'author': 'Akretion', |
1099 | + 'website': 'http://www.akretion.com/', |
1100 | + 'depends': ['product', 'base_custom_attributes'], |
1101 | + 'init_xml': [], |
1102 | + 'update_xml': [ |
1103 | + 'product_view.xml', |
1104 | + 'custom_attributes_view.xml', |
1105 | + 'wizard/open_product_by_attribute_set.xml', |
1106 | + ], |
1107 | + 'demo_xml': [], |
1108 | + 'installable': True, |
1109 | + 'active': False, |
1110 | +} |
1111 | + |
1112 | |
1113 | === added file 'product_custom_attributes/custom_attributes_view.xml' |
1114 | --- product_custom_attributes/custom_attributes_view.xml 1970-01-01 00:00:00 +0000 |
1115 | +++ product_custom_attributes/custom_attributes_view.xml 2013-06-18 16:21:29 +0000 |
1116 | @@ -0,0 +1,44 @@ |
1117 | +<?xml version="1.0" encoding="utf-8"?> |
1118 | +<!-- |
1119 | + base_custom_attributes for OpenERP |
1120 | + Copyright (C) 2011-2013 Akretion (http://www.akretion.com/) |
1121 | + @author: Benoît GUILLOT <benoit.guillot@akretion.com> |
1122 | + The licence is in the file __openerp__.py |
1123 | +--> |
1124 | + |
1125 | +<openerp> |
1126 | + <data> |
1127 | + |
1128 | + <menuitem |
1129 | + id="menu_attribute_in_config_product" name="Attributes" |
1130 | + parent="product.prod_config_main" sequence="20"/> |
1131 | + |
1132 | + <record id="attribute_set_form_action" model="ir.actions.act_window"> |
1133 | + <field name="name">Product Attribute Sets</field> |
1134 | + <field name="res_model">attribute.set</field> |
1135 | + <field name="view_type">form</field> |
1136 | + <field name="view_mode">tree,form</field> |
1137 | + <field name="search_view_id" ref="base_custom_attributes.view_attribute_set_search"/> |
1138 | + <field name="context">{"force_model": 'product.product'}</field> |
1139 | + <field name="help"></field> |
1140 | + </record> |
1141 | + |
1142 | + <record id="attribute_attribute_form_action" model="ir.actions.act_window"> |
1143 | + <field name="name">Product Attribute</field> |
1144 | + <field name="res_model">attribute.attribute</field> |
1145 | + <field name="view_type">form</field> |
1146 | + <field name="view_mode">tree,form</field> |
1147 | + <field name="search_view_id" ref="base_custom_attributes.view_attribute_attribute_search"/> |
1148 | + <field name="context">{"force_model": 'product.product'}</field> |
1149 | + <field name="help"></field> |
1150 | + </record> |
1151 | + |
1152 | + <menuitem |
1153 | + action="attribute_set_form_action" id="menu_attribute_set_action" |
1154 | + parent="product_custom_attributes.menu_attribute_in_config_product" sequence="1"/> |
1155 | + <menuitem |
1156 | + action="attribute_attribute_form_action" id="menu_attribute_attribute_action" |
1157 | + parent="product_custom_attributes.menu_attribute_in_config_product" sequence="4"/> |
1158 | + |
1159 | + </data> |
1160 | +</openerp> |
1161 | |
1162 | === renamed file 'product_custom_attributes/product.py' => 'product_custom_attributes/product.py' |
1163 | --- product_custom_attributes/product.py 2013-04-22 06:20:25 +0000 |
1164 | +++ product_custom_attributes/product.py 2013-06-18 16:21:29 +0000 |
1165 | @@ -28,7 +28,6 @@ |
1166 | |
1167 | |
1168 | class product_product(Model): |
1169 | - |
1170 | _inherit = "product.product" |
1171 | |
1172 | def _attr_grp_ids(self, cr, uid, ids, field_names, arg=None, context=None): |
1173 | @@ -83,40 +82,6 @@ |
1174 | def save_and_close_product_attributes(self, cr, uid, ids, context=None): |
1175 | return {'type': 'ir.actions.act_window_close'} |
1176 | |
1177 | - def _build_attribute_field(self, cr, uid, page, attribute, context=None): |
1178 | - parent = page |
1179 | - kwargs = {'name': "%s" % attribute.name} |
1180 | - if attribute.ttype == 'many2many': |
1181 | - parent = etree.SubElement(page, 'group', colspan="2", col="4") |
1182 | - #FIXME the following isn't displayed in v7: |
1183 | - sep = etree.SubElement(parent, 'separator', |
1184 | - string="%s" % attribute.field_description, colspan="4") |
1185 | - kwargs['nolabel'] = "1" |
1186 | - if attribute.ttype in ['many2one', 'many2many']: |
1187 | - if attribute.relation_model_id: |
1188 | - if attribute.domain: |
1189 | - kwargs['domain'] = attribute.domain |
1190 | - else: |
1191 | - ids = [op.value_ref.id for op in attribute.option_ids] |
1192 | - kwargs['domain'] = "[('id', 'in', %s)]" % ids |
1193 | - else: |
1194 | - kwargs['domain'] = "[('attribute_id', '=', %s)]" % attribute.attribute_id.id |
1195 | - field = etree.SubElement(parent, 'field', **kwargs) |
1196 | - setup_modifiers(field, self.fields_get(cr, uid, attribute.name, context)) |
1197 | - return parent |
1198 | - |
1199 | - def _build_attributes_notebook(self, cr, uid, attribute_group_ids, context=None): |
1200 | - notebook = etree.Element('notebook', name="attributes_notebook", colspan="4") |
1201 | - toupdate_fields = [] |
1202 | - grp_obj = self.pool.get('attribute.group') |
1203 | - for group in grp_obj.browse(cr, uid, attribute_group_ids, context=context): |
1204 | - page = etree.SubElement(notebook, 'page', string=group.name.capitalize()) |
1205 | - for attribute in group.attribute_ids: |
1206 | - if attribute.name not in toupdate_fields: |
1207 | - toupdate_fields.append(attribute.name) |
1208 | - self._build_attribute_field(cr, uid, page, attribute, context=context) |
1209 | - return notebook, toupdate_fields |
1210 | - |
1211 | def fields_view_get(self, cr, uid, view_id=None, view_type='form', context=None, toolbar=False, submenu=False): |
1212 | if context is None: |
1213 | context = {} |
1214 | @@ -128,7 +93,7 @@ |
1215 | if button: |
1216 | button = button[0] |
1217 | button.getparent().remove(button) |
1218 | - attributes_notebook, toupdate_fields = self._build_attributes_notebook(cr, uid, context['attribute_group_ids'], context=context) |
1219 | + attributes_notebook, toupdate_fields = self.pool.get('attribute.attribute')._build_attributes_notebook(cr, uid, context['attribute_group_ids'], context=context) |
1220 | result['fields'].update(self.fields_get(cr, uid, toupdate_fields, context)) |
1221 | if context.get('open_attributes'): |
1222 | placeholder = eview.xpath("//separator[@string='attributes_placeholder']")[0] |
1223 | |
1224 | === renamed file 'product_custom_attributes/product_view.xml' => 'product_custom_attributes/product_view.xml' |
1225 | === renamed directory 'product_custom_attributes/wizard' => 'product_custom_attributes/wizard' |
When you build a view yourself, you should call osv.orm. setup_modifiers ` on the nodes. (example in wizard. account_ report_ common. account_ common_ report. fields_ view_get` ).
`openerp.
`account.
In your case, I don't think it will change anything, because it setup
the modifiers for `attrs`, `states`, `invisible`, `readonly`, `required`
and you don't use them. But I still think it would be proper to call it.
What do you think?
Nitpickings on the style:
* The indentation of l.170,183,184 is a bit weird.
* l.213,215 spaces around '='