Merge lp:~camptocamp/openerp-product-attributes/6.1-backport-lot-custom-attributes-lep into lp:~product-core-editors/openerp-product-attributes/6.1
- 6.1-backport-lot-custom-attributes-lep
- Merge into 6.1
Status: | Merged |
---|---|
Merged at revision: | 195 |
Proposed branch: | lp:~camptocamp/openerp-product-attributes/6.1-backport-lot-custom-attributes-lep |
Merge into: | lp:~product-core-editors/openerp-product-attributes/6.1 |
Diff against target: |
2143 lines (+2048/-0) 18 files modified
base_custom_attributes/__init__.py (+29/-0) base_custom_attributes/__openerp__.py (+48/-0) base_custom_attributes/custom_attributes.py (+440/-0) base_custom_attributes/custom_attributes_view.xml (+312/-0) base_custom_attributes/i18n/base_custom_attributes.pot (+291/-0) base_custom_attributes/i18n/fr.po (+291/-0) base_custom_attributes/ir_model.py (+39/-0) base_custom_attributes/security/attribute_security.xml (+11/-0) base_custom_attributes/security/ir.model.access.csv (+13/-0) production_lot_custom_attributes/__init__.py (+25/-0) production_lot_custom_attributes/__openerp__.py (+62/-0) production_lot_custom_attributes/custom_attributes_view.xml (+58/-0) production_lot_custom_attributes/lot.py (+207/-0) production_lot_custom_attributes/lot_view.xml (+52/-0) production_lot_custom_attributes/test/lot_attribute_test.yml (+48/-0) production_lot_custom_attributes/wizard/__init__.py (+25/-0) production_lot_custom_attributes/wizard/open_lot_by_attribute_set.py (+67/-0) production_lot_custom_attributes/wizard/open_lot_by_attribute_set.xml (+30/-0) |
To merge this branch: | bzr merge lp:~camptocamp/openerp-product-attributes/6.1-backport-lot-custom-attributes-lep |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Omar (Pexego) | code review, no test | Approve | |
Review via email: mp+196538@code.launchpad.net |
Commit message
[mrg] new modules: base_custom_
Description of the change
This is to backport the modules base_custom_
I added some docstrings and comments that should make creating a new similar module easier.
Warning: in v7.0 the module product_
Thanks to Akretion for the original modules this is based on.
Omar (Pexego) (omar7r) wrote : | # |
- 200. By Leonardo Pistone
-
[imp] production_
lot_custom_ attributes: refactor wizard
Leonardo Pistone (lepistone) wrote : | # |
Thanks Omar.
I improved the code of the wizard in a similar fashion to the corresponding 7.0 branch.
L
- 201. By Leonardo Pistone
-
[fix] typo lenght -> length. yaml test now passes
- 202. By Leonardo Pistone
-
[add] method to search in all serialized fields
- 203. By Leonardo Pistone
-
[FIX] prevent KeyError if no 'attribute_ids' is present in 'vals'
Preview Diff
1 | === added directory 'base_custom_attributes' |
2 | === added file 'base_custom_attributes/__init__.py' |
3 | --- base_custom_attributes/__init__.py 1970-01-01 00:00:00 +0000 |
4 | +++ base_custom_attributes/__init__.py 2013-12-11 14:54:36 +0000 |
5 | @@ -0,0 +1,29 @@ |
6 | +# -*- encoding: utf-8 -*- |
7 | +############################################################################### |
8 | +# # |
9 | +# product_custom_attributes for OpenERP # |
10 | +# Copyright (C) 2011 Akretion Benoît GUILLOT <benoit.guillot@akretion.com> # |
11 | +# # |
12 | +# This program is free software: you can redistribute it and/or modify # |
13 | +# it under the terms of the GNU Affero General Public License as # |
14 | +# published by the Free Software Foundation, either version 3 of the # |
15 | +# License, or (at your option) any later version. # |
16 | +# # |
17 | +# This program is distributed in the hope that it will be useful, # |
18 | +# but WITHOUT ANY WARRANTY; without even the implied warranty of # |
19 | +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # |
20 | +# GNU Affero General Public License for more details. # |
21 | +# # |
22 | +# You should have received a copy of the GNU Affero General Public License # |
23 | +# along with this program. If not, see <http://www.gnu.org/licenses/>. # |
24 | +# # |
25 | +############################################################################### |
26 | + |
27 | + |
28 | + |
29 | +import ir_model |
30 | +import custom_attributes |
31 | + |
32 | + |
33 | + |
34 | + |
35 | |
36 | === added file 'base_custom_attributes/__openerp__.py' |
37 | --- base_custom_attributes/__openerp__.py 1970-01-01 00:00:00 +0000 |
38 | +++ base_custom_attributes/__openerp__.py 2013-12-11 14:54:36 +0000 |
39 | @@ -0,0 +1,48 @@ |
40 | +# -*- encoding: utf-8 -*- |
41 | +############################################################################### |
42 | +# # |
43 | +# base_custom_attributes for OpenERP # |
44 | +# Copyright (C) 2011 Akretion Benoît GUILLOT <benoit.guillot@akretion.com> # |
45 | +# # |
46 | +# This program is free software: you can redistribute it and/or modify # |
47 | +# it under the terms of the GNU Affero General Public License as # |
48 | +# published by the Free Software Foundation, either version 3 of the # |
49 | +# License, or (at your option) any later version. # |
50 | +# # |
51 | +# This program is distributed in the hope that it will be useful, # |
52 | +# but WITHOUT ANY WARRANTY; without even the implied warranty of # |
53 | +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # |
54 | +# GNU Affero General Public License for more details. # |
55 | +# # |
56 | +# You should have received a copy of the GNU Affero General Public License # |
57 | +# along with this program. If not, see <http://www.gnu.org/licenses/>. # |
58 | +# # |
59 | +############################################################################### |
60 | + |
61 | + |
62 | + |
63 | +{ |
64 | + 'name': 'base_custom_attributes', |
65 | + 'version': '0.1', |
66 | + 'category': 'Generic Modules/Others', |
67 | + 'license': 'AGPL-3', |
68 | + 'description': """This module adds the possibility to easily create custom attributes in any OpenERP business object. See the product_custom_attributes module for instance. |
69 | + """, |
70 | + 'author': 'Akretion', |
71 | + 'website': 'http://www.akretion.com/', |
72 | + 'depends': ['base'], |
73 | + 'init_xml': [], |
74 | + 'update_xml': [ |
75 | + 'security/ir.model.access.csv', |
76 | + 'security/attribute_security.xml', |
77 | + 'custom_attributes_view.xml', |
78 | + ], |
79 | + 'demo_xml': [], |
80 | + 'installable': True, |
81 | + 'active': False, |
82 | + 'external_dependencies' : { |
83 | + 'python' : ['unidecode'], |
84 | + } |
85 | + |
86 | +} |
87 | + |
88 | |
89 | === added file 'base_custom_attributes/custom_attributes.py' |
90 | --- base_custom_attributes/custom_attributes.py 1970-01-01 00:00:00 +0000 |
91 | +++ base_custom_attributes/custom_attributes.py 2013-12-11 14:54:36 +0000 |
92 | @@ -0,0 +1,440 @@ |
93 | +# -*- encoding: utf-8 -*- |
94 | +############################################################################### |
95 | +# # |
96 | +# base_attribute.attributes for OpenERP # |
97 | +# Copyright (C) 2011 Akretion Benoît GUILLOT <benoit.guillot@akretion.com> |
98 | +# Copyright (C) 2013 Akretion Raphaël VALYI <raphael.valyi@akretion.com> |
99 | +# # |
100 | +# This program is free software: you can redistribute it and/or modify # |
101 | +# it under the terms of the GNU Affero General Public License as # |
102 | +# published by the Free Software Foundation, either version 3 of the # |
103 | +# License, or (at your option) any later version. # |
104 | +# # |
105 | +# This program is distributed in the hope that it will be useful, # |
106 | +# but WITHOUT ANY WARRANTY; without even the implied warranty of # |
107 | +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # |
108 | +# GNU Affero General Public License for more details. # |
109 | +# # |
110 | +# You should have received a copy of the GNU Affero General Public License # |
111 | +# along with this program. If not, see <http://www.gnu.org/licenses/>. # |
112 | +# # |
113 | +############################################################################### |
114 | + |
115 | +import ast |
116 | +from openerp.osv import orm, fields |
117 | +from openerp.osv.osv import except_osv |
118 | +from openerp.tools.translate import _ |
119 | +from lxml import etree |
120 | +from unidecode import unidecode # Debian package python-unidecode |
121 | +import re |
122 | + |
123 | + |
124 | +def safe_column_name(string): |
125 | + """This function prevent portability problem in database column name |
126 | + with other DBMS system |
127 | + Use case : if you synchronise attributes with other applications """ |
128 | + string = unidecode(string.replace(' ', '_').lower()) |
129 | + return re.sub(r'[^0-9a-z_]','', string) |
130 | + |
131 | + |
132 | +class attribute_option(orm.Model): |
133 | + _name = "attribute.option" |
134 | + _description = "Attribute Option" |
135 | + _order="sequence" |
136 | + |
137 | + def _get_model_list(self, cr, uid, context=None): |
138 | + model_pool = self.pool.get('ir.model') |
139 | + ids = model_pool.search(cr, uid, [], context=context) |
140 | + res = model_pool.read(cr, uid, ids, ['model', 'name'], context=context) |
141 | + return [(r['model'], r['name']) for r in res] |
142 | + |
143 | + _columns = { |
144 | + 'name': fields.char( |
145 | + 'Name', |
146 | + size=128, |
147 | + translate=True, |
148 | + required=True), |
149 | + 'value_ref': fields.reference( |
150 | + 'Reference', |
151 | + selection=_get_model_list, |
152 | + size=128), |
153 | + 'attribute_id': fields.many2one( |
154 | + 'attribute.attribute', |
155 | + 'Product Attribute', |
156 | + required=True), |
157 | + 'sequence': fields.integer('Sequence'), |
158 | + } |
159 | + |
160 | + def name_change(self, cr, uid, ids, name, relation_model_id, context=None): |
161 | + if relation_model_id: |
162 | + warning = {'title': _('Error!'), |
163 | + 'message': _("Use the 'Load Options' button " |
164 | + "instead to select appropriate " |
165 | + "model references'")} |
166 | + return {"value": {"name": False}, "warning": warning} |
167 | + else: |
168 | + return True |
169 | + |
170 | + |
171 | +class attribute_option_wizard(orm.TransientModel): |
172 | + _name = "attribute.option.wizard" |
173 | + _rec_name = 'attribute_id' |
174 | + |
175 | + _columns = { |
176 | + 'attribute_id': fields.many2one( |
177 | + 'attribute.attribute', |
178 | + 'Product Attribute', |
179 | + required=True), |
180 | + } |
181 | + |
182 | + _defaults = { |
183 | + 'attribute_id': lambda self, cr, uid, context: |
184 | + context.get('attribute_id',False) |
185 | + } |
186 | + |
187 | + def validate(self, cr, uid, ids, context=None): |
188 | + return True |
189 | + |
190 | + def create(self, cr, uid, vals, context=None): |
191 | + attr_obj = self.pool.get("attribute.attribute") |
192 | + attr = attr_obj.browse(cr, uid, vals['attribute_id']) |
193 | + op_ids = [op.id for op in attr.option_ids] |
194 | + opt_obj = self.pool.get("attribute.option") |
195 | + opt_obj.unlink(cr, uid, op_ids) |
196 | + for op_id in (vals.get("option_ids") and vals['option_ids'][0][2] or []): |
197 | + model = attr.relation_model_id.model |
198 | + name = self.pool.get(model).name_get(cr, uid, [op_id], context)[0][1] |
199 | + opt_obj.create(cr, uid, { |
200 | + 'attribute_id': vals['attribute_id'], |
201 | + 'name': name, |
202 | + 'value_ref': "%s,%s" % (attr.relation_model_id.model, op_id) |
203 | + }) |
204 | + res = super(attribute_option_wizard, self).create(cr, uid, vals, context) |
205 | + return res |
206 | + |
207 | + def fields_view_get(self, cr, uid, view_id=None, view_type='form', |
208 | + context=None, toolbar=False, submenu=False): |
209 | + res = super(attribute_option_wizard, self).fields_view_get( |
210 | + cr, uid, view_id, view_type, context, toolbar, submenu) |
211 | + if view_type == 'form' and context and context.get("attribute_id"): |
212 | + attr_obj = self.pool.get("attribute.attribute") |
213 | + model_id = attr_obj.read(cr, uid, [context.get("attribute_id")], |
214 | + ['relation_model_id'])[0]['relation_model_id'][0] |
215 | + relation = self.pool.get("ir.model").read(cr, uid, [model_id], |
216 | + ["model"])[0]["model"] |
217 | + res['fields'].update({'option_ids': { |
218 | + 'domain': [], |
219 | + 'string': "Options", |
220 | + 'type': 'many2many', |
221 | + 'relation': relation, |
222 | + 'required': True, |
223 | + } |
224 | + }) |
225 | + eview = etree.fromstring(res['arch']) |
226 | + options = etree.Element('field', name='option_ids', colspan='6') |
227 | + placeholder = eview.xpath("//separator[@string='options_placeholder']")[0] |
228 | + placeholder.getparent().replace(placeholder, options) |
229 | + res['arch'] = etree.tostring(eview, pretty_print=True) |
230 | + return res |
231 | + |
232 | + |
233 | +class attribute_attribute(orm.Model): |
234 | + _name = "attribute.attribute" |
235 | + _description = "Attribute" |
236 | + _inherits = {'ir.model.fields': 'field_id'} |
237 | + |
238 | + def _build_attribute_field(self, cr, uid, page, attribute, context=None): |
239 | + parent = etree.SubElement(page, 'group', colspan="2", col="4") |
240 | + kwargs = {'name': "%s" % attribute.name} |
241 | + if attribute.ttype in ['many2many', 'text']: |
242 | + parent = etree.SubElement(parent, 'group', colspan="2", col="4") |
243 | + etree.SubElement(parent, |
244 | + 'separator', |
245 | + string="%s" % attribute.field_description, |
246 | + colspan="4") |
247 | + kwargs['nolabel'] = "1" |
248 | + if attribute.ttype in ['many2one', 'many2many']: |
249 | + if attribute.relation_model_id: |
250 | + # attribute.domain is a string, it may be an empty list |
251 | + try: |
252 | + domain = ast.literal_eval(attribute.domain) |
253 | + except ValueError: |
254 | + domain = None |
255 | + if domain: |
256 | + kwargs['domain'] = attribute.domain |
257 | + else: |
258 | + ids = [op.value_ref.id for op in attribute.option_ids] |
259 | + kwargs['domain'] = "[('id', 'in', %s)]" % ids |
260 | + else: |
261 | + kwargs['domain'] = "[('attribute_id', '=', %s)]" % attribute.attribute_id.id |
262 | + kwargs['context'] = "{'default_attribute_id': %s}" % attribute.attribute_id.id |
263 | + kwargs['required'] = str(attribute.required or |
264 | + attribute.required_on_views) |
265 | + field = etree.SubElement(parent, 'field', **kwargs) |
266 | + orm.setup_modifiers(field, self.fields_get(cr, uid, attribute.name, |
267 | + context)) |
268 | + return parent |
269 | + |
270 | + def _build_attributes_notebook(self, cr, uid, attribute_group_ids, |
271 | + context=None): |
272 | + notebook = etree.Element('notebook', name="attributes_notebook", |
273 | + colspan="4") |
274 | + toupdate_fields = [] |
275 | + grp_obj = self.pool.get('attribute.group') |
276 | + for group in grp_obj.browse(cr, uid, attribute_group_ids, |
277 | + context=context): |
278 | + page = etree.SubElement(notebook, 'page', |
279 | + string=group.name.capitalize()) |
280 | + for attribute in group.attribute_ids: |
281 | + if attribute.name not in toupdate_fields: |
282 | + toupdate_fields.append(attribute.name) |
283 | + self._build_attribute_field(cr, uid, page, attribute, |
284 | + context=context) |
285 | + return notebook, toupdate_fields |
286 | + |
287 | + def relation_model_id_change(self, cr, uid, ids, relation_model_id, |
288 | + option_ids, context=None): |
289 | + "removed selected options as they would be inconsistent" |
290 | + return {'value': {'option_ids': [(2, i[1]) for i in option_ids]}} |
291 | + |
292 | + def button_add_options(self, cr, uid, ids, context=None): |
293 | + return { |
294 | + 'context': "{'attribute_id': %s}" % (ids[0]), |
295 | + 'name': _('Options Wizard'), |
296 | + 'view_type': 'form', |
297 | + 'view_mode': 'form', |
298 | + 'res_model': 'attribute.option.wizard', |
299 | + 'type': 'ir.actions.act_window', |
300 | + 'target': 'new', |
301 | + } |
302 | + |
303 | + _columns = { |
304 | + 'field_id': fields.many2one( |
305 | + 'ir.model.fields', |
306 | + 'Ir Model Fields', |
307 | + required=True, |
308 | + ondelete="cascade"), |
309 | + 'attribute_type': fields.selection([ |
310 | + ('char', 'Char'), |
311 | + ('text', 'Text'), |
312 | + ('select', 'Select'), |
313 | + ('multiselect', 'Multiselect'), |
314 | + ('boolean', 'Boolean'), |
315 | + ('integer', 'Integer'), |
316 | + ('date', 'Date'), |
317 | + ('datetime', 'Datetime'), |
318 | + ('binary', 'Binary'), |
319 | + ('float', 'Float')], |
320 | + 'Type', required=True), |
321 | + 'serialized': fields.boolean( |
322 | + 'Field serialized', |
323 | + help="If serialized, the field will be stocked in the serialized " |
324 | + "field: attribute_custom_tmpl or attribute_custom_variant " |
325 | + "depending on the field based_on"), |
326 | + 'option_ids': fields.one2many( |
327 | + 'attribute.option', |
328 | + 'attribute_id', |
329 | + 'Attribute Options'), |
330 | + 'create_date': fields.datetime('Created date', readonly=True), |
331 | + 'relation_model_id': fields.many2one( |
332 | + 'ir.model', |
333 | + 'Model'), |
334 | + 'required_on_views': fields.boolean( |
335 | + 'Required (on views)', |
336 | + help="If activated, the attribute will be mandatory on the views, " |
337 | + "but not in the database"), |
338 | + } |
339 | + |
340 | + def create(self, cr, uid, vals, context=None): |
341 | + if vals.get('relation_model_id'): |
342 | + relation = self.pool.get('ir.model').read( |
343 | + cr, uid, [vals.get('relation_model_id')], ['model'])[0]['model'] |
344 | + else: |
345 | + relation = 'attribute.option' |
346 | + if vals['attribute_type'] == 'select': |
347 | + vals['ttype'] = 'many2one' |
348 | + vals['relation'] = relation |
349 | + elif vals['attribute_type'] == 'multiselect': |
350 | + vals['ttype'] = 'many2many' |
351 | + vals['relation'] = relation |
352 | + vals['serialized'] = True |
353 | + else: |
354 | + vals['ttype'] = vals['attribute_type'] |
355 | + |
356 | + if vals.get('serialized'): |
357 | + field_obj = self.pool.get('ir.model.fields') |
358 | + serialized_ids = field_obj.search(cr, uid, [ |
359 | + ('ttype', '=', 'serialized'), |
360 | + ('model_id', '=', vals['model_id']), |
361 | + ('name', '=', 'x_custom_json_attrs')], |
362 | + context=context) |
363 | + if serialized_ids: |
364 | + vals['serialization_field_id'] = serialized_ids[0] |
365 | + else: |
366 | + f_vals = { |
367 | + 'name': u'x_custom_json_attrs', |
368 | + 'field_description': u'Serialized JSON Attributes', |
369 | + 'ttype': 'serialized', |
370 | + 'model_id': vals['model_id'], |
371 | + } |
372 | + vals['serialization_field_id'] = field_obj.create( |
373 | + cr, uid, f_vals, {'manual': True}) |
374 | + vals['state'] = 'manual' |
375 | + return super(attribute_attribute, self).create(cr, uid, vals, context) |
376 | + |
377 | + def onchange_field_description(self, cr, uid, ids, field_description, |
378 | + name, create_date, context=None): |
379 | + name = name or u'x_' |
380 | + if field_description and not create_date: |
381 | + name = unicode('x_' + safe_column_name(field_description)) |
382 | + return {'value': {'name': name}} |
383 | + |
384 | + def onchange_name(self, cr, uid, ids, name, context=None): |
385 | + res = {} |
386 | + if not name.startswith('x_'): |
387 | + name = u'x_%s' % name |
388 | + else: |
389 | + name = u'%s' % name |
390 | + res = {'value': {'name': unidecode(name)}} |
391 | + |
392 | + #FILTER ON MODEL |
393 | + model_name = context.get('force_model') |
394 | + if not model_name: |
395 | + model_id = context.get('default_model_id') |
396 | + if model_id: |
397 | + model = self.pool['ir.model'].browse(cr, uid, model_id, |
398 | + context=context) |
399 | + model_name = model.model |
400 | + if model_name: |
401 | + model_obj = self.pool[model_name] |
402 | + allowed_model = [x for x in model_obj._inherits] + [model_name] |
403 | + res['domain'] = {'model_id': [['model', 'in', allowed_model]]} |
404 | + |
405 | + return res |
406 | + |
407 | + def _get_default_model(self, cr, uid, context=None): |
408 | + if context and context.get('force_model'): |
409 | + model_id = self.pool['ir.model'].search(cr, uid, [ |
410 | + ('model', '=', context['force_model']) |
411 | + ], context=context) |
412 | + if model_id: |
413 | + return model_id[0] |
414 | + return None |
415 | + |
416 | + _defaults = { |
417 | + 'model_id': _get_default_model |
418 | + } |
419 | + |
420 | + |
421 | +class attribute_group(orm.Model): |
422 | + _name = "attribute.group" |
423 | + _description = "Attribute Group" |
424 | + _order ="sequence" |
425 | + |
426 | + _columns = { |
427 | + 'name': fields.char( |
428 | + 'Name', |
429 | + size=128, |
430 | + required=True, |
431 | + translate=True), |
432 | + 'sequence': fields.integer('Sequence'), |
433 | + 'attribute_set_id': fields.many2one( |
434 | + 'attribute.set', |
435 | + 'Attribute Set'), |
436 | + 'attribute_ids': fields.one2many( |
437 | + 'attribute.location', |
438 | + 'attribute_group_id', |
439 | + 'Attributes'), |
440 | + 'model_id': fields.many2one( |
441 | + 'ir.model', |
442 | + 'Model', |
443 | + required=True), |
444 | + } |
445 | + |
446 | + def create(self, cr, uid, vals, context=None): |
447 | + for attribute in vals.get('attribute_ids', []): |
448 | + if (vals.get('attribute_set_id') and attribute[2] and |
449 | + not attribute[2].get('attribute_set_id')): |
450 | + attribute[2]['attribute_set_id'] = vals['attribute_set_id'] |
451 | + return super(attribute_group, self).create(cr, uid, vals, context) |
452 | + |
453 | + def _get_default_model(self, cr, uid, context=None): |
454 | + if context and context.get('force_model'): |
455 | + model_id = self.pool['ir.model'].search( |
456 | + cr, uid, [['model', '=', context['force_model']]], |
457 | + context=context) |
458 | + if model_id: |
459 | + return model_id[0] |
460 | + return None |
461 | + |
462 | + _defaults = { |
463 | + 'model_id': _get_default_model |
464 | + } |
465 | + |
466 | + |
467 | +class attribute_set(orm.Model): |
468 | + _name = "attribute.set" |
469 | + _description = "Attribute Set" |
470 | + _columns = { |
471 | + 'name': fields.char( |
472 | + 'Name', |
473 | + size=128, |
474 | + required=True, |
475 | + translate=True), |
476 | + 'attribute_group_ids': fields.one2many( |
477 | + 'attribute.group', |
478 | + 'attribute_set_id', |
479 | + 'Attribute Groups'), |
480 | + 'model_id': fields.many2one( |
481 | + 'ir.model', |
482 | + 'Model', |
483 | + required=True), |
484 | + } |
485 | + |
486 | + def _get_default_model(self, cr, uid, context=None): |
487 | + if context and context.get('force_model'): |
488 | + model_id = self.pool['ir.model'].search( |
489 | + cr, uid, [['model', '=', context['force_model']]], |
490 | + context=context) |
491 | + if model_id: |
492 | + return model_id[0] |
493 | + return None |
494 | + |
495 | + _defaults = { |
496 | + 'model_id': _get_default_model |
497 | + } |
498 | + |
499 | + |
500 | +class attribute_location(orm.Model): |
501 | + _name = "attribute.location" |
502 | + _description = "Attribute Location" |
503 | + _order="sequence" |
504 | + _inherits = {'attribute.attribute': 'attribute_id'} |
505 | + |
506 | + def _get_attribute_loc_from_group(self, cr, uid, ids, context=None): |
507 | + return self.pool.get('attribute.location').search( |
508 | + cr, uid, [('attribute_group_id', 'in', ids)], context=context) |
509 | + |
510 | + _columns = { |
511 | + 'attribute_id': fields.many2one( |
512 | + 'attribute.attribute', |
513 | + 'Product Attribute', |
514 | + required=True, |
515 | + ondelete="cascade"), |
516 | + 'attribute_set_id': fields.related( |
517 | + 'attribute_group_id', |
518 | + 'attribute_set_id', |
519 | + type='many2one', |
520 | + relation='attribute.set', |
521 | + string='Attribute Set', |
522 | + readonly=True, |
523 | + store={ |
524 | + 'attribute.group': (_get_attribute_loc_from_group, |
525 | + ['attribute_set_id'], 10), |
526 | + }), |
527 | + 'attribute_group_id': fields.many2one( |
528 | + 'attribute.group', |
529 | + 'Attribute Group', |
530 | + required=True), |
531 | + 'sequence': fields.integer('Sequence'), |
532 | + } |
533 | |
534 | === added file 'base_custom_attributes/custom_attributes_view.xml' |
535 | --- base_custom_attributes/custom_attributes_view.xml 1970-01-01 00:00:00 +0000 |
536 | +++ base_custom_attributes/custom_attributes_view.xml 2013-12-11 14:54:36 +0000 |
537 | @@ -0,0 +1,312 @@ |
538 | +<?xml version="1.0" encoding="utf-8"?> |
539 | +<!-- |
540 | + base_custom_attributes for OpenERP |
541 | + Copyright (C) 2011-2013 Akretion (http://www.akretion.com/) |
542 | + @author: Benoît GUILLOT <benoit.guillot@akretion.com> |
543 | + The licence is in the file __openerp__.py |
544 | +--> |
545 | + |
546 | +<openerp> |
547 | + <data> |
548 | + |
549 | + <menuitem |
550 | + id="menu_attribute_in_admin" name="Attributes" |
551 | + parent="base.next_id_9" sequence="1"/> |
552 | + |
553 | + <!-- ATTRIBUTE SET VIEW --> |
554 | + |
555 | + <record id="attribute_set_form_view" model="ir.ui.view"> |
556 | + <field name="name">attribute.set.form</field> |
557 | + <field name="model">attribute.set</field> |
558 | + <field name="type">form</field> |
559 | + <field name="arch" type="xml"> |
560 | + <form string="Attribute Set"> |
561 | + <field name="name"/> |
562 | + <field name="model_id" invisible="context.get('force_model')"/> |
563 | + <field name="attribute_group_ids" colspan="4" |
564 | + context="{'default_model_id': model_id, 'from_attribute_set':True}"> |
565 | + </field> |
566 | + </form> |
567 | + </field> |
568 | + </record> |
569 | + |
570 | + <record id="attribute_set_tree_view" model="ir.ui.view"> |
571 | + <field name="name">attribute.set.tree</field> |
572 | + <field name="model">attribute.set</field> |
573 | + <field name="type">tree</field> |
574 | + <field name="arch" type="xml"> |
575 | + <tree string="Attribute Set" > |
576 | + <field name="name" /> |
577 | + <field name="model_id" /> |
578 | + </tree> |
579 | + </field> |
580 | + </record> |
581 | + |
582 | + <record id="view_attribute_set_search" model="ir.ui.view"> |
583 | + <field name="name">attribute.set.list</field> |
584 | + <field name="model">attribute.set</field> |
585 | + <field name="type">search</field> |
586 | + <field name="arch" type="xml"> |
587 | + <search string="Search Attribute Sets"> |
588 | + <field name="name"/> |
589 | + <field name="model_id" /> |
590 | + </search> |
591 | + </field> |
592 | + </record> |
593 | + |
594 | + <record id="attribute_set_form_action" model="ir.actions.act_window"> |
595 | + <field name="name">Attribute Sets</field> |
596 | + <field name="res_model">attribute.set</field> |
597 | + <field name="view_type">form</field> |
598 | + <field name="view_mode">tree,form</field> |
599 | + <field name="search_view_id" ref="view_attribute_set_search"/> |
600 | + <field name="context">{"search_default_user_id":uid}</field> |
601 | + <field name="help"></field> |
602 | + </record> |
603 | + |
604 | + <menuitem |
605 | + action="attribute_set_form_action" id="menu_attribute_set_action" |
606 | + parent="menu_attribute_in_admin" sequence="10"/> |
607 | + |
608 | + |
609 | + |
610 | + <!-- ATTRIBUTE GROUP VIEW --> |
611 | + |
612 | + <record id="attribute_group_form_view" model="ir.ui.view"> |
613 | + <field name="name">attribute.group.form</field> |
614 | + <field name="model">attribute.group</field> |
615 | + <field name="type">form</field> |
616 | + <field name="arch" type="xml"> |
617 | + <form string="Attribute Group"> |
618 | + <field name="name" /> |
619 | + <field name="sequence" /> |
620 | + <field name="model_id" invisible="context.get('from_attribute_set') or context.get('force_model')"/> |
621 | + <field name="attribute_set_id" invisible="context.get('from_attribute_set')"/> |
622 | + <field name="attribute_ids" colspan="4" nolabel="1"> |
623 | + <form string="Attribute Location"> |
624 | + <field name="attribute_id" context="{'default_model_id': parent.model_id}"/> |
625 | + <field name="sequence" /> |
626 | + </form> |
627 | + <tree string="Attribute Location" editable="top"> |
628 | + <field name="attribute_id" context="{'default_model_id': parent.model_id}"/> |
629 | + <field name="sequence" /> |
630 | + </tree> |
631 | + </field> |
632 | + </form> |
633 | + </field> |
634 | + </record> |
635 | + |
636 | + <record id="attribute_group_tree_view" model="ir.ui.view"> |
637 | + <field name="name">attribute.group.tree</field> |
638 | + <field name="model">attribute.group</field> |
639 | + <field name="type">tree</field> |
640 | + <field name="arch" type="xml"> |
641 | + <tree string="Attribute Group"> |
642 | + <field name="name" /> |
643 | + <field name="sequence" /> |
644 | + <field name="attribute_set_id" invisible="context.get('from_attribute_set')"/> |
645 | + <field name="model_id" invisible="context.get('from_attribute_set')"/> |
646 | + </tree> |
647 | + </field> |
648 | + </record> |
649 | + |
650 | + <record id="view_attribute_group_search" model="ir.ui.view"> |
651 | + <field name="name">attribute.group.list</field> |
652 | + <field name="model">attribute.group</field> |
653 | + <field name="type">search</field> |
654 | + <field name="arch" type="xml"> |
655 | + <search string="Search Attribute Groups"> |
656 | + <field name="name"/> |
657 | + <field name="attribute_set_id"/> |
658 | + <field name="model_id" /> |
659 | + </search> |
660 | + </field> |
661 | + </record> |
662 | + |
663 | + |
664 | + <record id="attribute_group_form_action" model="ir.actions.act_window"> |
665 | + <field name="name">Attribute Groups</field> |
666 | + <field name="res_model">attribute.group</field> |
667 | + <field name="view_type">form</field> |
668 | + <field name="view_mode">tree,form</field> |
669 | + <field name="context">{"search_default_user_id":uid}</field> |
670 | + <field name="help"></field> |
671 | + </record> |
672 | + |
673 | + <menuitem |
674 | + action="attribute_group_form_action" id="menu_attribute_group_action" |
675 | + parent="menu_attribute_in_admin" sequence="20"/> |
676 | + |
677 | + <!-- ATTRIBUTE VIEW --> |
678 | + |
679 | + <record id="attribute_attribute_form_view" model="ir.ui.view"> |
680 | + <field name="name">attribute.attribute.form</field> |
681 | + <field name="model">attribute.attribute</field> |
682 | + <field name="type">form</field> |
683 | + <field name="arch" type="xml"> |
684 | + <form string="Attribute"> |
685 | + <field name="field_description" on_change="onchange_field_description(field_description, name, create_date, context)"/> |
686 | + <field name="name" attrs="{'readonly':[('create_date', '!=', False)]}" on_change="onchange_name(name, context)"/> |
687 | + <field name="attribute_type" /> |
688 | + <field name="model_id" /> |
689 | + <field name="serialized" attrs="{'invisible':[('attribute_type', '=', 'multiselect')]}"/> |
690 | + <field name="size" attrs="{'invisible':[('attribute_type', '!=', 'char')]}"/> |
691 | + <field name="required_on_views"/> |
692 | + <field name="translate" attrs="{'invisible':[('attribute_type', 'not in', ('char', 'text'))]}"/> |
693 | + <newline /> |
694 | + <group colspan="4" attrs="{'invisible':[('attribute_type', 'not in', ['select', 'multiselect'])]}"> |
695 | + <group groups="base.group_advanced_attribute"> |
696 | + <field name="relation_model_id" on_change="relation_model_id_change(relation_model_id, option_ids, context)"/> |
697 | + <field name="domain" attrs="{'invisible':[('relation_model_id', '=', False)]}"/> |
698 | + <button name="button_add_options" attrs="{'invisible':[('relation_model_id', '=', False), ('domain', '!=', False)]}" type="object" string="Load Options"/> |
699 | + </group> |
700 | + <field name="option_ids" colspan="4" nolabel="1"> |
701 | + <tree string="Attribute Options" editable="top"> |
702 | + <field name="sequence" invisible="1"/> |
703 | + <field name="name" on_change="name_change(name, parent.relation_model_id, context)"/> |
704 | + </tree> |
705 | + </field> |
706 | + </group> |
707 | + <field name="create_date" invisible="1"/> |
708 | + </form> |
709 | + </field> |
710 | + </record> |
711 | + |
712 | + <record id="attribute_attribute_tree_view" model="ir.ui.view"> |
713 | + <field name="name">attribute.attribute.tree</field> |
714 | + <field name="model">attribute.attribute</field> |
715 | + <field name="type">tree</field> |
716 | + <field name="arch" type="xml"> |
717 | + <tree string="Attribute"> |
718 | + <field name="name" /> |
719 | + <field name="attribute_type" /> |
720 | + </tree> |
721 | + </field> |
722 | + </record> |
723 | + |
724 | + <record id="view_attribute_attribute_search" model="ir.ui.view"> |
725 | + <field name="name">attribute.attribute.list</field> |
726 | + <field name="model">attribute.attribute</field> |
727 | + <field name="type">search</field> |
728 | + <field name="arch" type="xml"> |
729 | + <search string="Search Attributes"> |
730 | + <field name="name"/> |
731 | + </search> |
732 | + </field> |
733 | + </record> |
734 | + |
735 | + <record id="attribute_attribute_form_action" model="ir.actions.act_window"> |
736 | + <field name="name">Attributes</field> |
737 | + <field name="res_model">attribute.attribute</field> |
738 | + <field name="view_type">form</field> |
739 | + <field name="view_mode">tree,form</field> |
740 | + <field name="search_view_id" ref="view_attribute_attribute_search"/> |
741 | + <field name="context">{"search_default_user_id":uid}</field> |
742 | + <field name="help"></field> |
743 | + </record> |
744 | + <menuitem |
745 | + action="attribute_attribute_form_action" id="menu_attribute_attribute_action" |
746 | + parent="menu_attribute_in_admin" sequence="30"/> |
747 | + |
748 | + <!-- ATTRIBUTE OPTION VIEW --> |
749 | + <record id="attribute_option_form_popup_view" model="ir.ui.view"> |
750 | + <field name="name">attribute.option.form.popup</field> |
751 | + <field name="model">attribute.option</field> |
752 | + <field name="priority" eval="6"/> |
753 | + <field name="type">form</field> |
754 | + <field name="arch" type="xml"> |
755 | + <form string="Attribute Option"> |
756 | + <field name="name" colspan="2"/> |
757 | + <field name="value_ref" colspan="2" groups="base.group_advanced_attribute"/> |
758 | + <field name="sequence" colspan="2"/> |
759 | + </form> |
760 | + </field> |
761 | + </record> |
762 | + |
763 | + <record id="attribute_option_form_view" model="ir.ui.view"> |
764 | + <field name="name">attribute.option.form</field> |
765 | + <field name="model">attribute.option</field> |
766 | + <field name="type">form</field> |
767 | + <field name="arch" type="xml"> |
768 | + <form string="Attribute Option"> |
769 | + <field name="name" colspan="2"/> |
770 | + <field name="value_ref" colspan="2" groups="base.group_advanced_attribute"/> |
771 | + <field name="sequence" colspan="2"/> |
772 | + <field name="attribute_id" colspan="2"/> |
773 | + </form> |
774 | + </field> |
775 | + </record> |
776 | + |
777 | + <record id="attribute_option_tree_view" model="ir.ui.view"> |
778 | + <field name="name">attribute.option.tree</field> |
779 | + <field name="model">attribute.option</field> |
780 | + <field eval="20" name="priority"/> |
781 | + <field name="type">tree</field> |
782 | + <field name="arch" type="xml"> |
783 | + <tree string="Attribute Option"> |
784 | + <field name="name" /> |
785 | + <field name="sequence" /> |
786 | + <field name="value_ref" groups="base.group_advanced_attribute"/> |
787 | + <field name="attribute_id" /> |
788 | + </tree> |
789 | + </field> |
790 | + </record> |
791 | + |
792 | + <record id="view_attribute_option_search" model="ir.ui.view"> |
793 | + <field name="name">attribute.option.list</field> |
794 | + <field name="model">attribute.option</field> |
795 | + <field name="type">search</field> |
796 | + <field name="arch" type="xml"> |
797 | + <search string="Search Attribute Options"> |
798 | + <field name="name" /> |
799 | + <field name="attribute_id"/> |
800 | + </search> |
801 | + </field> |
802 | + </record> |
803 | + |
804 | + <record id="attribute_option_form_action" model="ir.actions.act_window"> |
805 | + <field name="name">Attribute Options</field> |
806 | + <field name="res_model">attribute.option</field> |
807 | + <field name="view_type">form</field> |
808 | + <field name="view_mode">tree,form</field> |
809 | + <field name="view_id" ref="attribute_option_tree_view"/> |
810 | + <field name="search_view_id" ref="view_attribute_option_search"/> |
811 | + <field name="context">{"search_default_user_id":uid}</field> |
812 | + <field name="help"></field> |
813 | + </record> |
814 | + |
815 | + <record id="attribute_option_form_action_tree" model="ir.actions.act_window.view"> |
816 | + <field name="sequence" eval="1"/> |
817 | + <field name="act_window_id" ref="attribute_option_form_action"/> |
818 | + <field name="view_id" ref="attribute_option_tree_view"/> |
819 | + <field name="view_mode">tree</field> |
820 | + </record> |
821 | + |
822 | + <record id="attribute_option_form_action_form" model="ir.actions.act_window.view"> |
823 | + <field name="sequence" eval="2"/> |
824 | + <field name="act_window_id" ref="attribute_option_form_action"/> |
825 | + <field name="view_id" ref="attribute_option_form_view"/> |
826 | + <field name="view_mode">form</field> |
827 | + </record> |
828 | + |
829 | + <menuitem |
830 | + action="attribute_option_form_action" id="menu_attribute_option_action" |
831 | + parent="menu_attribute_in_admin" sequence="40"/> |
832 | + |
833 | + <!-- ATTRIBUTE OPTION WIZARD --> |
834 | + <record id="attribute_option_wizard_form_view" model="ir.ui.view"> |
835 | + <field name="name">attribute.option.wizard</field> |
836 | + <field name="model">attribute.option.wizard</field> |
837 | + <field name="type">form</field> |
838 | + <field name="arch" type="xml"> |
839 | + <form string="Options Wizard" col="6"> |
840 | + <field name="attribute_id" invisible="1" colspan="2"/> |
841 | + <separator string="options_placeholder"/> |
842 | + <button special="cancel" string="Cancel" icon="gtk-cancel"/> |
843 | + <button name="validate" string="Validate" type="object" icon="gtk-convert"/> |
844 | + </form> |
845 | + </field> |
846 | + </record> |
847 | + |
848 | + </data> |
849 | +</openerp> |
850 | |
851 | === added directory 'base_custom_attributes/i18n' |
852 | === added file 'base_custom_attributes/i18n/base_custom_attributes.pot' |
853 | --- base_custom_attributes/i18n/base_custom_attributes.pot 1970-01-01 00:00:00 +0000 |
854 | +++ base_custom_attributes/i18n/base_custom_attributes.pot 2013-12-11 14:54:36 +0000 |
855 | @@ -0,0 +1,291 @@ |
856 | +# Translation of OpenERP Server. |
857 | +# This file contains the translation of the following modules: |
858 | +# * base_custom_attributes |
859 | +# |
860 | +msgid "" |
861 | +msgstr "" |
862 | +"Project-Id-Version: OpenERP Server 7.0\n" |
863 | +"Report-Msgid-Bugs-To: \n" |
864 | +"POT-Creation-Date: 2013-10-16 10:39+0000\n" |
865 | +"PO-Revision-Date: 2013-10-16 10:39+0000\n" |
866 | +"Last-Translator: <>\n" |
867 | +"Language-Team: \n" |
868 | +"MIME-Version: 1.0\n" |
869 | +"Content-Type: text/plain; charset=UTF-8\n" |
870 | +"Content-Transfer-Encoding: \n" |
871 | +"Plural-Forms: \n" |
872 | + |
873 | +#. module: base_custom_attributes |
874 | +#: code:addons/base_custom_attributes/custom_attributes.py:44 |
875 | +#, python-format |
876 | +msgid "Use the 'Load Options' button instead to select appropriate model references." |
877 | +msgstr "" |
878 | + |
879 | +#. module: base_custom_attributes |
880 | +#: selection:attribute.attribute,attribute_type:0 |
881 | +msgid "Binary" |
882 | +msgstr "" |
883 | + |
884 | +#. module: base_custom_attributes |
885 | +#: view:attribute.attribute:0 |
886 | +msgid "Search Attributes" |
887 | +msgstr "" |
888 | + |
889 | +#. module: base_custom_attributes |
890 | +#: view:attribute.group:0 |
891 | +#: field:attribute.location,attribute_group_id:0 |
892 | +#: model:ir.model,name:base_custom_attributes.model_attribute_group |
893 | +#: model:ir.model.fields,field_description:base_custom_attributes.field_attribute_location_attribute_group_id |
894 | +msgid "Attribute Group" |
895 | +msgstr "" |
896 | + |
897 | +#. module: base_custom_attributes |
898 | +#: view:attribute.group:0 |
899 | +#: model:ir.model,name:base_custom_attributes.model_attribute_location |
900 | +msgid "Attribute Location" |
901 | +msgstr "" |
902 | + |
903 | +#. module: base_custom_attributes |
904 | +#: code:addons/base_custom_attributes/custom_attributes.py:154 |
905 | +#: view:attribute.option.wizard:0 |
906 | +#, python-format |
907 | +msgid "Options Wizard" |
908 | +msgstr "" |
909 | + |
910 | +#. module: base_custom_attributes |
911 | +#: view:attribute.group:0 |
912 | +msgid "Search Attribute Groups" |
913 | +msgstr "" |
914 | + |
915 | +#. module: base_custom_attributes |
916 | +#: field:attribute.attribute,attribute_type:0 |
917 | +#: model:ir.model.fields,field_description:base_custom_attributes.field_attribute_attribute_attribute_type |
918 | +msgid "Type" |
919 | +msgstr "" |
920 | + |
921 | +#. module: base_custom_attributes |
922 | +#: field:attribute.set,attribute_group_ids:0 |
923 | +#: model:ir.actions.act_window,name:base_custom_attributes.attribute_group_form_action |
924 | +#: model:ir.model.fields,field_description:base_custom_attributes.field_attribute_set_attribute_group_ids |
925 | +#: model:ir.ui.menu,name:base_custom_attributes.menu_attribute_group_action |
926 | +msgid "Attribute Groups" |
927 | +msgstr "" |
928 | + |
929 | +#. module: base_custom_attributes |
930 | +#: field:attribute.attribute,create_date:0 |
931 | +#: model:ir.model.fields,field_description:base_custom_attributes.field_attribute_attribute_create_date |
932 | +msgid "Created date" |
933 | +msgstr "" |
934 | + |
935 | +#. module: base_custom_attributes |
936 | +#: view:attribute.set:0 |
937 | +msgid "Search Attribute Sets" |
938 | +msgstr "" |
939 | + |
940 | +#. module: base_custom_attributes |
941 | +#: view:attribute.option:0 |
942 | +#: model:ir.model,name:base_custom_attributes.model_attribute_option |
943 | +msgid "Attribute Option" |
944 | +msgstr "" |
945 | + |
946 | +#. module: base_custom_attributes |
947 | +#: selection:attribute.attribute,attribute_type:0 |
948 | +msgid "Date" |
949 | +msgstr "" |
950 | + |
951 | +#. module: base_custom_attributes |
952 | +#: help:attribute.attribute,required_on_views:0 |
953 | +msgid "If activated, the attribute will be mandatory on the views, but not in the database" |
954 | +msgstr "" |
955 | + |
956 | +#. module: base_custom_attributes |
957 | +#: field:attribute.attribute,field_id:0 |
958 | +#: model:ir.model.fields,field_description:base_custom_attributes.field_attribute_attribute_field_id |
959 | +msgid "Ir Model Fields" |
960 | +msgstr "" |
961 | + |
962 | +#. module: base_custom_attributes |
963 | +#: view:attribute.option.wizard:0 |
964 | +msgid "options_placeholder" |
965 | +msgstr "" |
966 | + |
967 | +#. module: base_custom_attributes |
968 | +#: field:attribute.group,name:0 |
969 | +#: field:attribute.option,name:0 |
970 | +#: field:attribute.set,name:0 |
971 | +#: model:ir.model.fields,field_description:base_custom_attributes.field_attribute_group_name |
972 | +#: model:ir.model.fields,field_description:base_custom_attributes.field_attribute_option_name |
973 | +#: model:ir.model.fields,field_description:base_custom_attributes.field_attribute_set_name |
974 | +msgid "Name" |
975 | +msgstr "" |
976 | + |
977 | +#. module: base_custom_attributes |
978 | +#: help:attribute.attribute,serialized:0 |
979 | +msgid "If serialized, the field will be stocked in the serialized field: attribute_custom_tmpl or attribute_custom_variant depending on the field based_on" |
980 | +msgstr "" |
981 | + |
982 | +#. module: base_custom_attributes |
983 | +#: field:attribute.attribute,required_on_views:0 |
984 | +#: model:ir.model.fields,field_description:base_custom_attributes.field_attribute_attribute_required_on_views |
985 | +msgid "Required (on views)" |
986 | +msgstr "" |
987 | + |
988 | +#. module: base_custom_attributes |
989 | +#: model:ir.model,name:base_custom_attributes.model_ir_model_fields |
990 | +msgid "Fields" |
991 | +msgstr "" |
992 | + |
993 | +#. module: base_custom_attributes |
994 | +#: view:attribute.attribute:0 |
995 | +#: field:attribute.attribute,option_ids:0 |
996 | +#: model:ir.actions.act_window,name:base_custom_attributes.attribute_option_form_action |
997 | +#: model:ir.model.fields,field_description:base_custom_attributes.field_attribute_attribute_option_ids |
998 | +#: model:ir.ui.menu,name:base_custom_attributes.menu_attribute_option_action |
999 | +msgid "Attribute Options" |
1000 | +msgstr "" |
1001 | + |
1002 | +#. module: base_custom_attributes |
1003 | +#: field:attribute.attribute,serialized:0 |
1004 | +#: model:ir.model.fields,field_description:base_custom_attributes.field_attribute_attribute_serialized |
1005 | +msgid "Field serialized" |
1006 | +msgstr "" |
1007 | + |
1008 | +#. module: base_custom_attributes |
1009 | +#: code:addons/base_custom_attributes/custom_attributes.py:44 |
1010 | +#, python-format |
1011 | +msgid "Error!" |
1012 | +msgstr "" |
1013 | + |
1014 | +#. module: base_custom_attributes |
1015 | +#: view:attribute.option.wizard:0 |
1016 | +msgid "Validate" |
1017 | +msgstr "" |
1018 | + |
1019 | +#. module: base_custom_attributes |
1020 | +#: selection:attribute.attribute,attribute_type:0 |
1021 | +msgid "Multiselect" |
1022 | +msgstr "" |
1023 | + |
1024 | +#. module: base_custom_attributes |
1025 | +#: view:attribute.option:0 |
1026 | +msgid "Search Attribute Options" |
1027 | +msgstr "" |
1028 | + |
1029 | +#. module: base_custom_attributes |
1030 | +#: selection:attribute.attribute,attribute_type:0 |
1031 | +msgid "Integer" |
1032 | +msgstr "" |
1033 | + |
1034 | +#. module: base_custom_attributes |
1035 | +#: field:attribute.group,attribute_ids:0 |
1036 | +#: model:ir.actions.act_window,name:base_custom_attributes.attribute_attribute_form_action |
1037 | +#: model:ir.model.fields,field_description:base_custom_attributes.field_attribute_group_attribute_ids |
1038 | +#: model:ir.ui.menu,name:base_custom_attributes.menu_attribute_attribute_action |
1039 | +#: model:ir.ui.menu,name:base_custom_attributes.menu_attribute_in_admin |
1040 | +msgid "Attributes" |
1041 | +msgstr "" |
1042 | + |
1043 | +#. module: base_custom_attributes |
1044 | +#: field:attribute.attribute,relation_model_id:0 |
1045 | +#: field:attribute.group,model_id:0 |
1046 | +#: field:attribute.set,model_id:0 |
1047 | +#: model:ir.model.fields,field_description:base_custom_attributes.field_attribute_attribute_relation_model_id |
1048 | +#: model:ir.model.fields,field_description:base_custom_attributes.field_attribute_group_model_id |
1049 | +#: model:ir.model.fields,field_description:base_custom_attributes.field_attribute_set_model_id |
1050 | +msgid "Model" |
1051 | +msgstr "" |
1052 | + |
1053 | +#. module: base_custom_attributes |
1054 | +#: model:ir.actions.act_window,name:base_custom_attributes.attribute_set_form_action |
1055 | +#: model:ir.ui.menu,name:base_custom_attributes.menu_attribute_set_action |
1056 | +msgid "Attribute Sets" |
1057 | +msgstr "" |
1058 | + |
1059 | +#. module: base_custom_attributes |
1060 | +#: view:attribute.attribute:0 |
1061 | +msgid "Load Options" |
1062 | +msgstr "" |
1063 | + |
1064 | +#. module: base_custom_attributes |
1065 | +#: field:attribute.option,value_ref:0 |
1066 | +#: model:ir.model.fields,field_description:base_custom_attributes.field_attribute_option_value_ref |
1067 | +msgid "Reference" |
1068 | +msgstr "" |
1069 | + |
1070 | +#. module: base_custom_attributes |
1071 | +#: field:attribute.group,sequence:0 |
1072 | +#: field:attribute.location,sequence:0 |
1073 | +#: field:attribute.option,sequence:0 |
1074 | +#: model:ir.model.fields,field_description:base_custom_attributes.field_attribute_group_sequence |
1075 | +#: model:ir.model.fields,field_description:base_custom_attributes.field_attribute_location_sequence |
1076 | +#: model:ir.model.fields,field_description:base_custom_attributes.field_attribute_option_sequence |
1077 | +msgid "Sequence" |
1078 | +msgstr "" |
1079 | + |
1080 | +#. module: base_custom_attributes |
1081 | +#: view:attribute.attribute:0 |
1082 | +#: field:attribute.location,attribute_id:0 |
1083 | +#: field:attribute.option,attribute_id:0 |
1084 | +#: field:attribute.option.wizard,attribute_id:0 |
1085 | +#: model:ir.model,name:base_custom_attributes.model_attribute_attribute |
1086 | +#: model:ir.model.fields,field_description:base_custom_attributes.field_attribute_location_attribute_id |
1087 | +#: model:ir.model.fields,field_description:base_custom_attributes.field_attribute_option_attribute_id |
1088 | +#: model:ir.model.fields,field_description:base_custom_attributes.field_attribute_option_wizard_attribute_id |
1089 | +msgid "Attribute" |
1090 | +msgstr "" |
1091 | + |
1092 | +#. module: base_custom_attributes |
1093 | +#: selection:attribute.attribute,attribute_type:0 |
1094 | +msgid "Float" |
1095 | +msgstr "" |
1096 | + |
1097 | +#. module: base_custom_attributes |
1098 | +#: field:attribute.group,attribute_set_id:0 |
1099 | +#: field:attribute.location,attribute_set_id:0 |
1100 | +#: view:attribute.set:0 |
1101 | +#: model:ir.model,name:base_custom_attributes.model_attribute_set |
1102 | +#: model:ir.model.fields,field_description:base_custom_attributes.field_attribute_group_attribute_set_id |
1103 | +#: model:ir.model.fields,field_description:base_custom_attributes.field_attribute_location_attribute_set_id |
1104 | +msgid "Attribute Set" |
1105 | +msgstr "" |
1106 | + |
1107 | +#. module: base_custom_attributes |
1108 | +#: selection:attribute.attribute,attribute_type:0 |
1109 | +msgid "Datetime" |
1110 | +msgstr "" |
1111 | + |
1112 | +#. module: base_custom_attributes |
1113 | +#: selection:attribute.attribute,attribute_type:0 |
1114 | +msgid "Char" |
1115 | +msgstr "" |
1116 | + |
1117 | +#. module: base_custom_attributes |
1118 | +#: selection:attribute.attribute,attribute_type:0 |
1119 | +msgid "Boolean" |
1120 | +msgstr "" |
1121 | + |
1122 | +#. module: base_custom_attributes |
1123 | +#: selection:attribute.attribute,attribute_type:0 |
1124 | +msgid "Text" |
1125 | +msgstr "" |
1126 | + |
1127 | +#. module: base_custom_attributes |
1128 | +#: view:attribute.option.wizard:0 |
1129 | +msgid "Cancel" |
1130 | +msgstr "" |
1131 | + |
1132 | +#. module: base_custom_attributes |
1133 | +#: model:ir.model,name:base_custom_attributes.model_attribute_option_wizard |
1134 | +msgid "attribute.option.wizard" |
1135 | +msgstr "" |
1136 | + |
1137 | +#. module: base_custom_attributes |
1138 | +#: sql_constraint:ir.model.fields:0 |
1139 | +msgid "The name of the field has to be uniq for a given model !" |
1140 | +msgstr "" |
1141 | + |
1142 | +#. module: base_custom_attributes |
1143 | +#: selection:attribute.attribute,attribute_type:0 |
1144 | +msgid "Select" |
1145 | +msgstr "" |
1146 | + |
1147 | |
1148 | === added file 'base_custom_attributes/i18n/fr.po' |
1149 | --- base_custom_attributes/i18n/fr.po 1970-01-01 00:00:00 +0000 |
1150 | +++ base_custom_attributes/i18n/fr.po 2013-12-11 14:54:36 +0000 |
1151 | @@ -0,0 +1,291 @@ |
1152 | +# Translation of OpenERP Server. |
1153 | +# This file contains the translation of the following modules: |
1154 | +# * base_custom_attributes |
1155 | +# |
1156 | +msgid "" |
1157 | +msgstr "" |
1158 | +"Project-Id-Version: OpenERP Server 7.0\n" |
1159 | +"Report-Msgid-Bugs-To: \n" |
1160 | +"POT-Creation-Date: 2013-10-16 09:03+0000\n" |
1161 | +"PO-Revision-Date: 2013-10-16 09:03+0000\n" |
1162 | +"Last-Translator: <>\n" |
1163 | +"Language-Team: \n" |
1164 | +"MIME-Version: 1.0\n" |
1165 | +"Content-Type: text/plain; charset=UTF-8\n" |
1166 | +"Content-Transfer-Encoding: \n" |
1167 | +"Plural-Forms: \n" |
1168 | + |
1169 | +#. module: base_custom_attributes |
1170 | +#: code:addons/base_custom_attributes/custom_attributes.py:44 |
1171 | +#, python-format |
1172 | +msgid "Use the 'Load Options' button instead to select appropriate model references." |
1173 | +msgstr "Utiliser le bouton 'Charger les options' pour sélectionner le modèle de référence approprié." |
1174 | + |
1175 | +#. module: base_custom_attributes |
1176 | +#: selection:attribute.attribute,attribute_type:0 |
1177 | +msgid "Binary" |
1178 | +msgstr "Binary" |
1179 | + |
1180 | +#. module: base_custom_attributes |
1181 | +#: view:attribute.attribute:0 |
1182 | +msgid "Search Attributes" |
1183 | +msgstr "Rechercher des attributs" |
1184 | + |
1185 | +#. module: base_custom_attributes |
1186 | +#: view:attribute.group:0 |
1187 | +#: field:attribute.location,attribute_group_id:0 |
1188 | +#: model:ir.model,name:base_custom_attributes.model_attribute_group |
1189 | +#: model:ir.model.fields,field_description:base_custom_attributes.field_attribute_location_attribute_group_id |
1190 | +msgid "Attribute Group" |
1191 | +msgstr "Groupe d'attributs" |
1192 | + |
1193 | +#. module: base_custom_attributes |
1194 | +#: view:attribute.group:0 |
1195 | +#: model:ir.model,name:base_custom_attributes.model_attribute_location |
1196 | +msgid "Attribute Location" |
1197 | +msgstr "Attribute Location" |
1198 | + |
1199 | +#. module: base_custom_attributes |
1200 | +#: code:addons/base_custom_attributes/custom_attributes.py:154 |
1201 | +#: view:attribute.option.wizard:0 |
1202 | +#, python-format |
1203 | +msgid "Options Wizard" |
1204 | +msgstr "Options Wizard" |
1205 | + |
1206 | +#. module: base_custom_attributes |
1207 | +#: view:attribute.group:0 |
1208 | +msgid "Search Attribute Groups" |
1209 | +msgstr "Rechercher des groupes d'attributs" |
1210 | + |
1211 | +#. module: base_custom_attributes |
1212 | +#: field:attribute.attribute,attribute_type:0 |
1213 | +#: model:ir.model.fields,field_description:base_custom_attributes.field_attribute_attribute_attribute_type |
1214 | +msgid "Type" |
1215 | +msgstr "Type" |
1216 | + |
1217 | +#. module: base_custom_attributes |
1218 | +#: field:attribute.set,attribute_group_ids:0 |
1219 | +#: model:ir.actions.act_window,name:base_custom_attributes.attribute_group_form_action |
1220 | +#: model:ir.model.fields,field_description:base_custom_attributes.field_attribute_set_attribute_group_ids |
1221 | +#: model:ir.ui.menu,name:base_custom_attributes.menu_attribute_group_action |
1222 | +msgid "Attribute Groups" |
1223 | +msgstr "Groupes d'attributs" |
1224 | + |
1225 | +#. module: base_custom_attributes |
1226 | +#: field:attribute.attribute,create_date:0 |
1227 | +#: model:ir.model.fields,field_description:base_custom_attributes.field_attribute_attribute_create_date |
1228 | +msgid "Created date" |
1229 | +msgstr "Date de création" |
1230 | + |
1231 | +#. module: base_custom_attributes |
1232 | +#: view:attribute.set:0 |
1233 | +msgid "Search Attribute Sets" |
1234 | +msgstr "Rechercher des jeux d'attributs" |
1235 | + |
1236 | +#. module: base_custom_attributes |
1237 | +#: view:attribute.option:0 |
1238 | +#: model:ir.model,name:base_custom_attributes.model_attribute_option |
1239 | +msgid "Attribute Option" |
1240 | +msgstr "Option d'attribut" |
1241 | + |
1242 | +#. module: base_custom_attributes |
1243 | +#: selection:attribute.attribute,attribute_type:0 |
1244 | +msgid "Date" |
1245 | +msgstr "Date" |
1246 | + |
1247 | +#. module: base_custom_attributes |
1248 | +#: help:attribute.attribute,required_on_views:0 |
1249 | +msgid "If activated, the attribute will be mandatory on the views, but not in the database" |
1250 | +msgstr "Si activé, l'attribut sera obligatoire dans les vues, mais pas dans la base de données." |
1251 | + |
1252 | +#. module: base_custom_attributes |
1253 | +#: field:attribute.attribute,field_id:0 |
1254 | +#: model:ir.model.fields,field_description:base_custom_attributes.field_attribute_attribute_field_id |
1255 | +msgid "Ir Model Fields" |
1256 | +msgstr "Ir Model Fields" |
1257 | + |
1258 | +#. module: base_custom_attributes |
1259 | +#: view:attribute.option.wizard:0 |
1260 | +msgid "options_placeholder" |
1261 | +msgstr "options_placeholder" |
1262 | + |
1263 | +#. module: base_custom_attributes |
1264 | +#: field:attribute.group,name:0 |
1265 | +#: field:attribute.option,name:0 |
1266 | +#: field:attribute.set,name:0 |
1267 | +#: model:ir.model.fields,field_description:base_custom_attributes.field_attribute_group_name |
1268 | +#: model:ir.model.fields,field_description:base_custom_attributes.field_attribute_option_name |
1269 | +#: model:ir.model.fields,field_description:base_custom_attributes.field_attribute_set_name |
1270 | +msgid "Name" |
1271 | +msgstr "Nom" |
1272 | + |
1273 | +#. module: base_custom_attributes |
1274 | +#: help:attribute.attribute,serialized:0 |
1275 | +msgid "If serialized, the field will be stocked in the serialized field: attribute_custom_tmpl or attribute_custom_variant depending on the field based_on" |
1276 | +msgstr "Si serialisé, le champ sera stocké dans un champ serialisé : attribute_custom_tmpl ou attribut_custom_variant selon la valeur du champ based_on" |
1277 | + |
1278 | +#. module: base_custom_attributes |
1279 | +#: field:attribute.attribute,required_on_views:0 |
1280 | +#: model:ir.model.fields,field_description:base_custom_attributes.field_attribute_attribute_required_on_views |
1281 | +msgid "Required (on views)" |
1282 | +msgstr "Obligatoire (dans les vues)" |
1283 | + |
1284 | +#. module: base_custom_attributes |
1285 | +#: model:ir.model,name:base_custom_attributes.model_ir_model_fields |
1286 | +msgid "Fields" |
1287 | +msgstr "Champs" |
1288 | + |
1289 | +#. module: base_custom_attributes |
1290 | +#: view:attribute.attribute:0 |
1291 | +#: field:attribute.attribute,option_ids:0 |
1292 | +#: model:ir.actions.act_window,name:base_custom_attributes.attribute_option_form_action |
1293 | +#: model:ir.model.fields,field_description:base_custom_attributes.field_attribute_attribute_option_ids |
1294 | +#: model:ir.ui.menu,name:base_custom_attributes.menu_attribute_option_action |
1295 | +msgid "Attribute Options" |
1296 | +msgstr "Options d'attribut" |
1297 | + |
1298 | +#. module: base_custom_attributes |
1299 | +#: field:attribute.attribute,serialized:0 |
1300 | +#: model:ir.model.fields,field_description:base_custom_attributes.field_attribute_attribute_serialized |
1301 | +msgid "Field serialized" |
1302 | +msgstr "Champ serialisé" |
1303 | + |
1304 | +#. module: base_custom_attributes |
1305 | +#: code:addons/base_custom_attributes/custom_attributes.py:44 |
1306 | +#, python-format |
1307 | +msgid "Error!" |
1308 | +msgstr "Erreur !" |
1309 | + |
1310 | +#. module: base_custom_attributes |
1311 | +#: view:attribute.option.wizard:0 |
1312 | +msgid "Validate" |
1313 | +msgstr "Valider" |
1314 | + |
1315 | +#. module: base_custom_attributes |
1316 | +#: selection:attribute.attribute,attribute_type:0 |
1317 | +msgid "Multiselect" |
1318 | +msgstr "Multiselect" |
1319 | + |
1320 | +#. module: base_custom_attributes |
1321 | +#: view:attribute.option:0 |
1322 | +msgid "Search Attribute Options" |
1323 | +msgstr "Rechercher des options d'attribut" |
1324 | + |
1325 | +#. module: base_custom_attributes |
1326 | +#: selection:attribute.attribute,attribute_type:0 |
1327 | +msgid "Integer" |
1328 | +msgstr "Integer" |
1329 | + |
1330 | +#. module: base_custom_attributes |
1331 | +#: field:attribute.group,attribute_ids:0 |
1332 | +#: model:ir.actions.act_window,name:base_custom_attributes.attribute_attribute_form_action |
1333 | +#: model:ir.model.fields,field_description:base_custom_attributes.field_attribute_group_attribute_ids |
1334 | +#: model:ir.ui.menu,name:base_custom_attributes.menu_attribute_attribute_action |
1335 | +#: model:ir.ui.menu,name:base_custom_attributes.menu_attribute_in_admin |
1336 | +msgid "Attributes" |
1337 | +msgstr "Attributs" |
1338 | + |
1339 | +#. module: base_custom_attributes |
1340 | +#: field:attribute.attribute,relation_model_id:0 |
1341 | +#: field:attribute.group,model_id:0 |
1342 | +#: field:attribute.set,model_id:0 |
1343 | +#: model:ir.model.fields,field_description:base_custom_attributes.field_attribute_attribute_relation_model_id |
1344 | +#: model:ir.model.fields,field_description:base_custom_attributes.field_attribute_group_model_id |
1345 | +#: model:ir.model.fields,field_description:base_custom_attributes.field_attribute_set_model_id |
1346 | +msgid "Model" |
1347 | +msgstr "Modèle" |
1348 | + |
1349 | +#. module: base_custom_attributes |
1350 | +#: model:ir.actions.act_window,name:base_custom_attributes.attribute_set_form_action |
1351 | +#: model:ir.ui.menu,name:base_custom_attributes.menu_attribute_set_action |
1352 | +msgid "Attribute Sets" |
1353 | +msgstr "Jeux d'attributs" |
1354 | + |
1355 | +#. module: base_custom_attributes |
1356 | +#: view:attribute.attribute:0 |
1357 | +msgid "Load Options" |
1358 | +msgstr "Charger les options" |
1359 | + |
1360 | +#. module: base_custom_attributes |
1361 | +#: field:attribute.option,value_ref:0 |
1362 | +#: model:ir.model.fields,field_description:base_custom_attributes.field_attribute_option_value_ref |
1363 | +msgid "Reference" |
1364 | +msgstr "Référence" |
1365 | + |
1366 | +#. module: base_custom_attributes |
1367 | +#: field:attribute.group,sequence:0 |
1368 | +#: field:attribute.location,sequence:0 |
1369 | +#: field:attribute.option,sequence:0 |
1370 | +#: model:ir.model.fields,field_description:base_custom_attributes.field_attribute_group_sequence |
1371 | +#: model:ir.model.fields,field_description:base_custom_attributes.field_attribute_location_sequence |
1372 | +#: model:ir.model.fields,field_description:base_custom_attributes.field_attribute_option_sequence |
1373 | +msgid "Sequence" |
1374 | +msgstr "Séquence" |
1375 | + |
1376 | +#. module: base_custom_attributes |
1377 | +#: view:attribute.attribute:0 |
1378 | +#: field:attribute.location,attribute_id:0 |
1379 | +#: field:attribute.option,attribute_id:0 |
1380 | +#: field:attribute.option.wizard,attribute_id:0 |
1381 | +#: model:ir.model,name:base_custom_attributes.model_attribute_attribute |
1382 | +#: model:ir.model.fields,field_description:base_custom_attributes.field_attribute_location_attribute_id |
1383 | +#: model:ir.model.fields,field_description:base_custom_attributes.field_attribute_option_attribute_id |
1384 | +#: model:ir.model.fields,field_description:base_custom_attributes.field_attribute_option_wizard_attribute_id |
1385 | +msgid "Attribute" |
1386 | +msgstr "Attribut" |
1387 | + |
1388 | +#. module: base_custom_attributes |
1389 | +#: selection:attribute.attribute,attribute_type:0 |
1390 | +msgid "Float" |
1391 | +msgstr "Float" |
1392 | + |
1393 | +#. module: base_custom_attributes |
1394 | +#: field:attribute.group,attribute_set_id:0 |
1395 | +#: field:attribute.location,attribute_set_id:0 |
1396 | +#: view:attribute.set:0 |
1397 | +#: model:ir.model,name:base_custom_attributes.model_attribute_set |
1398 | +#: model:ir.model.fields,field_description:base_custom_attributes.field_attribute_group_attribute_set_id |
1399 | +#: model:ir.model.fields,field_description:base_custom_attributes.field_attribute_location_attribute_set_id |
1400 | +msgid "Attribute Set" |
1401 | +msgstr "Jeux d'attributs" |
1402 | + |
1403 | +#. module: base_custom_attributes |
1404 | +#: selection:attribute.attribute,attribute_type:0 |
1405 | +msgid "Datetime" |
1406 | +msgstr "Datetime" |
1407 | + |
1408 | +#. module: base_custom_attributes |
1409 | +#: selection:attribute.attribute,attribute_type:0 |
1410 | +msgid "Char" |
1411 | +msgstr "Char" |
1412 | + |
1413 | +#. module: base_custom_attributes |
1414 | +#: selection:attribute.attribute,attribute_type:0 |
1415 | +msgid "Boolean" |
1416 | +msgstr "Boolean" |
1417 | + |
1418 | +#. module: base_custom_attributes |
1419 | +#: selection:attribute.attribute,attribute_type:0 |
1420 | +msgid "Text" |
1421 | +msgstr "Text" |
1422 | + |
1423 | +#. module: base_custom_attributes |
1424 | +#: view:attribute.option.wizard:0 |
1425 | +msgid "Cancel" |
1426 | +msgstr "Annuler" |
1427 | + |
1428 | +#. module: base_custom_attributes |
1429 | +#: model:ir.model,name:base_custom_attributes.model_attribute_option_wizard |
1430 | +msgid "attribute.option.wizard" |
1431 | +msgstr "attribute.option.wizard" |
1432 | + |
1433 | +#. module: base_custom_attributes |
1434 | +#: sql_constraint:ir.model.fields:0 |
1435 | +msgid "The name of the field has to be uniq for a given model !" |
1436 | +msgstr "Le nom du champ doit être unique pour un modèle donné !" |
1437 | + |
1438 | +#. module: base_custom_attributes |
1439 | +#: selection:attribute.attribute,attribute_type:0 |
1440 | +msgid "Select" |
1441 | +msgstr "Select" |
1442 | + |
1443 | |
1444 | === added file 'base_custom_attributes/ir_model.py' |
1445 | --- base_custom_attributes/ir_model.py 1970-01-01 00:00:00 +0000 |
1446 | +++ base_custom_attributes/ir_model.py 2013-12-11 14:54:36 +0000 |
1447 | @@ -0,0 +1,39 @@ |
1448 | +# -*- encoding: utf-8 -*- |
1449 | +############################################################################### |
1450 | +# # |
1451 | +# product_custom_attributes for OpenERP |
1452 | +# Copyright (C) 2011 Akretion Benoît GUILLOT <benoit.guillot@akretion.com> |
1453 | +# # |
1454 | +# This program is free software: you can redistribute it and/or modify # |
1455 | +# it under the terms of the GNU Affero General Public License as # |
1456 | +# published by the Free Software Foundation, either version 3 of the # |
1457 | +# License, or (at your option) any later version. # |
1458 | +# # |
1459 | +# This program is distributed in the hope that it will be useful, # |
1460 | +# but WITHOUT ANY WARRANTY; without even the implied warranty of # |
1461 | +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # |
1462 | +# GNU Affero General Public License for more details. # |
1463 | +# # |
1464 | +# You should have received a copy of the GNU Affero General Public License # |
1465 | +# along with this program. If not, see <http://www.gnu.org/licenses/>. # |
1466 | +# # |
1467 | +############################################################################### |
1468 | + |
1469 | +from openerp.osv.orm import Model |
1470 | +from openerp.osv import fields |
1471 | + |
1472 | + |
1473 | +class ir_model_fields(Model): |
1474 | + |
1475 | + _inherit = "ir.model.fields" |
1476 | + _columns = { |
1477 | + 'field_description': fields.char( |
1478 | + 'Field Label', |
1479 | + required=True, |
1480 | + size=256, |
1481 | + translate=True), |
1482 | + } |
1483 | + _sql_constraints = [ |
1484 | + ('name_model_uniq', 'unique (name, model_id)', |
1485 | + 'The name of the field has to be uniq for a given model !'), |
1486 | + ] |
1487 | |
1488 | === added directory 'base_custom_attributes/security' |
1489 | === added file 'base_custom_attributes/security/attribute_security.xml' |
1490 | --- base_custom_attributes/security/attribute_security.xml 1970-01-01 00:00:00 +0000 |
1491 | +++ base_custom_attributes/security/attribute_security.xml 2013-12-11 14:54:36 +0000 |
1492 | @@ -0,0 +1,11 @@ |
1493 | +<?xml version="1.0" encoding="utf-8"?> |
1494 | +<openerp> |
1495 | +<data noupdate="0"> |
1496 | + |
1497 | + <record id="base.group_advanced_attribute" model="res.groups"> |
1498 | + <field name="name">Advanced Attribute Option</field> |
1499 | + <field name="category_id" ref="base.module_category_hidden"/> |
1500 | + </record> |
1501 | + |
1502 | +</data> |
1503 | +</openerp> |
1504 | |
1505 | === added file 'base_custom_attributes/security/ir.model.access.csv' |
1506 | --- base_custom_attributes/security/ir.model.access.csv 1970-01-01 00:00:00 +0000 |
1507 | +++ base_custom_attributes/security/ir.model.access.csv 2013-12-11 14:54:36 +0000 |
1508 | @@ -0,0 +1,13 @@ |
1509 | +id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink |
1510 | +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 |
1511 | +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 |
1512 | +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 |
1513 | +access_base_custom_attributes_attribute_location_salemanager,base_custom_attributes_attribute_location,base_custom_attributes.model_attribute_location,base.group_sale_manager,1,1,1,1 |
1514 | +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 |
1515 | +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 |
1516 | +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 |
1517 | +access_base_custom_attributes_attribute_location_manager,base_custom_attributes_attribute_location,base_custom_attributes.model_attribute_location,base.group_no_one,1,1,1,1 |
1518 | +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 |
1519 | +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 |
1520 | +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 |
1521 | +access_base_custom_attributes_attribute_location_user,base_custom_attributes_attribute_location,base_custom_attributes.model_attribute_location,base.group_user,1,1,1,0 |
1522 | |
1523 | === added directory 'production_lot_custom_attributes' |
1524 | === added file 'production_lot_custom_attributes/__init__.py' |
1525 | --- production_lot_custom_attributes/__init__.py 1970-01-01 00:00:00 +0000 |
1526 | +++ production_lot_custom_attributes/__init__.py 2013-12-11 14:54:36 +0000 |
1527 | @@ -0,0 +1,25 @@ |
1528 | +# -*- coding: utf-8 -*- |
1529 | +############################################################################### |
1530 | +# # |
1531 | +# Author: Leonardo Pistone <leonardo.pistone@camptocamp.com> # |
1532 | +# Copyright 2013 Camptocamp SA # |
1533 | +# # |
1534 | +# Inspired by the module product_custom_attributes # |
1535 | +# by Benoît GUILLOT <benoit.guillot@akretion.com>, Akretion # |
1536 | +# # |
1537 | +# This program is free software: you can redistribute it and/or modify # |
1538 | +# it under the terms of the GNU Affero General Public License as # |
1539 | +# published by the Free Software Foundation, either version 3 of the # |
1540 | +# License, or (at your option) any later version. # |
1541 | +# # |
1542 | +# This program is distributed in the hope that it will be useful, # |
1543 | +# but WITHOUT ANY WARRANTY; without even the implied warranty of # |
1544 | +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # |
1545 | +# GNU Affero General Public License for more details. # |
1546 | +# # |
1547 | +# You should have received a copy of the GNU Affero General Public License # |
1548 | +# along with this program. If not, see <http://www.gnu.org/licenses/>. # |
1549 | +# # |
1550 | +############################################################################### |
1551 | +from . import lot |
1552 | +from . import wizard |
1553 | |
1554 | === added file 'production_lot_custom_attributes/__openerp__.py' |
1555 | --- production_lot_custom_attributes/__openerp__.py 1970-01-01 00:00:00 +0000 |
1556 | +++ production_lot_custom_attributes/__openerp__.py 2013-12-11 14:54:36 +0000 |
1557 | @@ -0,0 +1,62 @@ |
1558 | +# -*- coding: utf-8 -*- |
1559 | +############################################################################### |
1560 | +# # |
1561 | +# Author: Leonardo Pistone <leonardo.pistone@camptocamp.com> # |
1562 | +# Copyright 2013 Camptocamp SA # |
1563 | +# # |
1564 | +# Inspired by the module product_custom_attributes # |
1565 | +# by Benoît GUILLOT <benoit.guillot@akretion.com>, Akretion # |
1566 | +# # |
1567 | +# This program is free software: you can redistribute it and/or modify # |
1568 | +# it under the terms of the GNU Affero General Public License as # |
1569 | +# published by the Free Software Foundation, either version 3 of the # |
1570 | +# License, or (at your option) any later version. # |
1571 | +# # |
1572 | +# This program is distributed in the hope that it will be useful, # |
1573 | +# but WITHOUT ANY WARRANTY; without even the implied warranty of # |
1574 | +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # |
1575 | +# GNU Affero General Public License for more details. # |
1576 | +# # |
1577 | +# You should have received a copy of the GNU Affero General Public License # |
1578 | +# along with this program. If not, see <http://www.gnu.org/licenses/>. # |
1579 | +# # |
1580 | +############################################################################### |
1581 | + |
1582 | +{'name': 'production_lot_custom_attributes', |
1583 | + 'version': '0.1', |
1584 | + 'category': 'Generic Modules/Others', |
1585 | + 'license': 'AGPL-3', |
1586 | + 'description': """ |
1587 | +Production lot custom attributes |
1588 | +================================ |
1589 | + |
1590 | +This module adds the possibility to easily create custom fields on stock |
1591 | +production lots. Each lot can be linked to an attribute set. |
1592 | +Each attribute has custom fields (for example, you don't need the same field |
1593 | +for a frigde and a camera). |
1594 | +In particular it's used by the Magento Magentoerpconnect module to match the |
1595 | +EAV flexibility of Magento. |
1596 | + |
1597 | +Warning: This module is not compatible with product_custom_attributes from 6.1. |
1598 | +To make the two compatible, product_custom_attributes should be split to depend |
1599 | +from base_custom_attributes, like it is already in 7.0. |
1600 | + |
1601 | +This module is inspired by the module product_custom_attributes by |
1602 | +Benoît GUILLOT, Akretion |
1603 | + |
1604 | +""", |
1605 | + 'complexity': 'normal', |
1606 | + 'author': 'Camptocamp', |
1607 | + 'website': 'http://www.camptocamp.com/', |
1608 | + 'depends': ['stock', 'base_custom_attributes'], |
1609 | + 'init_xml': [], |
1610 | + 'update_xml': ['lot_view.xml', |
1611 | + 'custom_attributes_view.xml', |
1612 | + 'wizard/open_lot_by_attribute_set.xml' |
1613 | + ], |
1614 | + 'test': ['test/lot_attribute_test.yml', |
1615 | + ], |
1616 | + 'demo_xml': [], |
1617 | + 'installable': True, |
1618 | + 'active': False, |
1619 | + } |
1620 | |
1621 | === added file 'production_lot_custom_attributes/custom_attributes_view.xml' |
1622 | --- production_lot_custom_attributes/custom_attributes_view.xml 1970-01-01 00:00:00 +0000 |
1623 | +++ production_lot_custom_attributes/custom_attributes_view.xml 2013-12-11 14:54:36 +0000 |
1624 | @@ -0,0 +1,58 @@ |
1625 | +<?xml version="1.0" encoding="utf-8"?> |
1626 | +<openerp> |
1627 | + <data> |
1628 | + |
1629 | + <menuitem |
1630 | + id="menu_lot_attribute_in_warehouse_config" |
1631 | + name="Serial Number Attributes" |
1632 | + parent="stock.menu_warehouse_config" |
1633 | + sequence="20"/> |
1634 | + |
1635 | + <record id="lot_attribute_set_form_action" model="ir.actions.act_window"> |
1636 | + <field name="name">Lot Attribute Sets</field> |
1637 | + <field name="res_model">attribute.set</field> |
1638 | + <field name="view_type">form</field> |
1639 | + <field name="view_mode">tree,form</field> |
1640 | + <field name="search_view_id" ref="base_custom_attributes.view_attribute_set_search"/> |
1641 | + <field name="context">{"force_model": 'stock.production.lot'}</field> |
1642 | + <field name="help"></field> |
1643 | + </record> |
1644 | + |
1645 | + <record id="lot_attribute_group_form_action" model="ir.actions.act_window"> |
1646 | + <field name="name">Attribute Groups</field> |
1647 | + <field name="res_model">attribute.group</field> |
1648 | + <field name="view_type">form</field> |
1649 | + <field name="view_mode">tree,form</field> |
1650 | + <field name="search_view_id" ref="base_custom_attributes.view_attribute_attribute_search"/> |
1651 | + <field name="context">{"force_model": 'stock.production.lot'}</field> |
1652 | + <field name="help"></field> |
1653 | + </record> |
1654 | + |
1655 | + <record id="lot_attribute_attribute_form_action" model="ir.actions.act_window"> |
1656 | + <field name="name">Lot Attributes</field> |
1657 | + <field name="res_model">attribute.attribute</field> |
1658 | + <field name="view_type">form</field> |
1659 | + <field name="view_mode">tree,form</field> |
1660 | + <field name="search_view_id" ref="base_custom_attributes.view_attribute_attribute_search"/> |
1661 | + <field name="context">{"force_model": 'stock.production.lot'}</field> |
1662 | + <field name="help"></field> |
1663 | + </record> |
1664 | + |
1665 | + <menuitem |
1666 | + action="lot_attribute_set_form_action" |
1667 | + id="menu_lot_attribute_set_action" |
1668 | + parent="menu_lot_attribute_in_warehouse_config" |
1669 | + sequence="1"/> |
1670 | + <menuitem |
1671 | + action="lot_attribute_group_form_action" |
1672 | + id="menu_lot_attribute_group_action" |
1673 | + parent="menu_lot_attribute_in_warehouse_config" |
1674 | + sequence="2"/> |
1675 | + <menuitem |
1676 | + action="lot_attribute_attribute_form_action" |
1677 | + id="menu_lot_attribute_attribute_action" |
1678 | + parent="menu_lot_attribute_in_warehouse_config" |
1679 | + sequence="4"/> |
1680 | + |
1681 | + </data> |
1682 | +</openerp> |
1683 | |
1684 | === added file 'production_lot_custom_attributes/lot.py' |
1685 | --- production_lot_custom_attributes/lot.py 1970-01-01 00:00:00 +0000 |
1686 | +++ production_lot_custom_attributes/lot.py 2013-12-11 14:54:36 +0000 |
1687 | @@ -0,0 +1,207 @@ |
1688 | +# -*- coding: utf-8 -*- |
1689 | +############################################################################### |
1690 | +# # |
1691 | +# Author: Leonardo Pistone <leonardo.pistone@camptocamp.com> # |
1692 | +# Copyright 2013 Camptocamp SA # |
1693 | +# # |
1694 | +# Inspired by the module product_custom_attributes # |
1695 | +# by Benoît GUILLOT <benoit.guillot@akretion.com>, Akretion # |
1696 | +# # |
1697 | +# This program is free software: you can redistribute it and/or modify # |
1698 | +# it under the terms of the GNU Affero General Public License as # |
1699 | +# published by the Free Software Foundation, either version 3 of the # |
1700 | +# License, or (at your option) any later version. # |
1701 | +# # |
1702 | +# This program is distributed in the hope that it will be useful, # |
1703 | +# but WITHOUT ANY WARRANTY; without even the implied warranty of # |
1704 | +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # |
1705 | +# GNU Affero General Public License for more details. # |
1706 | +# # |
1707 | +# You should have received a copy of the GNU Affero General Public License # |
1708 | +# along with this program. If not, see <http://www.gnu.org/licenses/>. # |
1709 | +# # |
1710 | +############################################################################### |
1711 | + |
1712 | +from openerp.osv import fields, osv |
1713 | +from tools.translate import _ |
1714 | +from lxml import etree |
1715 | +import re |
1716 | + |
1717 | + |
1718 | +class stock_production_lot(osv.Model): |
1719 | + _inherit = "stock.production.lot" |
1720 | + |
1721 | + def _search_all_attributes(self, cr, uid, obj, name, args, context): |
1722 | + """Search in all serialized attributes |
1723 | + |
1724 | + Receives a domain in args, and expands all relevant terms into ids |
1725 | + to search into all attributes. The ORM will take care of security |
1726 | + afterwards, so it' OK to use SQL here. |
1727 | + |
1728 | + In the future, we could consider storing attributes as native PostgreSQL |
1729 | + hstore or JSON instead of strings, and substitute this rough regexp |
1730 | + search with native PostgreSQL goodness. |
1731 | + |
1732 | + """ |
1733 | + |
1734 | + def expand_arg(arg): |
1735 | + """Takes a single argument of the domain, and when possible expands |
1736 | + it to a trivial domain ('in', 'in', list) |
1737 | + |
1738 | + """ |
1739 | + if isinstance(arg, tuple) and arg[0] == name: |
1740 | + if arg[1] == 'like': |
1741 | + operator = '~' |
1742 | + elif arg[1] == 'ilike': |
1743 | + operator = '~*' |
1744 | + else: |
1745 | + raise osv.except_osv( |
1746 | + _('Not Implemented!'), |
1747 | + _('Search not supported for this field')) |
1748 | + |
1749 | + cr.execute( |
1750 | + """ |
1751 | + select id |
1752 | + from {0} |
1753 | + where x_custom_json_attrs {1} %s; |
1754 | + """.format( |
1755 | + self._table, |
1756 | + operator |
1757 | + ), |
1758 | + (ur'.*: "[^"]*%s' % re.escape(arg[2]) ,) |
1759 | + ) |
1760 | + sql_ids = [line[0] for line in cr.fetchall()] |
1761 | + return ('id', 'in', sql_ids) |
1762 | + else: |
1763 | + return arg |
1764 | + |
1765 | + return [expand_arg(arg) for arg in args] |
1766 | + |
1767 | + _columns = { |
1768 | + 'attribute_set_id': fields.many2one('attribute.set', 'Attribute Set'), |
1769 | + 'attribute_group_ids': fields.related( |
1770 | + 'attribute_set_id', |
1771 | + 'attribute_group_ids', |
1772 | + type='many2many', |
1773 | + relation='attribute.group' |
1774 | + ), |
1775 | + 'search_all_attributes': fields.function( |
1776 | + lambda self, cr, uid, ids, field, args, context: u'', |
1777 | + type="char", |
1778 | + fnct_search=_search_all_attributes, |
1779 | + method=True, |
1780 | + string="Search all Attributes"), |
1781 | + } |
1782 | + |
1783 | + def _fix_size_bug(self, cr, uid, result, context=None): |
1784 | + """When created a field text dynamicaly, its size is limited to 64 in |
1785 | + the view. The bug is fixed but not merged |
1786 | + https://code.launchpad.net/~openerp-dev/openerp-web/6.1-opw-579462-cpa |
1787 | + To remove when the fix will be merged |
1788 | + |
1789 | + """ |
1790 | + for field in result['fields']: |
1791 | + if result['fields'][field]['type'] == 'text': |
1792 | + if 'size' in result['fields'][field]: |
1793 | + del result['fields'][field]['size'] |
1794 | + return result |
1795 | + |
1796 | + def open_attributes(self, cr, uid, ids, context=None): |
1797 | + """Open the attributes of an object |
1798 | + |
1799 | + This method is called when the user presses the Open Attributes button |
1800 | + in the form view of the object. It opens a dinamically-built form view. |
1801 | + |
1802 | + :param ids: this is normally a singleton. If a longer list is passed, |
1803 | + we consider only the first item. |
1804 | + |
1805 | + """ |
1806 | + |
1807 | + if context is None: |
1808 | + context = {} |
1809 | + |
1810 | + model_data_pool = self.pool.get('ir.model.data') |
1811 | + |
1812 | + for lot in self.browse(cr, uid, ids, context=context): |
1813 | + view_id = model_data_pool.get_object_reference( |
1814 | + cr, uid, |
1815 | + 'production_lot_custom_attributes', |
1816 | + 'lot_attributes_form_view')[1] |
1817 | + ctx = { |
1818 | + 'open_attributes': True, |
1819 | + 'attribute_group_ids': [ |
1820 | + group.id for group in lot.attribute_group_ids |
1821 | + ] |
1822 | + } |
1823 | + |
1824 | + return { |
1825 | + 'name': 'Lot Attributes', |
1826 | + 'view_type': 'form', |
1827 | + 'view_mode': 'form', |
1828 | + 'view_id': [view_id], |
1829 | + 'res_model': self._name, |
1830 | + 'context': ctx, |
1831 | + 'type': 'ir.actions.act_window', |
1832 | + 'nodestroy': True, |
1833 | + 'target': 'new', |
1834 | + 'res_id': lot.id, |
1835 | + } |
1836 | + |
1837 | + def save_and_close_lot_attributes(self, cr, uid, ids, context=None): |
1838 | + return {'type': 'ir.actions.act_window_close'} |
1839 | + |
1840 | + def fields_view_get(self, cr, uid, view_id=None, view_type='form', |
1841 | + context=None, toolbar=False, submenu=False): |
1842 | + """Dinamically adds attributes to the view |
1843 | + |
1844 | + Modifies dinamically the view to show the attributes. If the users |
1845 | + presses the Open Attributes button, the attributes are shown in a |
1846 | + new form field. Otherwise, if the attribute set is known beforehand, |
1847 | + attributes are added to a new tab in the main form view. |
1848 | + |
1849 | + """ |
1850 | + if context is None: |
1851 | + context = {} |
1852 | + attr_pool = self.pool.get('attribute.attribute') |
1853 | + result = super(stock_production_lot, self).fields_view_get( |
1854 | + cr, uid, view_id, view_type, context, toolbar=toolbar, |
1855 | + submenu=submenu |
1856 | + ) |
1857 | + if view_type == 'form' and context.get('attribute_group_ids'): |
1858 | + eview = etree.fromstring(result['arch']) |
1859 | + #hide button under the name |
1860 | + button = eview.xpath("//button[@name='open_attributes']") |
1861 | + if button: |
1862 | + button = button[0] |
1863 | + button.getparent().remove(button) |
1864 | + attributes_notebook, toupdate_fields = ( |
1865 | + attr_pool._build_attributes_notebook( |
1866 | + cr, uid, context['attribute_group_ids'], context=context |
1867 | + ) |
1868 | + ) |
1869 | + result['fields'].update( |
1870 | + self.fields_get(cr, uid, toupdate_fields, context) |
1871 | + ) |
1872 | + if context.get('open_attributes'): |
1873 | + # i.e. the user pressed the open attributes button on the |
1874 | + # form view. We put the attributes in a separate form view |
1875 | + placeholder = eview.xpath( |
1876 | + "//separator[@string='attributes_placeholder']" |
1877 | + )[0] |
1878 | + placeholder.getparent().replace( |
1879 | + placeholder, attributes_notebook |
1880 | + ) |
1881 | + elif context.get('open_lot_by_attribute_set'): |
1882 | + # in this case, we know the attribute set beforehand, and we |
1883 | + # add the attributes to the current view |
1884 | + main_page = etree.Element( |
1885 | + 'page', string=_('Custom Attributes') |
1886 | + ) |
1887 | + main_page.append(attributes_notebook) |
1888 | + info_page = eview.xpath( |
1889 | + "//page[@string='%s']" % (_('Stock Moves'),) |
1890 | + )[0] |
1891 | + info_page.addnext(main_page) |
1892 | + result['arch'] = etree.tostring(eview, pretty_print=True) |
1893 | + result = self._fix_size_bug(cr, uid, result, context=context) |
1894 | + return result |
1895 | |
1896 | === added file 'production_lot_custom_attributes/lot_view.xml' |
1897 | --- production_lot_custom_attributes/lot_view.xml 1970-01-01 00:00:00 +0000 |
1898 | +++ production_lot_custom_attributes/lot_view.xml 2013-12-11 14:54:36 +0000 |
1899 | @@ -0,0 +1,52 @@ |
1900 | +<?xml version="1.0" encoding="utf-8"?> |
1901 | + |
1902 | +<openerp> |
1903 | + <data> |
1904 | + |
1905 | + <record model="ir.ui.view" id="lot_form_view_set_button"> |
1906 | + <field name="name">attributes.lot.normal.form</field> |
1907 | + <field name="model">stock.production.lot</field> |
1908 | + <field name="inherit_id" ref="stock.view_production_lot_form"/> |
1909 | + <field name="arch" type="xml"> |
1910 | + <notebook position="inside"> |
1911 | + <page string="Attributes"> |
1912 | + <group name="attribute_fields"> |
1913 | + <field name="attribute_set_id" /> |
1914 | + <button name="open_attributes" string="Open Attributes" type="object" icon="gtk-ok" attrs="{'invisible':[('attribute_set_id', '=', False)]}"/> |
1915 | + </group> |
1916 | + </page> |
1917 | + </notebook> |
1918 | + </field> |
1919 | + </record> |
1920 | + |
1921 | + <record model="ir.ui.view" id="search_product_lot_filter"> |
1922 | + <field name="model">stock.production.lot</field> |
1923 | + <field name="inherit_id" ref="stock.search_product_lot_filter"/> |
1924 | + <field name="arch" type="xml"> |
1925 | + <field name="date" position="after"> |
1926 | + <field name="search_all_attributes"/> |
1927 | + </field> |
1928 | + </field> |
1929 | + </record> |
1930 | + |
1931 | + <record model="ir.ui.view" id="lot_attributes_form_view"> |
1932 | + <field name="name">lot.attributes.normal.wizard</field> |
1933 | + <field name="model">stock.production.lot</field> |
1934 | + <field name="priority">20</field> |
1935 | + <field name="arch" type="xml"> |
1936 | + <form string="Lot"> |
1937 | + <group name="name_set" colspan='4' col='8'> |
1938 | + <field name="name"/> |
1939 | + <field name="attribute_set_id" /> |
1940 | + </group> |
1941 | + <separator string="attributes_placeholder" colspan="4"/> |
1942 | + <group colspan='4' col='4'> |
1943 | + <button icon="gtk-cancel" special="cancel" string="Cancel"/> |
1944 | + <button icon="gtk-ok" name="save_and_close_lot_attributes" string="Save and Close" type="object"/> |
1945 | + </group> |
1946 | + </form> |
1947 | + </field> |
1948 | + </record> |
1949 | + |
1950 | + </data> |
1951 | +</openerp> |
1952 | |
1953 | === added directory 'production_lot_custom_attributes/test' |
1954 | === added file 'production_lot_custom_attributes/test/lot_attribute_test.yml' |
1955 | --- production_lot_custom_attributes/test/lot_attribute_test.yml 1970-01-01 00:00:00 +0000 |
1956 | +++ production_lot_custom_attributes/test/lot_attribute_test.yml 2013-12-11 14:54:36 +0000 |
1957 | @@ -0,0 +1,48 @@ |
1958 | +- |
1959 | + In order to test Production Lot Custom Fields |
1960 | +- |
1961 | + First I create an Attribute Set |
1962 | +- |
1963 | + !record {model: attribute.set, id: lot_attribute_set_A}: |
1964 | + name: Serial Number Attribute Set A |
1965 | + model_id: stock.model_stock_production_lot |
1966 | + attribute_group_ids: |
1967 | + - name: Components |
1968 | + model_id: stock.model_stock_production_lot |
1969 | + sequence: 1 |
1970 | + attribute_ids: |
1971 | + - name: x_ram_amount |
1972 | + model_id: stock.model_stock_production_lot |
1973 | + field_description: Amount of RAM |
1974 | + attribute_type: float |
1975 | + - name: x_has_display |
1976 | + model_id: stock.model_stock_production_lot |
1977 | + field_description: Has Display |
1978 | + attribute_type: boolean |
1979 | + - name: Characteristics |
1980 | + model_id: stock.model_stock_production_lot |
1981 | + sequence: 2 |
1982 | + attribute_ids: |
1983 | + - name: x_color |
1984 | + model_id: stock.model_stock_production_lot |
1985 | + field_description: Color |
1986 | + attribute_type: char |
1987 | + - name: x_length |
1988 | + model_id: stock.model_stock_production_lot |
1989 | + field_description: Length |
1990 | + attribute_type: float |
1991 | +- |
1992 | + Then I create a Serial Number and set some Attributes |
1993 | +- |
1994 | + !record {model: stock.production.lot, id: lot_A}: |
1995 | + product_id: product.product_product_pc2 |
1996 | + name: 0005 |
1997 | + attribute_set_id: lot_attribute_set_A |
1998 | + x_color: green |
1999 | + x_length: 12.5 |
2000 | +- |
2001 | + Now I check that my attributes are there |
2002 | +- |
2003 | + !assert {model: stock.production.lot, id: lot_A, string: Lot Attributes do not work}: |
2004 | + - x_color == 'green' |
2005 | + - x_length == 12.5 |
2006 | |
2007 | === added directory 'production_lot_custom_attributes/wizard' |
2008 | === added file 'production_lot_custom_attributes/wizard/__init__.py' |
2009 | --- production_lot_custom_attributes/wizard/__init__.py 1970-01-01 00:00:00 +0000 |
2010 | +++ production_lot_custom_attributes/wizard/__init__.py 2013-12-11 14:54:36 +0000 |
2011 | @@ -0,0 +1,25 @@ |
2012 | +# -*- coding: utf-8 -*- |
2013 | +############################################################################### |
2014 | +# # |
2015 | +# Author: Leonardo Pistone <leonardo.pistone@camptocamp.com> # |
2016 | +# Copyright 2013 Camptocamp SA # |
2017 | +# # |
2018 | +# Inspired by the module product_custom_attributes # |
2019 | +# by Benoît GUILLOT <benoit.guillot@akretion.com>, Akretion # |
2020 | +# # |
2021 | +# This program is free software: you can redistribute it and/or modify # |
2022 | +# it under the terms of the GNU Affero General Public License as # |
2023 | +# published by the Free Software Foundation, either version 3 of the # |
2024 | +# License, or (at your option) any later version. # |
2025 | +# # |
2026 | +# This program is distributed in the hope that it will be useful, # |
2027 | +# but WITHOUT ANY WARRANTY; without even the implied warranty of # |
2028 | +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # |
2029 | +# GNU Affero General Public License for more details. # |
2030 | +# # |
2031 | +# You should have received a copy of the GNU Affero General Public License # |
2032 | +# along with this program. If not, see <http://www.gnu.org/licenses/>. # |
2033 | +# # |
2034 | +############################################################################### |
2035 | + |
2036 | +from . import open_lot_by_attribute_set |
2037 | |
2038 | === added file 'production_lot_custom_attributes/wizard/open_lot_by_attribute_set.py' |
2039 | --- production_lot_custom_attributes/wizard/open_lot_by_attribute_set.py 1970-01-01 00:00:00 +0000 |
2040 | +++ production_lot_custom_attributes/wizard/open_lot_by_attribute_set.py 2013-12-11 14:54:36 +0000 |
2041 | @@ -0,0 +1,67 @@ |
2042 | +# -*- coding: utf-8 -*- |
2043 | +############################################################################### |
2044 | +# # |
2045 | +# Author: Leonardo Pistone <leonardo.pistone@camptocamp.com> # |
2046 | +# Copyright 2013 Camptocamp SA # |
2047 | +# # |
2048 | +# This program is free software: you can redistribute it and/or modify # |
2049 | +# it under the terms of the GNU Affero General Public License as # |
2050 | +# published by the Free Software Foundation, either version 3 of the # |
2051 | +# License, or (at your option) any later version. # |
2052 | +# # |
2053 | +# This program is distributed in the hope that it will be useful, # |
2054 | +# but WITHOUT ANY WARRANTY; without even the implied warranty of # |
2055 | +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # |
2056 | +# GNU Affero General Public License for more details. # |
2057 | +# # |
2058 | +# You should have received a copy of the GNU Affero General Public License # |
2059 | +# along with this program. If not, see <http://www.gnu.org/licenses/>. # |
2060 | +# # |
2061 | +############################################################################### |
2062 | + |
2063 | +from openerp.osv.orm import TransientModel |
2064 | +from osv import fields |
2065 | + |
2066 | + |
2067 | +class open_lot_by_attribute_set(TransientModel): |
2068 | + _name = 'open.lot.by.attribute.set' |
2069 | + _description = 'Wizard to open lots by attributes set' |
2070 | + |
2071 | + _columns = { |
2072 | + 'attribute_set_id': fields.many2one('attribute.set', 'Attribute Set'), |
2073 | + } |
2074 | + |
2075 | + def open_lot_by_attribute(self, cr, uid, ids, context=None): |
2076 | + """Opens a lot by attributes |
2077 | + |
2078 | + Returns a custom action built modifying the original one. |
2079 | + """ |
2080 | + |
2081 | + mod_obj = self.pool.get('ir.model.data') |
2082 | + act_obj = self.pool.get('ir.actions.act_window') |
2083 | + |
2084 | + if context is None: |
2085 | + context = {} |
2086 | + |
2087 | + # we expect one wizard instance at a time |
2088 | + for wiz in self.browse(cr, uid, ids, context=context): |
2089 | + action_id = mod_obj.get_object_reference( |
2090 | + cr, uid, 'stock', 'action_production_lot_form')[1] |
2091 | + action = act_obj.read(cr, uid, [action_id], context=context)[0] |
2092 | + |
2093 | + ctx = ( |
2094 | + "{'open_lot_by_attribute_set': True, " |
2095 | + "'attribute_group_ids': %s}" |
2096 | + % [ |
2097 | + group.id |
2098 | + for group in wiz.attribute_set_id.attribute_group_ids |
2099 | + ] |
2100 | + ) |
2101 | + |
2102 | + action['context'] = ctx |
2103 | + action['domain'] = ( |
2104 | + "[('attribute_set_id', '=', %s)]" |
2105 | + % wiz.attribute_set_id.id |
2106 | + ) |
2107 | + action['name'] = wiz.attribute_set_id.name |
2108 | + return action |
2109 | |
2110 | === added file 'production_lot_custom_attributes/wizard/open_lot_by_attribute_set.xml' |
2111 | --- production_lot_custom_attributes/wizard/open_lot_by_attribute_set.xml 1970-01-01 00:00:00 +0000 |
2112 | +++ production_lot_custom_attributes/wizard/open_lot_by_attribute_set.xml 2013-12-11 14:54:36 +0000 |
2113 | @@ -0,0 +1,30 @@ |
2114 | +<?xml version="1.0" encoding="utf-8"?> |
2115 | + |
2116 | +<openerp> |
2117 | + <data> |
2118 | + |
2119 | + <record id="open_lot_by_attribute_set_view" model="ir.ui.view"> |
2120 | + <field name="name">open.lot.by.attribute.set.view</field> |
2121 | + <field name="model">open.lot.by.attribute.set</field> |
2122 | + <field name="arch" type="xml"> |
2123 | + <form string="Open lot by attributes set"> |
2124 | + <field name="attribute_set_id" colspan="4"/> |
2125 | + <button icon="gtk-cancel" special="cancel" string="Cancel"/> |
2126 | + <button icon="gtk-ok" name="open_lot_by_attribute" string="Open Product By attribute" type="object"/> |
2127 | + </form> |
2128 | + </field> |
2129 | + </record> |
2130 | + |
2131 | + <record id="open_lot_by_attribute_set" model="ir.actions.act_window"> |
2132 | + <field name="name">Open lot By Attribute Set</field> |
2133 | + <field name="res_model">open.lot.by.attribute.set</field> |
2134 | + <field name="view_type">form</field> |
2135 | + <field name="target">new</field> |
2136 | + <field name="view_id" ref="open_lot_by_attribute_set_view"/> |
2137 | + <field name="help"></field> |
2138 | + </record> |
2139 | + |
2140 | + <menuitem action="open_lot_by_attribute_set" id="open_lot_wizard" parent="stock.menu_traceability"/> |
2141 | + |
2142 | + </data> |
2143 | +</openerp> |
LGTM