Merge lp:~camptocamp/openerp-product-attributes/6.1-backport-lot-custom-attributes-lep into lp:~product-core-editors/openerp-product-attributes/6.1

Proposed by Leonardo Pistone
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
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_attributes and production_lot_custom_attributes, backported from 7.0 and cleaned up

Description of the change

This is to backport the modules base_custom_attributes and production_lot_custom_attributes to v6.1.

I added some docstrings and comments that should make creating a new similar module easier.

Warning: in v7.0 the module product_custom_attributes (where all that started) has been split to use base_custom_attributes. In 6.1 is hasn't, so at the moment in 6.1 product_custom_attributes and production_lot_custom_attributes are incompatible.

Thanks to Akretion for the original modules this is based on.

To post a comment you must log in.
Revision history for this message
Omar (Pexego) (omar7r) wrote :

LGTM

review: Approve (code review, no test)
200. By Leonardo Pistone

[imp] production_lot_custom_attributes: refactor wizard

Revision history for this message
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

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== added directory 'base_custom_attributes'
=== added file 'base_custom_attributes/__init__.py'
--- base_custom_attributes/__init__.py 1970-01-01 00:00:00 +0000
+++ base_custom_attributes/__init__.py 2013-12-11 14:54:36 +0000
@@ -0,0 +1,29 @@
1# -*- encoding: utf-8 -*-
2###############################################################################
3# #
4# product_custom_attributes for OpenERP #
5# Copyright (C) 2011 Akretion Benoît GUILLOT <benoit.guillot@akretion.com> #
6# #
7# This program is free software: you can redistribute it and/or modify #
8# it under the terms of the GNU Affero General Public License as #
9# published by the Free Software Foundation, either version 3 of the #
10# License, or (at your option) any later version. #
11# #
12# This program is distributed in the hope that it will be useful, #
13# but WITHOUT ANY WARRANTY; without even the implied warranty of #
14# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
15# GNU Affero General Public License for more details. #
16# #
17# You should have received a copy of the GNU Affero General Public License #
18# along with this program. If not, see <http://www.gnu.org/licenses/>. #
19# #
20###############################################################################
21
22
23
24import ir_model
25import custom_attributes
26
27
28
29
030
=== added file 'base_custom_attributes/__openerp__.py'
--- base_custom_attributes/__openerp__.py 1970-01-01 00:00:00 +0000
+++ base_custom_attributes/__openerp__.py 2013-12-11 14:54:36 +0000
@@ -0,0 +1,48 @@
1# -*- encoding: utf-8 -*-
2###############################################################################
3# #
4# base_custom_attributes for OpenERP #
5# Copyright (C) 2011 Akretion Benoît GUILLOT <benoit.guillot@akretion.com> #
6# #
7# This program is free software: you can redistribute it and/or modify #
8# it under the terms of the GNU Affero General Public License as #
9# published by the Free Software Foundation, either version 3 of the #
10# License, or (at your option) any later version. #
11# #
12# This program is distributed in the hope that it will be useful, #
13# but WITHOUT ANY WARRANTY; without even the implied warranty of #
14# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
15# GNU Affero General Public License for more details. #
16# #
17# You should have received a copy of the GNU Affero General Public License #
18# along with this program. If not, see <http://www.gnu.org/licenses/>. #
19# #
20###############################################################################
21
22
23
24{
25 'name': 'base_custom_attributes',
26 'version': '0.1',
27 'category': 'Generic Modules/Others',
28 'license': 'AGPL-3',
29 'description': """This module adds the possibility to easily create custom attributes in any OpenERP business object. See the product_custom_attributes module for instance.
30 """,
31 'author': 'Akretion',
32 'website': 'http://www.akretion.com/',
33 'depends': ['base'],
34 'init_xml': [],
35 'update_xml': [
36 'security/ir.model.access.csv',
37 'security/attribute_security.xml',
38 'custom_attributes_view.xml',
39 ],
40 'demo_xml': [],
41 'installable': True,
42 'active': False,
43 'external_dependencies' : {
44 'python' : ['unidecode'],
45 }
46
47}
48
049
=== added file 'base_custom_attributes/custom_attributes.py'
--- base_custom_attributes/custom_attributes.py 1970-01-01 00:00:00 +0000
+++ base_custom_attributes/custom_attributes.py 2013-12-11 14:54:36 +0000
@@ -0,0 +1,440 @@
1# -*- encoding: utf-8 -*-
2###############################################################################
3# #
4# base_attribute.attributes for OpenERP #
5# Copyright (C) 2011 Akretion Benoît GUILLOT <benoit.guillot@akretion.com>
6# Copyright (C) 2013 Akretion Raphaël VALYI <raphael.valyi@akretion.com>
7# #
8# This program is free software: you can redistribute it and/or modify #
9# it under the terms of the GNU Affero General Public License as #
10# published by the Free Software Foundation, either version 3 of the #
11# License, or (at your option) any later version. #
12# #
13# This program is distributed in the hope that it will be useful, #
14# but WITHOUT ANY WARRANTY; without even the implied warranty of #
15# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
16# GNU Affero General Public License for more details. #
17# #
18# You should have received a copy of the GNU Affero General Public License #
19# along with this program. If not, see <http://www.gnu.org/licenses/>. #
20# #
21###############################################################################
22
23import ast
24from openerp.osv import orm, fields
25from openerp.osv.osv import except_osv
26from openerp.tools.translate import _
27from lxml import etree
28from unidecode import unidecode # Debian package python-unidecode
29import re
30
31
32def safe_column_name(string):
33 """This function prevent portability problem in database column name
34 with other DBMS system
35 Use case : if you synchronise attributes with other applications """
36 string = unidecode(string.replace(' ', '_').lower())
37 return re.sub(r'[^0-9a-z_]','', string)
38
39
40class attribute_option(orm.Model):
41 _name = "attribute.option"
42 _description = "Attribute Option"
43 _order="sequence"
44
45 def _get_model_list(self, cr, uid, context=None):
46 model_pool = self.pool.get('ir.model')
47 ids = model_pool.search(cr, uid, [], context=context)
48 res = model_pool.read(cr, uid, ids, ['model', 'name'], context=context)
49 return [(r['model'], r['name']) for r in res]
50
51 _columns = {
52 'name': fields.char(
53 'Name',
54 size=128,
55 translate=True,
56 required=True),
57 'value_ref': fields.reference(
58 'Reference',
59 selection=_get_model_list,
60 size=128),
61 'attribute_id': fields.many2one(
62 'attribute.attribute',
63 'Product Attribute',
64 required=True),
65 'sequence': fields.integer('Sequence'),
66 }
67
68 def name_change(self, cr, uid, ids, name, relation_model_id, context=None):
69 if relation_model_id:
70 warning = {'title': _('Error!'),
71 'message': _("Use the 'Load Options' button "
72 "instead to select appropriate "
73 "model references'")}
74 return {"value": {"name": False}, "warning": warning}
75 else:
76 return True
77
78
79class attribute_option_wizard(orm.TransientModel):
80 _name = "attribute.option.wizard"
81 _rec_name = 'attribute_id'
82
83 _columns = {
84 'attribute_id': fields.many2one(
85 'attribute.attribute',
86 'Product Attribute',
87 required=True),
88 }
89
90 _defaults = {
91 'attribute_id': lambda self, cr, uid, context:
92 context.get('attribute_id',False)
93 }
94
95 def validate(self, cr, uid, ids, context=None):
96 return True
97
98 def create(self, cr, uid, vals, context=None):
99 attr_obj = self.pool.get("attribute.attribute")
100 attr = attr_obj.browse(cr, uid, vals['attribute_id'])
101 op_ids = [op.id for op in attr.option_ids]
102 opt_obj = self.pool.get("attribute.option")
103 opt_obj.unlink(cr, uid, op_ids)
104 for op_id in (vals.get("option_ids") and vals['option_ids'][0][2] or []):
105 model = attr.relation_model_id.model
106 name = self.pool.get(model).name_get(cr, uid, [op_id], context)[0][1]
107 opt_obj.create(cr, uid, {
108 'attribute_id': vals['attribute_id'],
109 'name': name,
110 'value_ref': "%s,%s" % (attr.relation_model_id.model, op_id)
111 })
112 res = super(attribute_option_wizard, self).create(cr, uid, vals, context)
113 return res
114
115 def fields_view_get(self, cr, uid, view_id=None, view_type='form',
116 context=None, toolbar=False, submenu=False):
117 res = super(attribute_option_wizard, self).fields_view_get(
118 cr, uid, view_id, view_type, context, toolbar, submenu)
119 if view_type == 'form' and context and context.get("attribute_id"):
120 attr_obj = self.pool.get("attribute.attribute")
121 model_id = attr_obj.read(cr, uid, [context.get("attribute_id")],
122 ['relation_model_id'])[0]['relation_model_id'][0]
123 relation = self.pool.get("ir.model").read(cr, uid, [model_id],
124 ["model"])[0]["model"]
125 res['fields'].update({'option_ids': {
126 'domain': [],
127 'string': "Options",
128 'type': 'many2many',
129 'relation': relation,
130 'required': True,
131 }
132 })
133 eview = etree.fromstring(res['arch'])
134 options = etree.Element('field', name='option_ids', colspan='6')
135 placeholder = eview.xpath("//separator[@string='options_placeholder']")[0]
136 placeholder.getparent().replace(placeholder, options)
137 res['arch'] = etree.tostring(eview, pretty_print=True)
138 return res
139
140
141class attribute_attribute(orm.Model):
142 _name = "attribute.attribute"
143 _description = "Attribute"
144 _inherits = {'ir.model.fields': 'field_id'}
145
146 def _build_attribute_field(self, cr, uid, page, attribute, context=None):
147 parent = etree.SubElement(page, 'group', colspan="2", col="4")
148 kwargs = {'name': "%s" % attribute.name}
149 if attribute.ttype in ['many2many', 'text']:
150 parent = etree.SubElement(parent, 'group', colspan="2", col="4")
151 etree.SubElement(parent,
152 'separator',
153 string="%s" % attribute.field_description,
154 colspan="4")
155 kwargs['nolabel'] = "1"
156 if attribute.ttype in ['many2one', 'many2many']:
157 if attribute.relation_model_id:
158 # attribute.domain is a string, it may be an empty list
159 try:
160 domain = ast.literal_eval(attribute.domain)
161 except ValueError:
162 domain = None
163 if domain:
164 kwargs['domain'] = attribute.domain
165 else:
166 ids = [op.value_ref.id for op in attribute.option_ids]
167 kwargs['domain'] = "[('id', 'in', %s)]" % ids
168 else:
169 kwargs['domain'] = "[('attribute_id', '=', %s)]" % attribute.attribute_id.id
170 kwargs['context'] = "{'default_attribute_id': %s}" % attribute.attribute_id.id
171 kwargs['required'] = str(attribute.required or
172 attribute.required_on_views)
173 field = etree.SubElement(parent, 'field', **kwargs)
174 orm.setup_modifiers(field, self.fields_get(cr, uid, attribute.name,
175 context))
176 return parent
177
178 def _build_attributes_notebook(self, cr, uid, attribute_group_ids,
179 context=None):
180 notebook = etree.Element('notebook', name="attributes_notebook",
181 colspan="4")
182 toupdate_fields = []
183 grp_obj = self.pool.get('attribute.group')
184 for group in grp_obj.browse(cr, uid, attribute_group_ids,
185 context=context):
186 page = etree.SubElement(notebook, 'page',
187 string=group.name.capitalize())
188 for attribute in group.attribute_ids:
189 if attribute.name not in toupdate_fields:
190 toupdate_fields.append(attribute.name)
191 self._build_attribute_field(cr, uid, page, attribute,
192 context=context)
193 return notebook, toupdate_fields
194
195 def relation_model_id_change(self, cr, uid, ids, relation_model_id,
196 option_ids, context=None):
197 "removed selected options as they would be inconsistent"
198 return {'value': {'option_ids': [(2, i[1]) for i in option_ids]}}
199
200 def button_add_options(self, cr, uid, ids, context=None):
201 return {
202 'context': "{'attribute_id': %s}" % (ids[0]),
203 'name': _('Options Wizard'),
204 'view_type': 'form',
205 'view_mode': 'form',
206 'res_model': 'attribute.option.wizard',
207 'type': 'ir.actions.act_window',
208 'target': 'new',
209 }
210
211 _columns = {
212 'field_id': fields.many2one(
213 'ir.model.fields',
214 'Ir Model Fields',
215 required=True,
216 ondelete="cascade"),
217 'attribute_type': fields.selection([
218 ('char', 'Char'),
219 ('text', 'Text'),
220 ('select', 'Select'),
221 ('multiselect', 'Multiselect'),
222 ('boolean', 'Boolean'),
223 ('integer', 'Integer'),
224 ('date', 'Date'),
225 ('datetime', 'Datetime'),
226 ('binary', 'Binary'),
227 ('float', 'Float')],
228 'Type', required=True),
229 'serialized': fields.boolean(
230 'Field serialized',
231 help="If serialized, the field will be stocked in the serialized "
232 "field: attribute_custom_tmpl or attribute_custom_variant "
233 "depending on the field based_on"),
234 'option_ids': fields.one2many(
235 'attribute.option',
236 'attribute_id',
237 'Attribute Options'),
238 'create_date': fields.datetime('Created date', readonly=True),
239 'relation_model_id': fields.many2one(
240 'ir.model',
241 'Model'),
242 'required_on_views': fields.boolean(
243 'Required (on views)',
244 help="If activated, the attribute will be mandatory on the views, "
245 "but not in the database"),
246 }
247
248 def create(self, cr, uid, vals, context=None):
249 if vals.get('relation_model_id'):
250 relation = self.pool.get('ir.model').read(
251 cr, uid, [vals.get('relation_model_id')], ['model'])[0]['model']
252 else:
253 relation = 'attribute.option'
254 if vals['attribute_type'] == 'select':
255 vals['ttype'] = 'many2one'
256 vals['relation'] = relation
257 elif vals['attribute_type'] == 'multiselect':
258 vals['ttype'] = 'many2many'
259 vals['relation'] = relation
260 vals['serialized'] = True
261 else:
262 vals['ttype'] = vals['attribute_type']
263
264 if vals.get('serialized'):
265 field_obj = self.pool.get('ir.model.fields')
266 serialized_ids = field_obj.search(cr, uid, [
267 ('ttype', '=', 'serialized'),
268 ('model_id', '=', vals['model_id']),
269 ('name', '=', 'x_custom_json_attrs')],
270 context=context)
271 if serialized_ids:
272 vals['serialization_field_id'] = serialized_ids[0]
273 else:
274 f_vals = {
275 'name': u'x_custom_json_attrs',
276 'field_description': u'Serialized JSON Attributes',
277 'ttype': 'serialized',
278 'model_id': vals['model_id'],
279 }
280 vals['serialization_field_id'] = field_obj.create(
281 cr, uid, f_vals, {'manual': True})
282 vals['state'] = 'manual'
283 return super(attribute_attribute, self).create(cr, uid, vals, context)
284
285 def onchange_field_description(self, cr, uid, ids, field_description,
286 name, create_date, context=None):
287 name = name or u'x_'
288 if field_description and not create_date:
289 name = unicode('x_' + safe_column_name(field_description))
290 return {'value': {'name': name}}
291
292 def onchange_name(self, cr, uid, ids, name, context=None):
293 res = {}
294 if not name.startswith('x_'):
295 name = u'x_%s' % name
296 else:
297 name = u'%s' % name
298 res = {'value': {'name': unidecode(name)}}
299
300 #FILTER ON MODEL
301 model_name = context.get('force_model')
302 if not model_name:
303 model_id = context.get('default_model_id')
304 if model_id:
305 model = self.pool['ir.model'].browse(cr, uid, model_id,
306 context=context)
307 model_name = model.model
308 if model_name:
309 model_obj = self.pool[model_name]
310 allowed_model = [x for x in model_obj._inherits] + [model_name]
311 res['domain'] = {'model_id': [['model', 'in', allowed_model]]}
312
313 return res
314
315 def _get_default_model(self, cr, uid, context=None):
316 if context and context.get('force_model'):
317 model_id = self.pool['ir.model'].search(cr, uid, [
318 ('model', '=', context['force_model'])
319 ], context=context)
320 if model_id:
321 return model_id[0]
322 return None
323
324 _defaults = {
325 'model_id': _get_default_model
326 }
327
328
329class attribute_group(orm.Model):
330 _name = "attribute.group"
331 _description = "Attribute Group"
332 _order ="sequence"
333
334 _columns = {
335 'name': fields.char(
336 'Name',
337 size=128,
338 required=True,
339 translate=True),
340 'sequence': fields.integer('Sequence'),
341 'attribute_set_id': fields.many2one(
342 'attribute.set',
343 'Attribute Set'),
344 'attribute_ids': fields.one2many(
345 'attribute.location',
346 'attribute_group_id',
347 'Attributes'),
348 'model_id': fields.many2one(
349 'ir.model',
350 'Model',
351 required=True),
352 }
353
354 def create(self, cr, uid, vals, context=None):
355 for attribute in vals.get('attribute_ids', []):
356 if (vals.get('attribute_set_id') and attribute[2] and
357 not attribute[2].get('attribute_set_id')):
358 attribute[2]['attribute_set_id'] = vals['attribute_set_id']
359 return super(attribute_group, self).create(cr, uid, vals, context)
360
361 def _get_default_model(self, cr, uid, context=None):
362 if context and context.get('force_model'):
363 model_id = self.pool['ir.model'].search(
364 cr, uid, [['model', '=', context['force_model']]],
365 context=context)
366 if model_id:
367 return model_id[0]
368 return None
369
370 _defaults = {
371 'model_id': _get_default_model
372 }
373
374
375class attribute_set(orm.Model):
376 _name = "attribute.set"
377 _description = "Attribute Set"
378 _columns = {
379 'name': fields.char(
380 'Name',
381 size=128,
382 required=True,
383 translate=True),
384 'attribute_group_ids': fields.one2many(
385 'attribute.group',
386 'attribute_set_id',
387 'Attribute Groups'),
388 'model_id': fields.many2one(
389 'ir.model',
390 'Model',
391 required=True),
392 }
393
394 def _get_default_model(self, cr, uid, context=None):
395 if context and context.get('force_model'):
396 model_id = self.pool['ir.model'].search(
397 cr, uid, [['model', '=', context['force_model']]],
398 context=context)
399 if model_id:
400 return model_id[0]
401 return None
402
403 _defaults = {
404 'model_id': _get_default_model
405 }
406
407
408class attribute_location(orm.Model):
409 _name = "attribute.location"
410 _description = "Attribute Location"
411 _order="sequence"
412 _inherits = {'attribute.attribute': 'attribute_id'}
413
414 def _get_attribute_loc_from_group(self, cr, uid, ids, context=None):
415 return self.pool.get('attribute.location').search(
416 cr, uid, [('attribute_group_id', 'in', ids)], context=context)
417
418 _columns = {
419 'attribute_id': fields.many2one(
420 'attribute.attribute',
421 'Product Attribute',
422 required=True,
423 ondelete="cascade"),
424 'attribute_set_id': fields.related(
425 'attribute_group_id',
426 'attribute_set_id',
427 type='many2one',
428 relation='attribute.set',
429 string='Attribute Set',
430 readonly=True,
431 store={
432 'attribute.group': (_get_attribute_loc_from_group,
433 ['attribute_set_id'], 10),
434 }),
435 'attribute_group_id': fields.many2one(
436 'attribute.group',
437 'Attribute Group',
438 required=True),
439 'sequence': fields.integer('Sequence'),
440 }
0441
=== added file 'base_custom_attributes/custom_attributes_view.xml'
--- base_custom_attributes/custom_attributes_view.xml 1970-01-01 00:00:00 +0000
+++ base_custom_attributes/custom_attributes_view.xml 2013-12-11 14:54:36 +0000
@@ -0,0 +1,312 @@
1<?xml version="1.0" encoding="utf-8"?>
2<!--
3 base_custom_attributes for OpenERP
4 Copyright (C) 2011-2013 Akretion (http://www.akretion.com/)
5 @author: Benoît GUILLOT <benoit.guillot@akretion.com>
6 The licence is in the file __openerp__.py
7-->
8
9<openerp>
10 <data>
11
12 <menuitem
13 id="menu_attribute_in_admin" name="Attributes"
14 parent="base.next_id_9" sequence="1"/>
15
16 <!-- ATTRIBUTE SET VIEW -->
17
18 <record id="attribute_set_form_view" model="ir.ui.view">
19 <field name="name">attribute.set.form</field>
20 <field name="model">attribute.set</field>
21 <field name="type">form</field>
22 <field name="arch" type="xml">
23 <form string="Attribute Set">
24 <field name="name"/>
25 <field name="model_id" invisible="context.get('force_model')"/>
26 <field name="attribute_group_ids" colspan="4"
27 context="{'default_model_id': model_id, 'from_attribute_set':True}">
28 </field>
29 </form>
30 </field>
31 </record>
32
33 <record id="attribute_set_tree_view" model="ir.ui.view">
34 <field name="name">attribute.set.tree</field>
35 <field name="model">attribute.set</field>
36 <field name="type">tree</field>
37 <field name="arch" type="xml">
38 <tree string="Attribute Set" >
39 <field name="name" />
40 <field name="model_id" />
41 </tree>
42 </field>
43 </record>
44
45 <record id="view_attribute_set_search" model="ir.ui.view">
46 <field name="name">attribute.set.list</field>
47 <field name="model">attribute.set</field>
48 <field name="type">search</field>
49 <field name="arch" type="xml">
50 <search string="Search Attribute Sets">
51 <field name="name"/>
52 <field name="model_id" />
53 </search>
54 </field>
55 </record>
56
57 <record id="attribute_set_form_action" model="ir.actions.act_window">
58 <field name="name">Attribute Sets</field>
59 <field name="res_model">attribute.set</field>
60 <field name="view_type">form</field>
61 <field name="view_mode">tree,form</field>
62 <field name="search_view_id" ref="view_attribute_set_search"/>
63 <field name="context">{"search_default_user_id":uid}</field>
64 <field name="help"></field>
65 </record>
66
67 <menuitem
68 action="attribute_set_form_action" id="menu_attribute_set_action"
69 parent="menu_attribute_in_admin" sequence="10"/>
70
71
72
73 <!-- ATTRIBUTE GROUP VIEW -->
74
75 <record id="attribute_group_form_view" model="ir.ui.view">
76 <field name="name">attribute.group.form</field>
77 <field name="model">attribute.group</field>
78 <field name="type">form</field>
79 <field name="arch" type="xml">
80 <form string="Attribute Group">
81 <field name="name" />
82 <field name="sequence" />
83 <field name="model_id" invisible="context.get('from_attribute_set') or context.get('force_model')"/>
84 <field name="attribute_set_id" invisible="context.get('from_attribute_set')"/>
85 <field name="attribute_ids" colspan="4" nolabel="1">
86 <form string="Attribute Location">
87 <field name="attribute_id" context="{'default_model_id': parent.model_id}"/>
88 <field name="sequence" />
89 </form>
90 <tree string="Attribute Location" editable="top">
91 <field name="attribute_id" context="{'default_model_id': parent.model_id}"/>
92 <field name="sequence" />
93 </tree>
94 </field>
95 </form>
96 </field>
97 </record>
98
99 <record id="attribute_group_tree_view" model="ir.ui.view">
100 <field name="name">attribute.group.tree</field>
101 <field name="model">attribute.group</field>
102 <field name="type">tree</field>
103 <field name="arch" type="xml">
104 <tree string="Attribute Group">
105 <field name="name" />
106 <field name="sequence" />
107 <field name="attribute_set_id" invisible="context.get('from_attribute_set')"/>
108 <field name="model_id" invisible="context.get('from_attribute_set')"/>
109 </tree>
110 </field>
111 </record>
112
113 <record id="view_attribute_group_search" model="ir.ui.view">
114 <field name="name">attribute.group.list</field>
115 <field name="model">attribute.group</field>
116 <field name="type">search</field>
117 <field name="arch" type="xml">
118 <search string="Search Attribute Groups">
119 <field name="name"/>
120 <field name="attribute_set_id"/>
121 <field name="model_id" />
122 </search>
123 </field>
124 </record>
125
126
127 <record id="attribute_group_form_action" model="ir.actions.act_window">
128 <field name="name">Attribute Groups</field>
129 <field name="res_model">attribute.group</field>
130 <field name="view_type">form</field>
131 <field name="view_mode">tree,form</field>
132 <field name="context">{"search_default_user_id":uid}</field>
133 <field name="help"></field>
134 </record>
135
136 <menuitem
137 action="attribute_group_form_action" id="menu_attribute_group_action"
138 parent="menu_attribute_in_admin" sequence="20"/>
139
140 <!-- ATTRIBUTE VIEW -->
141
142 <record id="attribute_attribute_form_view" model="ir.ui.view">
143 <field name="name">attribute.attribute.form</field>
144 <field name="model">attribute.attribute</field>
145 <field name="type">form</field>
146 <field name="arch" type="xml">
147 <form string="Attribute">
148 <field name="field_description" on_change="onchange_field_description(field_description, name, create_date, context)"/>
149 <field name="name" attrs="{'readonly':[('create_date', '!=', False)]}" on_change="onchange_name(name, context)"/>
150 <field name="attribute_type" />
151 <field name="model_id" />
152 <field name="serialized" attrs="{'invisible':[('attribute_type', '=', 'multiselect')]}"/>
153 <field name="size" attrs="{'invisible':[('attribute_type', '!=', 'char')]}"/>
154 <field name="required_on_views"/>
155 <field name="translate" attrs="{'invisible':[('attribute_type', 'not in', ('char', 'text'))]}"/>
156 <newline />
157 <group colspan="4" attrs="{'invisible':[('attribute_type', 'not in', ['select', 'multiselect'])]}">
158 <group groups="base.group_advanced_attribute">
159 <field name="relation_model_id" on_change="relation_model_id_change(relation_model_id, option_ids, context)"/>
160 <field name="domain" attrs="{'invisible':[('relation_model_id', '=', False)]}"/>
161 <button name="button_add_options" attrs="{'invisible':[('relation_model_id', '=', False), ('domain', '!=', False)]}" type="object" string="Load Options"/>
162 </group>
163 <field name="option_ids" colspan="4" nolabel="1">
164 <tree string="Attribute Options" editable="top">
165 <field name="sequence" invisible="1"/>
166 <field name="name" on_change="name_change(name, parent.relation_model_id, context)"/>
167 </tree>
168 </field>
169 </group>
170 <field name="create_date" invisible="1"/>
171 </form>
172 </field>
173 </record>
174
175 <record id="attribute_attribute_tree_view" model="ir.ui.view">
176 <field name="name">attribute.attribute.tree</field>
177 <field name="model">attribute.attribute</field>
178 <field name="type">tree</field>
179 <field name="arch" type="xml">
180 <tree string="Attribute">
181 <field name="name" />
182 <field name="attribute_type" />
183 </tree>
184 </field>
185 </record>
186
187 <record id="view_attribute_attribute_search" model="ir.ui.view">
188 <field name="name">attribute.attribute.list</field>
189 <field name="model">attribute.attribute</field>
190 <field name="type">search</field>
191 <field name="arch" type="xml">
192 <search string="Search Attributes">
193 <field name="name"/>
194 </search>
195 </field>
196 </record>
197
198 <record id="attribute_attribute_form_action" model="ir.actions.act_window">
199 <field name="name">Attributes</field>
200 <field name="res_model">attribute.attribute</field>
201 <field name="view_type">form</field>
202 <field name="view_mode">tree,form</field>
203 <field name="search_view_id" ref="view_attribute_attribute_search"/>
204 <field name="context">{"search_default_user_id":uid}</field>
205 <field name="help"></field>
206 </record>
207 <menuitem
208 action="attribute_attribute_form_action" id="menu_attribute_attribute_action"
209 parent="menu_attribute_in_admin" sequence="30"/>
210
211 <!-- ATTRIBUTE OPTION VIEW -->
212 <record id="attribute_option_form_popup_view" model="ir.ui.view">
213 <field name="name">attribute.option.form.popup</field>
214 <field name="model">attribute.option</field>
215 <field name="priority" eval="6"/>
216 <field name="type">form</field>
217 <field name="arch" type="xml">
218 <form string="Attribute Option">
219 <field name="name" colspan="2"/>
220 <field name="value_ref" colspan="2" groups="base.group_advanced_attribute"/>
221 <field name="sequence" colspan="2"/>
222 </form>
223 </field>
224 </record>
225
226 <record id="attribute_option_form_view" model="ir.ui.view">
227 <field name="name">attribute.option.form</field>
228 <field name="model">attribute.option</field>
229 <field name="type">form</field>
230 <field name="arch" type="xml">
231 <form string="Attribute Option">
232 <field name="name" colspan="2"/>
233 <field name="value_ref" colspan="2" groups="base.group_advanced_attribute"/>
234 <field name="sequence" colspan="2"/>
235 <field name="attribute_id" colspan="2"/>
236 </form>
237 </field>
238 </record>
239
240 <record id="attribute_option_tree_view" model="ir.ui.view">
241 <field name="name">attribute.option.tree</field>
242 <field name="model">attribute.option</field>
243 <field eval="20" name="priority"/>
244 <field name="type">tree</field>
245 <field name="arch" type="xml">
246 <tree string="Attribute Option">
247 <field name="name" />
248 <field name="sequence" />
249 <field name="value_ref" groups="base.group_advanced_attribute"/>
250 <field name="attribute_id" />
251 </tree>
252 </field>
253 </record>
254
255 <record id="view_attribute_option_search" model="ir.ui.view">
256 <field name="name">attribute.option.list</field>
257 <field name="model">attribute.option</field>
258 <field name="type">search</field>
259 <field name="arch" type="xml">
260 <search string="Search Attribute Options">
261 <field name="name" />
262 <field name="attribute_id"/>
263 </search>
264 </field>
265 </record>
266
267 <record id="attribute_option_form_action" model="ir.actions.act_window">
268 <field name="name">Attribute Options</field>
269 <field name="res_model">attribute.option</field>
270 <field name="view_type">form</field>
271 <field name="view_mode">tree,form</field>
272 <field name="view_id" ref="attribute_option_tree_view"/>
273 <field name="search_view_id" ref="view_attribute_option_search"/>
274 <field name="context">{"search_default_user_id":uid}</field>
275 <field name="help"></field>
276 </record>
277
278 <record id="attribute_option_form_action_tree" model="ir.actions.act_window.view">
279 <field name="sequence" eval="1"/>
280 <field name="act_window_id" ref="attribute_option_form_action"/>
281 <field name="view_id" ref="attribute_option_tree_view"/>
282 <field name="view_mode">tree</field>
283 </record>
284
285 <record id="attribute_option_form_action_form" model="ir.actions.act_window.view">
286 <field name="sequence" eval="2"/>
287 <field name="act_window_id" ref="attribute_option_form_action"/>
288 <field name="view_id" ref="attribute_option_form_view"/>
289 <field name="view_mode">form</field>
290 </record>
291
292 <menuitem
293 action="attribute_option_form_action" id="menu_attribute_option_action"
294 parent="menu_attribute_in_admin" sequence="40"/>
295
296 <!-- ATTRIBUTE OPTION WIZARD -->
297 <record id="attribute_option_wizard_form_view" model="ir.ui.view">
298 <field name="name">attribute.option.wizard</field>
299 <field name="model">attribute.option.wizard</field>
300 <field name="type">form</field>
301 <field name="arch" type="xml">
302 <form string="Options Wizard" col="6">
303 <field name="attribute_id" invisible="1" colspan="2"/>
304 <separator string="options_placeholder"/>
305 <button special="cancel" string="Cancel" icon="gtk-cancel"/>
306 <button name="validate" string="Validate" type="object" icon="gtk-convert"/>
307 </form>
308 </field>
309 </record>
310
311 </data>
312</openerp>
0313
=== added directory 'base_custom_attributes/i18n'
=== added file 'base_custom_attributes/i18n/base_custom_attributes.pot'
--- base_custom_attributes/i18n/base_custom_attributes.pot 1970-01-01 00:00:00 +0000
+++ base_custom_attributes/i18n/base_custom_attributes.pot 2013-12-11 14:54:36 +0000
@@ -0,0 +1,291 @@
1# Translation of OpenERP Server.
2# This file contains the translation of the following modules:
3# * base_custom_attributes
4#
5msgid ""
6msgstr ""
7"Project-Id-Version: OpenERP Server 7.0\n"
8"Report-Msgid-Bugs-To: \n"
9"POT-Creation-Date: 2013-10-16 10:39+0000\n"
10"PO-Revision-Date: 2013-10-16 10:39+0000\n"
11"Last-Translator: <>\n"
12"Language-Team: \n"
13"MIME-Version: 1.0\n"
14"Content-Type: text/plain; charset=UTF-8\n"
15"Content-Transfer-Encoding: \n"
16"Plural-Forms: \n"
17
18#. module: base_custom_attributes
19#: code:addons/base_custom_attributes/custom_attributes.py:44
20#, python-format
21msgid "Use the 'Load Options' button instead to select appropriate model references."
22msgstr ""
23
24#. module: base_custom_attributes
25#: selection:attribute.attribute,attribute_type:0
26msgid "Binary"
27msgstr ""
28
29#. module: base_custom_attributes
30#: view:attribute.attribute:0
31msgid "Search Attributes"
32msgstr ""
33
34#. module: base_custom_attributes
35#: view:attribute.group:0
36#: field:attribute.location,attribute_group_id:0
37#: model:ir.model,name:base_custom_attributes.model_attribute_group
38#: model:ir.model.fields,field_description:base_custom_attributes.field_attribute_location_attribute_group_id
39msgid "Attribute Group"
40msgstr ""
41
42#. module: base_custom_attributes
43#: view:attribute.group:0
44#: model:ir.model,name:base_custom_attributes.model_attribute_location
45msgid "Attribute Location"
46msgstr ""
47
48#. module: base_custom_attributes
49#: code:addons/base_custom_attributes/custom_attributes.py:154
50#: view:attribute.option.wizard:0
51#, python-format
52msgid "Options Wizard"
53msgstr ""
54
55#. module: base_custom_attributes
56#: view:attribute.group:0
57msgid "Search Attribute Groups"
58msgstr ""
59
60#. module: base_custom_attributes
61#: field:attribute.attribute,attribute_type:0
62#: model:ir.model.fields,field_description:base_custom_attributes.field_attribute_attribute_attribute_type
63msgid "Type"
64msgstr ""
65
66#. module: base_custom_attributes
67#: field:attribute.set,attribute_group_ids:0
68#: model:ir.actions.act_window,name:base_custom_attributes.attribute_group_form_action
69#: model:ir.model.fields,field_description:base_custom_attributes.field_attribute_set_attribute_group_ids
70#: model:ir.ui.menu,name:base_custom_attributes.menu_attribute_group_action
71msgid "Attribute Groups"
72msgstr ""
73
74#. module: base_custom_attributes
75#: field:attribute.attribute,create_date:0
76#: model:ir.model.fields,field_description:base_custom_attributes.field_attribute_attribute_create_date
77msgid "Created date"
78msgstr ""
79
80#. module: base_custom_attributes
81#: view:attribute.set:0
82msgid "Search Attribute Sets"
83msgstr ""
84
85#. module: base_custom_attributes
86#: view:attribute.option:0
87#: model:ir.model,name:base_custom_attributes.model_attribute_option
88msgid "Attribute Option"
89msgstr ""
90
91#. module: base_custom_attributes
92#: selection:attribute.attribute,attribute_type:0
93msgid "Date"
94msgstr ""
95
96#. module: base_custom_attributes
97#: help:attribute.attribute,required_on_views:0
98msgid "If activated, the attribute will be mandatory on the views, but not in the database"
99msgstr ""
100
101#. module: base_custom_attributes
102#: field:attribute.attribute,field_id:0
103#: model:ir.model.fields,field_description:base_custom_attributes.field_attribute_attribute_field_id
104msgid "Ir Model Fields"
105msgstr ""
106
107#. module: base_custom_attributes
108#: view:attribute.option.wizard:0
109msgid "options_placeholder"
110msgstr ""
111
112#. module: base_custom_attributes
113#: field:attribute.group,name:0
114#: field:attribute.option,name:0
115#: field:attribute.set,name:0
116#: model:ir.model.fields,field_description:base_custom_attributes.field_attribute_group_name
117#: model:ir.model.fields,field_description:base_custom_attributes.field_attribute_option_name
118#: model:ir.model.fields,field_description:base_custom_attributes.field_attribute_set_name
119msgid "Name"
120msgstr ""
121
122#. module: base_custom_attributes
123#: help:attribute.attribute,serialized:0
124msgid "If serialized, the field will be stocked in the serialized field: attribute_custom_tmpl or attribute_custom_variant depending on the field based_on"
125msgstr ""
126
127#. module: base_custom_attributes
128#: field:attribute.attribute,required_on_views:0
129#: model:ir.model.fields,field_description:base_custom_attributes.field_attribute_attribute_required_on_views
130msgid "Required (on views)"
131msgstr ""
132
133#. module: base_custom_attributes
134#: model:ir.model,name:base_custom_attributes.model_ir_model_fields
135msgid "Fields"
136msgstr ""
137
138#. module: base_custom_attributes
139#: view:attribute.attribute:0
140#: field:attribute.attribute,option_ids:0
141#: model:ir.actions.act_window,name:base_custom_attributes.attribute_option_form_action
142#: model:ir.model.fields,field_description:base_custom_attributes.field_attribute_attribute_option_ids
143#: model:ir.ui.menu,name:base_custom_attributes.menu_attribute_option_action
144msgid "Attribute Options"
145msgstr ""
146
147#. module: base_custom_attributes
148#: field:attribute.attribute,serialized:0
149#: model:ir.model.fields,field_description:base_custom_attributes.field_attribute_attribute_serialized
150msgid "Field serialized"
151msgstr ""
152
153#. module: base_custom_attributes
154#: code:addons/base_custom_attributes/custom_attributes.py:44
155#, python-format
156msgid "Error!"
157msgstr ""
158
159#. module: base_custom_attributes
160#: view:attribute.option.wizard:0
161msgid "Validate"
162msgstr ""
163
164#. module: base_custom_attributes
165#: selection:attribute.attribute,attribute_type:0
166msgid "Multiselect"
167msgstr ""
168
169#. module: base_custom_attributes
170#: view:attribute.option:0
171msgid "Search Attribute Options"
172msgstr ""
173
174#. module: base_custom_attributes
175#: selection:attribute.attribute,attribute_type:0
176msgid "Integer"
177msgstr ""
178
179#. module: base_custom_attributes
180#: field:attribute.group,attribute_ids:0
181#: model:ir.actions.act_window,name:base_custom_attributes.attribute_attribute_form_action
182#: model:ir.model.fields,field_description:base_custom_attributes.field_attribute_group_attribute_ids
183#: model:ir.ui.menu,name:base_custom_attributes.menu_attribute_attribute_action
184#: model:ir.ui.menu,name:base_custom_attributes.menu_attribute_in_admin
185msgid "Attributes"
186msgstr ""
187
188#. module: base_custom_attributes
189#: field:attribute.attribute,relation_model_id:0
190#: field:attribute.group,model_id:0
191#: field:attribute.set,model_id:0
192#: model:ir.model.fields,field_description:base_custom_attributes.field_attribute_attribute_relation_model_id
193#: model:ir.model.fields,field_description:base_custom_attributes.field_attribute_group_model_id
194#: model:ir.model.fields,field_description:base_custom_attributes.field_attribute_set_model_id
195msgid "Model"
196msgstr ""
197
198#. module: base_custom_attributes
199#: model:ir.actions.act_window,name:base_custom_attributes.attribute_set_form_action
200#: model:ir.ui.menu,name:base_custom_attributes.menu_attribute_set_action
201msgid "Attribute Sets"
202msgstr ""
203
204#. module: base_custom_attributes
205#: view:attribute.attribute:0
206msgid "Load Options"
207msgstr ""
208
209#. module: base_custom_attributes
210#: field:attribute.option,value_ref:0
211#: model:ir.model.fields,field_description:base_custom_attributes.field_attribute_option_value_ref
212msgid "Reference"
213msgstr ""
214
215#. module: base_custom_attributes
216#: field:attribute.group,sequence:0
217#: field:attribute.location,sequence:0
218#: field:attribute.option,sequence:0
219#: model:ir.model.fields,field_description:base_custom_attributes.field_attribute_group_sequence
220#: model:ir.model.fields,field_description:base_custom_attributes.field_attribute_location_sequence
221#: model:ir.model.fields,field_description:base_custom_attributes.field_attribute_option_sequence
222msgid "Sequence"
223msgstr ""
224
225#. module: base_custom_attributes
226#: view:attribute.attribute:0
227#: field:attribute.location,attribute_id:0
228#: field:attribute.option,attribute_id:0
229#: field:attribute.option.wizard,attribute_id:0
230#: model:ir.model,name:base_custom_attributes.model_attribute_attribute
231#: model:ir.model.fields,field_description:base_custom_attributes.field_attribute_location_attribute_id
232#: model:ir.model.fields,field_description:base_custom_attributes.field_attribute_option_attribute_id
233#: model:ir.model.fields,field_description:base_custom_attributes.field_attribute_option_wizard_attribute_id
234msgid "Attribute"
235msgstr ""
236
237#. module: base_custom_attributes
238#: selection:attribute.attribute,attribute_type:0
239msgid "Float"
240msgstr ""
241
242#. module: base_custom_attributes
243#: field:attribute.group,attribute_set_id:0
244#: field:attribute.location,attribute_set_id:0
245#: view:attribute.set:0
246#: model:ir.model,name:base_custom_attributes.model_attribute_set
247#: model:ir.model.fields,field_description:base_custom_attributes.field_attribute_group_attribute_set_id
248#: model:ir.model.fields,field_description:base_custom_attributes.field_attribute_location_attribute_set_id
249msgid "Attribute Set"
250msgstr ""
251
252#. module: base_custom_attributes
253#: selection:attribute.attribute,attribute_type:0
254msgid "Datetime"
255msgstr ""
256
257#. module: base_custom_attributes
258#: selection:attribute.attribute,attribute_type:0
259msgid "Char"
260msgstr ""
261
262#. module: base_custom_attributes
263#: selection:attribute.attribute,attribute_type:0
264msgid "Boolean"
265msgstr ""
266
267#. module: base_custom_attributes
268#: selection:attribute.attribute,attribute_type:0
269msgid "Text"
270msgstr ""
271
272#. module: base_custom_attributes
273#: view:attribute.option.wizard:0
274msgid "Cancel"
275msgstr ""
276
277#. module: base_custom_attributes
278#: model:ir.model,name:base_custom_attributes.model_attribute_option_wizard
279msgid "attribute.option.wizard"
280msgstr ""
281
282#. module: base_custom_attributes
283#: sql_constraint:ir.model.fields:0
284msgid "The name of the field has to be uniq for a given model !"
285msgstr ""
286
287#. module: base_custom_attributes
288#: selection:attribute.attribute,attribute_type:0
289msgid "Select"
290msgstr ""
291
0292
=== added file 'base_custom_attributes/i18n/fr.po'
--- base_custom_attributes/i18n/fr.po 1970-01-01 00:00:00 +0000
+++ base_custom_attributes/i18n/fr.po 2013-12-11 14:54:36 +0000
@@ -0,0 +1,291 @@
1# Translation of OpenERP Server.
2# This file contains the translation of the following modules:
3# * base_custom_attributes
4#
5msgid ""
6msgstr ""
7"Project-Id-Version: OpenERP Server 7.0\n"
8"Report-Msgid-Bugs-To: \n"
9"POT-Creation-Date: 2013-10-16 09:03+0000\n"
10"PO-Revision-Date: 2013-10-16 09:03+0000\n"
11"Last-Translator: <>\n"
12"Language-Team: \n"
13"MIME-Version: 1.0\n"
14"Content-Type: text/plain; charset=UTF-8\n"
15"Content-Transfer-Encoding: \n"
16"Plural-Forms: \n"
17
18#. module: base_custom_attributes
19#: code:addons/base_custom_attributes/custom_attributes.py:44
20#, python-format
21msgid "Use the 'Load Options' button instead to select appropriate model references."
22msgstr "Utiliser le bouton 'Charger les options' pour sélectionner le modèle de référence approprié."
23
24#. module: base_custom_attributes
25#: selection:attribute.attribute,attribute_type:0
26msgid "Binary"
27msgstr "Binary"
28
29#. module: base_custom_attributes
30#: view:attribute.attribute:0
31msgid "Search Attributes"
32msgstr "Rechercher des attributs"
33
34#. module: base_custom_attributes
35#: view:attribute.group:0
36#: field:attribute.location,attribute_group_id:0
37#: model:ir.model,name:base_custom_attributes.model_attribute_group
38#: model:ir.model.fields,field_description:base_custom_attributes.field_attribute_location_attribute_group_id
39msgid "Attribute Group"
40msgstr "Groupe d'attributs"
41
42#. module: base_custom_attributes
43#: view:attribute.group:0
44#: model:ir.model,name:base_custom_attributes.model_attribute_location
45msgid "Attribute Location"
46msgstr "Attribute Location"
47
48#. module: base_custom_attributes
49#: code:addons/base_custom_attributes/custom_attributes.py:154
50#: view:attribute.option.wizard:0
51#, python-format
52msgid "Options Wizard"
53msgstr "Options Wizard"
54
55#. module: base_custom_attributes
56#: view:attribute.group:0
57msgid "Search Attribute Groups"
58msgstr "Rechercher des groupes d'attributs"
59
60#. module: base_custom_attributes
61#: field:attribute.attribute,attribute_type:0
62#: model:ir.model.fields,field_description:base_custom_attributes.field_attribute_attribute_attribute_type
63msgid "Type"
64msgstr "Type"
65
66#. module: base_custom_attributes
67#: field:attribute.set,attribute_group_ids:0
68#: model:ir.actions.act_window,name:base_custom_attributes.attribute_group_form_action
69#: model:ir.model.fields,field_description:base_custom_attributes.field_attribute_set_attribute_group_ids
70#: model:ir.ui.menu,name:base_custom_attributes.menu_attribute_group_action
71msgid "Attribute Groups"
72msgstr "Groupes d'attributs"
73
74#. module: base_custom_attributes
75#: field:attribute.attribute,create_date:0
76#: model:ir.model.fields,field_description:base_custom_attributes.field_attribute_attribute_create_date
77msgid "Created date"
78msgstr "Date de création"
79
80#. module: base_custom_attributes
81#: view:attribute.set:0
82msgid "Search Attribute Sets"
83msgstr "Rechercher des jeux d'attributs"
84
85#. module: base_custom_attributes
86#: view:attribute.option:0
87#: model:ir.model,name:base_custom_attributes.model_attribute_option
88msgid "Attribute Option"
89msgstr "Option d'attribut"
90
91#. module: base_custom_attributes
92#: selection:attribute.attribute,attribute_type:0
93msgid "Date"
94msgstr "Date"
95
96#. module: base_custom_attributes
97#: help:attribute.attribute,required_on_views:0
98msgid "If activated, the attribute will be mandatory on the views, but not in the database"
99msgstr "Si activé, l'attribut sera obligatoire dans les vues, mais pas dans la base de données."
100
101#. module: base_custom_attributes
102#: field:attribute.attribute,field_id:0
103#: model:ir.model.fields,field_description:base_custom_attributes.field_attribute_attribute_field_id
104msgid "Ir Model Fields"
105msgstr "Ir Model Fields"
106
107#. module: base_custom_attributes
108#: view:attribute.option.wizard:0
109msgid "options_placeholder"
110msgstr "options_placeholder"
111
112#. module: base_custom_attributes
113#: field:attribute.group,name:0
114#: field:attribute.option,name:0
115#: field:attribute.set,name:0
116#: model:ir.model.fields,field_description:base_custom_attributes.field_attribute_group_name
117#: model:ir.model.fields,field_description:base_custom_attributes.field_attribute_option_name
118#: model:ir.model.fields,field_description:base_custom_attributes.field_attribute_set_name
119msgid "Name"
120msgstr "Nom"
121
122#. module: base_custom_attributes
123#: help:attribute.attribute,serialized:0
124msgid "If serialized, the field will be stocked in the serialized field: attribute_custom_tmpl or attribute_custom_variant depending on the field based_on"
125msgstr "Si serialisé, le champ sera stocké dans un champ serialisé : attribute_custom_tmpl ou attribut_custom_variant selon la valeur du champ based_on"
126
127#. module: base_custom_attributes
128#: field:attribute.attribute,required_on_views:0
129#: model:ir.model.fields,field_description:base_custom_attributes.field_attribute_attribute_required_on_views
130msgid "Required (on views)"
131msgstr "Obligatoire (dans les vues)"
132
133#. module: base_custom_attributes
134#: model:ir.model,name:base_custom_attributes.model_ir_model_fields
135msgid "Fields"
136msgstr "Champs"
137
138#. module: base_custom_attributes
139#: view:attribute.attribute:0
140#: field:attribute.attribute,option_ids:0
141#: model:ir.actions.act_window,name:base_custom_attributes.attribute_option_form_action
142#: model:ir.model.fields,field_description:base_custom_attributes.field_attribute_attribute_option_ids
143#: model:ir.ui.menu,name:base_custom_attributes.menu_attribute_option_action
144msgid "Attribute Options"
145msgstr "Options d'attribut"
146
147#. module: base_custom_attributes
148#: field:attribute.attribute,serialized:0
149#: model:ir.model.fields,field_description:base_custom_attributes.field_attribute_attribute_serialized
150msgid "Field serialized"
151msgstr "Champ serialisé"
152
153#. module: base_custom_attributes
154#: code:addons/base_custom_attributes/custom_attributes.py:44
155#, python-format
156msgid "Error!"
157msgstr "Erreur !"
158
159#. module: base_custom_attributes
160#: view:attribute.option.wizard:0
161msgid "Validate"
162msgstr "Valider"
163
164#. module: base_custom_attributes
165#: selection:attribute.attribute,attribute_type:0
166msgid "Multiselect"
167msgstr "Multiselect"
168
169#. module: base_custom_attributes
170#: view:attribute.option:0
171msgid "Search Attribute Options"
172msgstr "Rechercher des options d'attribut"
173
174#. module: base_custom_attributes
175#: selection:attribute.attribute,attribute_type:0
176msgid "Integer"
177msgstr "Integer"
178
179#. module: base_custom_attributes
180#: field:attribute.group,attribute_ids:0
181#: model:ir.actions.act_window,name:base_custom_attributes.attribute_attribute_form_action
182#: model:ir.model.fields,field_description:base_custom_attributes.field_attribute_group_attribute_ids
183#: model:ir.ui.menu,name:base_custom_attributes.menu_attribute_attribute_action
184#: model:ir.ui.menu,name:base_custom_attributes.menu_attribute_in_admin
185msgid "Attributes"
186msgstr "Attributs"
187
188#. module: base_custom_attributes
189#: field:attribute.attribute,relation_model_id:0
190#: field:attribute.group,model_id:0
191#: field:attribute.set,model_id:0
192#: model:ir.model.fields,field_description:base_custom_attributes.field_attribute_attribute_relation_model_id
193#: model:ir.model.fields,field_description:base_custom_attributes.field_attribute_group_model_id
194#: model:ir.model.fields,field_description:base_custom_attributes.field_attribute_set_model_id
195msgid "Model"
196msgstr "Modèle"
197
198#. module: base_custom_attributes
199#: model:ir.actions.act_window,name:base_custom_attributes.attribute_set_form_action
200#: model:ir.ui.menu,name:base_custom_attributes.menu_attribute_set_action
201msgid "Attribute Sets"
202msgstr "Jeux d'attributs"
203
204#. module: base_custom_attributes
205#: view:attribute.attribute:0
206msgid "Load Options"
207msgstr "Charger les options"
208
209#. module: base_custom_attributes
210#: field:attribute.option,value_ref:0
211#: model:ir.model.fields,field_description:base_custom_attributes.field_attribute_option_value_ref
212msgid "Reference"
213msgstr "Référence"
214
215#. module: base_custom_attributes
216#: field:attribute.group,sequence:0
217#: field:attribute.location,sequence:0
218#: field:attribute.option,sequence:0
219#: model:ir.model.fields,field_description:base_custom_attributes.field_attribute_group_sequence
220#: model:ir.model.fields,field_description:base_custom_attributes.field_attribute_location_sequence
221#: model:ir.model.fields,field_description:base_custom_attributes.field_attribute_option_sequence
222msgid "Sequence"
223msgstr "Séquence"
224
225#. module: base_custom_attributes
226#: view:attribute.attribute:0
227#: field:attribute.location,attribute_id:0
228#: field:attribute.option,attribute_id:0
229#: field:attribute.option.wizard,attribute_id:0
230#: model:ir.model,name:base_custom_attributes.model_attribute_attribute
231#: model:ir.model.fields,field_description:base_custom_attributes.field_attribute_location_attribute_id
232#: model:ir.model.fields,field_description:base_custom_attributes.field_attribute_option_attribute_id
233#: model:ir.model.fields,field_description:base_custom_attributes.field_attribute_option_wizard_attribute_id
234msgid "Attribute"
235msgstr "Attribut"
236
237#. module: base_custom_attributes
238#: selection:attribute.attribute,attribute_type:0
239msgid "Float"
240msgstr "Float"
241
242#. module: base_custom_attributes
243#: field:attribute.group,attribute_set_id:0
244#: field:attribute.location,attribute_set_id:0
245#: view:attribute.set:0
246#: model:ir.model,name:base_custom_attributes.model_attribute_set
247#: model:ir.model.fields,field_description:base_custom_attributes.field_attribute_group_attribute_set_id
248#: model:ir.model.fields,field_description:base_custom_attributes.field_attribute_location_attribute_set_id
249msgid "Attribute Set"
250msgstr "Jeux d'attributs"
251
252#. module: base_custom_attributes
253#: selection:attribute.attribute,attribute_type:0
254msgid "Datetime"
255msgstr "Datetime"
256
257#. module: base_custom_attributes
258#: selection:attribute.attribute,attribute_type:0
259msgid "Char"
260msgstr "Char"
261
262#. module: base_custom_attributes
263#: selection:attribute.attribute,attribute_type:0
264msgid "Boolean"
265msgstr "Boolean"
266
267#. module: base_custom_attributes
268#: selection:attribute.attribute,attribute_type:0
269msgid "Text"
270msgstr "Text"
271
272#. module: base_custom_attributes
273#: view:attribute.option.wizard:0
274msgid "Cancel"
275msgstr "Annuler"
276
277#. module: base_custom_attributes
278#: model:ir.model,name:base_custom_attributes.model_attribute_option_wizard
279msgid "attribute.option.wizard"
280msgstr "attribute.option.wizard"
281
282#. module: base_custom_attributes
283#: sql_constraint:ir.model.fields:0
284msgid "The name of the field has to be uniq for a given model !"
285msgstr "Le nom du champ doit être unique pour un modèle donné !"
286
287#. module: base_custom_attributes
288#: selection:attribute.attribute,attribute_type:0
289msgid "Select"
290msgstr "Select"
291
0292
=== added file 'base_custom_attributes/ir_model.py'
--- base_custom_attributes/ir_model.py 1970-01-01 00:00:00 +0000
+++ base_custom_attributes/ir_model.py 2013-12-11 14:54:36 +0000
@@ -0,0 +1,39 @@
1# -*- encoding: utf-8 -*-
2###############################################################################
3# #
4# product_custom_attributes for OpenERP
5# Copyright (C) 2011 Akretion Benoît GUILLOT <benoit.guillot@akretion.com>
6# #
7# This program is free software: you can redistribute it and/or modify #
8# it under the terms of the GNU Affero General Public License as #
9# published by the Free Software Foundation, either version 3 of the #
10# License, or (at your option) any later version. #
11# #
12# This program is distributed in the hope that it will be useful, #
13# but WITHOUT ANY WARRANTY; without even the implied warranty of #
14# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
15# GNU Affero General Public License for more details. #
16# #
17# You should have received a copy of the GNU Affero General Public License #
18# along with this program. If not, see <http://www.gnu.org/licenses/>. #
19# #
20###############################################################################
21
22from openerp.osv.orm import Model
23from openerp.osv import fields
24
25
26class ir_model_fields(Model):
27
28 _inherit = "ir.model.fields"
29 _columns = {
30 'field_description': fields.char(
31 'Field Label',
32 required=True,
33 size=256,
34 translate=True),
35 }
36 _sql_constraints = [
37 ('name_model_uniq', 'unique (name, model_id)',
38 'The name of the field has to be uniq for a given model !'),
39 ]
040
=== added directory 'base_custom_attributes/security'
=== added file 'base_custom_attributes/security/attribute_security.xml'
--- base_custom_attributes/security/attribute_security.xml 1970-01-01 00:00:00 +0000
+++ base_custom_attributes/security/attribute_security.xml 2013-12-11 14:54:36 +0000
@@ -0,0 +1,11 @@
1<?xml version="1.0" encoding="utf-8"?>
2<openerp>
3<data noupdate="0">
4
5 <record id="base.group_advanced_attribute" model="res.groups">
6 <field name="name">Advanced Attribute Option</field>
7 <field name="category_id" ref="base.module_category_hidden"/>
8 </record>
9
10</data>
11</openerp>
012
=== added file 'base_custom_attributes/security/ir.model.access.csv'
--- base_custom_attributes/security/ir.model.access.csv 1970-01-01 00:00:00 +0000
+++ base_custom_attributes/security/ir.model.access.csv 2013-12-11 14:54:36 +0000
@@ -0,0 +1,13 @@
1id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
2access_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
3access_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
4access_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
5access_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
6access_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
7access_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
8access_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
9access_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
10access_base_custom_attributes_attribute_group_user,base_custom_attributes_attribute_group,base_custom_attributes.model_attribute_group,base.group_user,1,0,0,0
11access_base_custom_attributes_attribute_attribute_user,base_custom_attributes_attribute_attribute,base_custom_attributes.model_attribute_attribute,base.group_user,1,0,0,0
12access_base_custom_attributes_attribute_option_user,base_custom_attributes_attribute_option,base_custom_attributes.model_attribute_option,base.group_user,1,0,0,0
13access_base_custom_attributes_attribute_location_user,base_custom_attributes_attribute_location,base_custom_attributes.model_attribute_location,base.group_user,1,1,1,0
014
=== added directory 'production_lot_custom_attributes'
=== added file 'production_lot_custom_attributes/__init__.py'
--- production_lot_custom_attributes/__init__.py 1970-01-01 00:00:00 +0000
+++ production_lot_custom_attributes/__init__.py 2013-12-11 14:54:36 +0000
@@ -0,0 +1,25 @@
1# -*- coding: utf-8 -*-
2###############################################################################
3# #
4# Author: Leonardo Pistone <leonardo.pistone@camptocamp.com> #
5# Copyright 2013 Camptocamp SA #
6# #
7# Inspired by the module product_custom_attributes #
8# by Benoît GUILLOT <benoit.guillot@akretion.com>, Akretion #
9# #
10# This program is free software: you can redistribute it and/or modify #
11# it under the terms of the GNU Affero General Public License as #
12# published by the Free Software Foundation, either version 3 of the #
13# License, or (at your option) any later version. #
14# #
15# This program is distributed in the hope that it will be useful, #
16# but WITHOUT ANY WARRANTY; without even the implied warranty of #
17# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
18# GNU Affero General Public License for more details. #
19# #
20# You should have received a copy of the GNU Affero General Public License #
21# along with this program. If not, see <http://www.gnu.org/licenses/>. #
22# #
23###############################################################################
24from . import lot
25from . import wizard
026
=== added file 'production_lot_custom_attributes/__openerp__.py'
--- production_lot_custom_attributes/__openerp__.py 1970-01-01 00:00:00 +0000
+++ production_lot_custom_attributes/__openerp__.py 2013-12-11 14:54:36 +0000
@@ -0,0 +1,62 @@
1# -*- coding: utf-8 -*-
2###############################################################################
3# #
4# Author: Leonardo Pistone <leonardo.pistone@camptocamp.com> #
5# Copyright 2013 Camptocamp SA #
6# #
7# Inspired by the module product_custom_attributes #
8# by Benoît GUILLOT <benoit.guillot@akretion.com>, Akretion #
9# #
10# This program is free software: you can redistribute it and/or modify #
11# it under the terms of the GNU Affero General Public License as #
12# published by the Free Software Foundation, either version 3 of the #
13# License, or (at your option) any later version. #
14# #
15# This program is distributed in the hope that it will be useful, #
16# but WITHOUT ANY WARRANTY; without even the implied warranty of #
17# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
18# GNU Affero General Public License for more details. #
19# #
20# You should have received a copy of the GNU Affero General Public License #
21# along with this program. If not, see <http://www.gnu.org/licenses/>. #
22# #
23###############################################################################
24
25{'name': 'production_lot_custom_attributes',
26 'version': '0.1',
27 'category': 'Generic Modules/Others',
28 'license': 'AGPL-3',
29 'description': """
30Production lot custom attributes
31================================
32
33This module adds the possibility to easily create custom fields on stock
34production lots. Each lot can be linked to an attribute set.
35Each attribute has custom fields (for example, you don't need the same field
36for a frigde and a camera).
37In particular it's used by the Magento Magentoerpconnect module to match the
38EAV flexibility of Magento.
39
40Warning: This module is not compatible with product_custom_attributes from 6.1.
41To make the two compatible, product_custom_attributes should be split to depend
42from base_custom_attributes, like it is already in 7.0.
43
44This module is inspired by the module product_custom_attributes by
45Benoît GUILLOT, Akretion
46
47""",
48 'complexity': 'normal',
49 'author': 'Camptocamp',
50 'website': 'http://www.camptocamp.com/',
51 'depends': ['stock', 'base_custom_attributes'],
52 'init_xml': [],
53 'update_xml': ['lot_view.xml',
54 'custom_attributes_view.xml',
55 'wizard/open_lot_by_attribute_set.xml'
56 ],
57 'test': ['test/lot_attribute_test.yml',
58 ],
59 'demo_xml': [],
60 'installable': True,
61 'active': False,
62 }
063
=== added file 'production_lot_custom_attributes/custom_attributes_view.xml'
--- production_lot_custom_attributes/custom_attributes_view.xml 1970-01-01 00:00:00 +0000
+++ production_lot_custom_attributes/custom_attributes_view.xml 2013-12-11 14:54:36 +0000
@@ -0,0 +1,58 @@
1<?xml version="1.0" encoding="utf-8"?>
2<openerp>
3 <data>
4
5 <menuitem
6 id="menu_lot_attribute_in_warehouse_config"
7 name="Serial Number Attributes"
8 parent="stock.menu_warehouse_config"
9 sequence="20"/>
10
11 <record id="lot_attribute_set_form_action" model="ir.actions.act_window">
12 <field name="name">Lot Attribute Sets</field>
13 <field name="res_model">attribute.set</field>
14 <field name="view_type">form</field>
15 <field name="view_mode">tree,form</field>
16 <field name="search_view_id" ref="base_custom_attributes.view_attribute_set_search"/>
17 <field name="context">{"force_model": 'stock.production.lot'}</field>
18 <field name="help"></field>
19 </record>
20
21 <record id="lot_attribute_group_form_action" model="ir.actions.act_window">
22 <field name="name">Attribute Groups</field>
23 <field name="res_model">attribute.group</field>
24 <field name="view_type">form</field>
25 <field name="view_mode">tree,form</field>
26 <field name="search_view_id" ref="base_custom_attributes.view_attribute_attribute_search"/>
27 <field name="context">{"force_model": 'stock.production.lot'}</field>
28 <field name="help"></field>
29 </record>
30
31 <record id="lot_attribute_attribute_form_action" model="ir.actions.act_window">
32 <field name="name">Lot Attributes</field>
33 <field name="res_model">attribute.attribute</field>
34 <field name="view_type">form</field>
35 <field name="view_mode">tree,form</field>
36 <field name="search_view_id" ref="base_custom_attributes.view_attribute_attribute_search"/>
37 <field name="context">{"force_model": 'stock.production.lot'}</field>
38 <field name="help"></field>
39 </record>
40
41 <menuitem
42 action="lot_attribute_set_form_action"
43 id="menu_lot_attribute_set_action"
44 parent="menu_lot_attribute_in_warehouse_config"
45 sequence="1"/>
46 <menuitem
47 action="lot_attribute_group_form_action"
48 id="menu_lot_attribute_group_action"
49 parent="menu_lot_attribute_in_warehouse_config"
50 sequence="2"/>
51 <menuitem
52 action="lot_attribute_attribute_form_action"
53 id="menu_lot_attribute_attribute_action"
54 parent="menu_lot_attribute_in_warehouse_config"
55 sequence="4"/>
56
57 </data>
58</openerp>
059
=== added file 'production_lot_custom_attributes/lot.py'
--- production_lot_custom_attributes/lot.py 1970-01-01 00:00:00 +0000
+++ production_lot_custom_attributes/lot.py 2013-12-11 14:54:36 +0000
@@ -0,0 +1,207 @@
1# -*- coding: utf-8 -*-
2###############################################################################
3# #
4# Author: Leonardo Pistone <leonardo.pistone@camptocamp.com> #
5# Copyright 2013 Camptocamp SA #
6# #
7# Inspired by the module product_custom_attributes #
8# by Benoît GUILLOT <benoit.guillot@akretion.com>, Akretion #
9# #
10# This program is free software: you can redistribute it and/or modify #
11# it under the terms of the GNU Affero General Public License as #
12# published by the Free Software Foundation, either version 3 of the #
13# License, or (at your option) any later version. #
14# #
15# This program is distributed in the hope that it will be useful, #
16# but WITHOUT ANY WARRANTY; without even the implied warranty of #
17# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
18# GNU Affero General Public License for more details. #
19# #
20# You should have received a copy of the GNU Affero General Public License #
21# along with this program. If not, see <http://www.gnu.org/licenses/>. #
22# #
23###############################################################################
24
25from openerp.osv import fields, osv
26from tools.translate import _
27from lxml import etree
28import re
29
30
31class stock_production_lot(osv.Model):
32 _inherit = "stock.production.lot"
33
34 def _search_all_attributes(self, cr, uid, obj, name, args, context):
35 """Search in all serialized attributes
36
37 Receives a domain in args, and expands all relevant terms into ids
38 to search into all attributes. The ORM will take care of security
39 afterwards, so it' OK to use SQL here.
40
41 In the future, we could consider storing attributes as native PostgreSQL
42 hstore or JSON instead of strings, and substitute this rough regexp
43 search with native PostgreSQL goodness.
44
45 """
46
47 def expand_arg(arg):
48 """Takes a single argument of the domain, and when possible expands
49 it to a trivial domain ('in', 'in', list)
50
51 """
52 if isinstance(arg, tuple) and arg[0] == name:
53 if arg[1] == 'like':
54 operator = '~'
55 elif arg[1] == 'ilike':
56 operator = '~*'
57 else:
58 raise osv.except_osv(
59 _('Not Implemented!'),
60 _('Search not supported for this field'))
61
62 cr.execute(
63 """
64 select id
65 from {0}
66 where x_custom_json_attrs {1} %s;
67 """.format(
68 self._table,
69 operator
70 ),
71 (ur'.*: "[^"]*%s' % re.escape(arg[2]) ,)
72 )
73 sql_ids = [line[0] for line in cr.fetchall()]
74 return ('id', 'in', sql_ids)
75 else:
76 return arg
77
78 return [expand_arg(arg) for arg in args]
79
80 _columns = {
81 'attribute_set_id': fields.many2one('attribute.set', 'Attribute Set'),
82 'attribute_group_ids': fields.related(
83 'attribute_set_id',
84 'attribute_group_ids',
85 type='many2many',
86 relation='attribute.group'
87 ),
88 'search_all_attributes': fields.function(
89 lambda self, cr, uid, ids, field, args, context: u'',
90 type="char",
91 fnct_search=_search_all_attributes,
92 method=True,
93 string="Search all Attributes"),
94 }
95
96 def _fix_size_bug(self, cr, uid, result, context=None):
97 """When created a field text dynamicaly, its size is limited to 64 in
98 the view. The bug is fixed but not merged
99 https://code.launchpad.net/~openerp-dev/openerp-web/6.1-opw-579462-cpa
100 To remove when the fix will be merged
101
102 """
103 for field in result['fields']:
104 if result['fields'][field]['type'] == 'text':
105 if 'size' in result['fields'][field]:
106 del result['fields'][field]['size']
107 return result
108
109 def open_attributes(self, cr, uid, ids, context=None):
110 """Open the attributes of an object
111
112 This method is called when the user presses the Open Attributes button
113 in the form view of the object. It opens a dinamically-built form view.
114
115 :param ids: this is normally a singleton. If a longer list is passed,
116 we consider only the first item.
117
118 """
119
120 if context is None:
121 context = {}
122
123 model_data_pool = self.pool.get('ir.model.data')
124
125 for lot in self.browse(cr, uid, ids, context=context):
126 view_id = model_data_pool.get_object_reference(
127 cr, uid,
128 'production_lot_custom_attributes',
129 'lot_attributes_form_view')[1]
130 ctx = {
131 'open_attributes': True,
132 'attribute_group_ids': [
133 group.id for group in lot.attribute_group_ids
134 ]
135 }
136
137 return {
138 'name': 'Lot Attributes',
139 'view_type': 'form',
140 'view_mode': 'form',
141 'view_id': [view_id],
142 'res_model': self._name,
143 'context': ctx,
144 'type': 'ir.actions.act_window',
145 'nodestroy': True,
146 'target': 'new',
147 'res_id': lot.id,
148 }
149
150 def save_and_close_lot_attributes(self, cr, uid, ids, context=None):
151 return {'type': 'ir.actions.act_window_close'}
152
153 def fields_view_get(self, cr, uid, view_id=None, view_type='form',
154 context=None, toolbar=False, submenu=False):
155 """Dinamically adds attributes to the view
156
157 Modifies dinamically the view to show the attributes. If the users
158 presses the Open Attributes button, the attributes are shown in a
159 new form field. Otherwise, if the attribute set is known beforehand,
160 attributes are added to a new tab in the main form view.
161
162 """
163 if context is None:
164 context = {}
165 attr_pool = self.pool.get('attribute.attribute')
166 result = super(stock_production_lot, self).fields_view_get(
167 cr, uid, view_id, view_type, context, toolbar=toolbar,
168 submenu=submenu
169 )
170 if view_type == 'form' and context.get('attribute_group_ids'):
171 eview = etree.fromstring(result['arch'])
172 #hide button under the name
173 button = eview.xpath("//button[@name='open_attributes']")
174 if button:
175 button = button[0]
176 button.getparent().remove(button)
177 attributes_notebook, toupdate_fields = (
178 attr_pool._build_attributes_notebook(
179 cr, uid, context['attribute_group_ids'], context=context
180 )
181 )
182 result['fields'].update(
183 self.fields_get(cr, uid, toupdate_fields, context)
184 )
185 if context.get('open_attributes'):
186 # i.e. the user pressed the open attributes button on the
187 # form view. We put the attributes in a separate form view
188 placeholder = eview.xpath(
189 "//separator[@string='attributes_placeholder']"
190 )[0]
191 placeholder.getparent().replace(
192 placeholder, attributes_notebook
193 )
194 elif context.get('open_lot_by_attribute_set'):
195 # in this case, we know the attribute set beforehand, and we
196 # add the attributes to the current view
197 main_page = etree.Element(
198 'page', string=_('Custom Attributes')
199 )
200 main_page.append(attributes_notebook)
201 info_page = eview.xpath(
202 "//page[@string='%s']" % (_('Stock Moves'),)
203 )[0]
204 info_page.addnext(main_page)
205 result['arch'] = etree.tostring(eview, pretty_print=True)
206 result = self._fix_size_bug(cr, uid, result, context=context)
207 return result
0208
=== added file 'production_lot_custom_attributes/lot_view.xml'
--- production_lot_custom_attributes/lot_view.xml 1970-01-01 00:00:00 +0000
+++ production_lot_custom_attributes/lot_view.xml 2013-12-11 14:54:36 +0000
@@ -0,0 +1,52 @@
1<?xml version="1.0" encoding="utf-8"?>
2
3<openerp>
4 <data>
5
6 <record model="ir.ui.view" id="lot_form_view_set_button">
7 <field name="name">attributes.lot.normal.form</field>
8 <field name="model">stock.production.lot</field>
9 <field name="inherit_id" ref="stock.view_production_lot_form"/>
10 <field name="arch" type="xml">
11 <notebook position="inside">
12 <page string="Attributes">
13 <group name="attribute_fields">
14 <field name="attribute_set_id" />
15 <button name="open_attributes" string="Open Attributes" type="object" icon="gtk-ok" attrs="{'invisible':[('attribute_set_id', '=', False)]}"/>
16 </group>
17 </page>
18 </notebook>
19 </field>
20 </record>
21
22 <record model="ir.ui.view" id="search_product_lot_filter">
23 <field name="model">stock.production.lot</field>
24 <field name="inherit_id" ref="stock.search_product_lot_filter"/>
25 <field name="arch" type="xml">
26 <field name="date" position="after">
27 <field name="search_all_attributes"/>
28 </field>
29 </field>
30 </record>
31
32 <record model="ir.ui.view" id="lot_attributes_form_view">
33 <field name="name">lot.attributes.normal.wizard</field>
34 <field name="model">stock.production.lot</field>
35 <field name="priority">20</field>
36 <field name="arch" type="xml">
37 <form string="Lot">
38 <group name="name_set" colspan='4' col='8'>
39 <field name="name"/>
40 <field name="attribute_set_id" />
41 </group>
42 <separator string="attributes_placeholder" colspan="4"/>
43 <group colspan='4' col='4'>
44 <button icon="gtk-cancel" special="cancel" string="Cancel"/>
45 <button icon="gtk-ok" name="save_and_close_lot_attributes" string="Save and Close" type="object"/>
46 </group>
47 </form>
48 </field>
49 </record>
50
51 </data>
52</openerp>
053
=== added directory 'production_lot_custom_attributes/test'
=== added file 'production_lot_custom_attributes/test/lot_attribute_test.yml'
--- production_lot_custom_attributes/test/lot_attribute_test.yml 1970-01-01 00:00:00 +0000
+++ production_lot_custom_attributes/test/lot_attribute_test.yml 2013-12-11 14:54:36 +0000
@@ -0,0 +1,48 @@
1-
2 In order to test Production Lot Custom Fields
3-
4 First I create an Attribute Set
5-
6 !record {model: attribute.set, id: lot_attribute_set_A}:
7 name: Serial Number Attribute Set A
8 model_id: stock.model_stock_production_lot
9 attribute_group_ids:
10 - name: Components
11 model_id: stock.model_stock_production_lot
12 sequence: 1
13 attribute_ids:
14 - name: x_ram_amount
15 model_id: stock.model_stock_production_lot
16 field_description: Amount of RAM
17 attribute_type: float
18 - name: x_has_display
19 model_id: stock.model_stock_production_lot
20 field_description: Has Display
21 attribute_type: boolean
22 - name: Characteristics
23 model_id: stock.model_stock_production_lot
24 sequence: 2
25 attribute_ids:
26 - name: x_color
27 model_id: stock.model_stock_production_lot
28 field_description: Color
29 attribute_type: char
30 - name: x_length
31 model_id: stock.model_stock_production_lot
32 field_description: Length
33 attribute_type: float
34-
35 Then I create a Serial Number and set some Attributes
36-
37 !record {model: stock.production.lot, id: lot_A}:
38 product_id: product.product_product_pc2
39 name: 0005
40 attribute_set_id: lot_attribute_set_A
41 x_color: green
42 x_length: 12.5
43-
44 Now I check that my attributes are there
45-
46 !assert {model: stock.production.lot, id: lot_A, string: Lot Attributes do not work}:
47 - x_color == 'green'
48 - x_length == 12.5
049
=== added directory 'production_lot_custom_attributes/wizard'
=== added file 'production_lot_custom_attributes/wizard/__init__.py'
--- production_lot_custom_attributes/wizard/__init__.py 1970-01-01 00:00:00 +0000
+++ production_lot_custom_attributes/wizard/__init__.py 2013-12-11 14:54:36 +0000
@@ -0,0 +1,25 @@
1# -*- coding: utf-8 -*-
2###############################################################################
3# #
4# Author: Leonardo Pistone <leonardo.pistone@camptocamp.com> #
5# Copyright 2013 Camptocamp SA #
6# #
7# Inspired by the module product_custom_attributes #
8# by Benoît GUILLOT <benoit.guillot@akretion.com>, Akretion #
9# #
10# This program is free software: you can redistribute it and/or modify #
11# it under the terms of the GNU Affero General Public License as #
12# published by the Free Software Foundation, either version 3 of the #
13# License, or (at your option) any later version. #
14# #
15# This program is distributed in the hope that it will be useful, #
16# but WITHOUT ANY WARRANTY; without even the implied warranty of #
17# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
18# GNU Affero General Public License for more details. #
19# #
20# You should have received a copy of the GNU Affero General Public License #
21# along with this program. If not, see <http://www.gnu.org/licenses/>. #
22# #
23###############################################################################
24
25from . import open_lot_by_attribute_set
026
=== added file 'production_lot_custom_attributes/wizard/open_lot_by_attribute_set.py'
--- production_lot_custom_attributes/wizard/open_lot_by_attribute_set.py 1970-01-01 00:00:00 +0000
+++ production_lot_custom_attributes/wizard/open_lot_by_attribute_set.py 2013-12-11 14:54:36 +0000
@@ -0,0 +1,67 @@
1# -*- coding: utf-8 -*-
2###############################################################################
3# #
4# Author: Leonardo Pistone <leonardo.pistone@camptocamp.com> #
5# Copyright 2013 Camptocamp SA #
6# #
7# This program is free software: you can redistribute it and/or modify #
8# it under the terms of the GNU Affero General Public License as #
9# published by the Free Software Foundation, either version 3 of the #
10# License, or (at your option) any later version. #
11# #
12# This program is distributed in the hope that it will be useful, #
13# but WITHOUT ANY WARRANTY; without even the implied warranty of #
14# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
15# GNU Affero General Public License for more details. #
16# #
17# You should have received a copy of the GNU Affero General Public License #
18# along with this program. If not, see <http://www.gnu.org/licenses/>. #
19# #
20###############################################################################
21
22from openerp.osv.orm import TransientModel
23from osv import fields
24
25
26class open_lot_by_attribute_set(TransientModel):
27 _name = 'open.lot.by.attribute.set'
28 _description = 'Wizard to open lots by attributes set'
29
30 _columns = {
31 'attribute_set_id': fields.many2one('attribute.set', 'Attribute Set'),
32 }
33
34 def open_lot_by_attribute(self, cr, uid, ids, context=None):
35 """Opens a lot by attributes
36
37 Returns a custom action built modifying the original one.
38 """
39
40 mod_obj = self.pool.get('ir.model.data')
41 act_obj = self.pool.get('ir.actions.act_window')
42
43 if context is None:
44 context = {}
45
46 # we expect one wizard instance at a time
47 for wiz in self.browse(cr, uid, ids, context=context):
48 action_id = mod_obj.get_object_reference(
49 cr, uid, 'stock', 'action_production_lot_form')[1]
50 action = act_obj.read(cr, uid, [action_id], context=context)[0]
51
52 ctx = (
53 "{'open_lot_by_attribute_set': True, "
54 "'attribute_group_ids': %s}"
55 % [
56 group.id
57 for group in wiz.attribute_set_id.attribute_group_ids
58 ]
59 )
60
61 action['context'] = ctx
62 action['domain'] = (
63 "[('attribute_set_id', '=', %s)]"
64 % wiz.attribute_set_id.id
65 )
66 action['name'] = wiz.attribute_set_id.name
67 return action
068
=== added file 'production_lot_custom_attributes/wizard/open_lot_by_attribute_set.xml'
--- production_lot_custom_attributes/wizard/open_lot_by_attribute_set.xml 1970-01-01 00:00:00 +0000
+++ production_lot_custom_attributes/wizard/open_lot_by_attribute_set.xml 2013-12-11 14:54:36 +0000
@@ -0,0 +1,30 @@
1<?xml version="1.0" encoding="utf-8"?>
2
3<openerp>
4 <data>
5
6 <record id="open_lot_by_attribute_set_view" model="ir.ui.view">
7 <field name="name">open.lot.by.attribute.set.view</field>
8 <field name="model">open.lot.by.attribute.set</field>
9 <field name="arch" type="xml">
10 <form string="Open lot by attributes set">
11 <field name="attribute_set_id" colspan="4"/>
12 <button icon="gtk-cancel" special="cancel" string="Cancel"/>
13 <button icon="gtk-ok" name="open_lot_by_attribute" string="Open Product By attribute" type="object"/>
14 </form>
15 </field>
16 </record>
17
18 <record id="open_lot_by_attribute_set" model="ir.actions.act_window">
19 <field name="name">Open lot By Attribute Set</field>
20 <field name="res_model">open.lot.by.attribute.set</field>
21 <field name="view_type">form</field>
22 <field name="target">new</field>
23 <field name="view_id" ref="open_lot_by_attribute_set_view"/>
24 <field name="help"></field>
25 </record>
26
27 <menuitem action="open_lot_by_attribute_set" id="open_lot_wizard" parent="stock.menu_traceability"/>
28
29 </data>
30</openerp>

Subscribers

People subscribed via source and target branches