Merge lp:~camptocamp/openerp-product-attributes/7.0-product_images-migr into lp:~product-core-editors/openerp-product-attributes/7.0
- 7.0-product_images-migr
- Merge into 7.0
Status: | Merged |
---|---|
Merged at revision: | 200 |
Proposed branch: | lp:~camptocamp/openerp-product-attributes/7.0-product_images-migr |
Merge into: | lp:~product-core-editors/openerp-product-attributes/7.0 |
Prerequisite: | lp:~camptocamp/openerp-product-attributes/7.0-product_sequence-migr |
Diff against target: |
636 lines (+199/-158) 10 files modified
product_images/__init__.py (+1/-0) product_images/__openerp__.py (+9/-10) product_images/company.py (+12/-10) product_images/product.py (+26/-21) product_images/product_images.py (+49/-34) product_images/views/company_view.xml (+5/-5) product_images/views/product_images_view.xml (+55/-52) product_sequence/__openerp__.py (+4/-6) product_sequence/product_product.py (+36/-19) product_sequence/product_sequence.xml (+2/-1) |
To merge this branch: | bzr merge lp:~camptocamp/openerp-product-attributes/7.0-product_images-migr |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Alexandre Fayolle - camptocamp | Approve | ||
Guewen Baconnier @ Camptocamp | Pending | ||
Review via email: mp+145630@code.launchpad.net |
Commit message
[MIGR] migration of product_images (previously product_
Description of the change
Migration of product_sequence to openerp 7.0
* updated manifest (version, 'data' key, installable, category)
* formatting and pep8
* replaced 'encoding: utf-8' by 'coding: utf-8'
* fixed the views which where not displayed correctly
* fixed the image widget which was not working (the <field> should be in a <group>)
* renamed the field 'extention' to 'extension'
Prerequisite merge for this branch: https:/
Guewen Baconnier @ Camptocamp (gbaconnier-c2c) wrote : | # |
Raphaël Valyi - http://www.akretion.com (rvalyi) wrote : | # |
Hello guys,
we are double working here, Renato already did part of that work 2 weeks ago:
http://
That being said, that merge is probably better, but it's just sad we are splitting efforts because of these two branches.
That would be cool if you could see with Sebastien to decide what should be done about these conflicting branches. Is your branch a perfect replacement of Sebastien branch? have all commit from Sebastien been propagated to that branch?
As for improving the product_images module, In my opinion, the idea would be to have the image file created by the same code that create OpenERP standard attachments in the file-system.
Regards.
Guewen Baconnier @ Camptocamp (gbaconnier-c2c) wrote : | # |
Hello,
> we are double working here, Renato already did part of that work 2 weeks ago:
> http://
> addons/
The diff in your link was already there in the branch when I did my migration (the branch is as recent as the Sebastien one), so I don't think we worked double. Anyway, thanks for pointing that out because that's always a frustration when such things happen.
> That would be cool if you could see with Sebastien to decide what should be
> done about these conflicting branches. Is your branch a perfect replacement of
> Sebastien branch? have all commit from Sebastien been propagated to that
> branch?
We discussed with Sebastien and the sitation is clear about those 2 branches. He agreed to move the modules in this branch.
The branch is a perfect replacement of the Sebastien's branch, all commits are there.
he's aware that the modules have been moved and he confirmed me that he will remove the modules from his branch.
I'll ping him again about that.
Alexandre Fayolle - camptocamp (alexandre-fayolle-c2c) wrote : | # |
version in __openerp__.py : I'm not too fond of Sébastien's choice of using 6.1.0 in other related modules. I'd rather have a normal increment here.
s/add images against/add images to/
in field description:
s/Local mounted path on OpenERP server wheree all your images are stored./Local directory on the OpenERP server where all images are stored/
s/add the posibility/add the possibility/
there are lots of vals.get('name', False) used as truth values, which can be rewritten asn vals.get('name').
line 252: vals['name'] and vals['extension'] are garanteed to exist here, so no need to use the get method. Possibly the case later in the write method.
Sébastien BEAU - http://www.akretion.com (sebastien.beau) wrote : | # |
Alexandre yes your right, I did a mistake on number version.
I don't use anymore this version number now. Only two digit is the correct way.
See you
- 203. By Guewen Baconnier @ Camptocamp
-
[FIX] phrasing, typo
- 204. By Guewen Baconnier @ Camptocamp
-
[FIX] remove useless default values in get()
- 205. By Guewen Baconnier @ Camptocamp
-
[FIX] increment version instead of openerp version
Guewen Baconnier @ Camptocamp (gbaconnier-c2c) wrote : | # |
Updated the proposal taking into account your comments.
Still, I don't see cases where we are garanteed that 'name' and 'extension' are in the vals.
When we do a create(), we are able to call it without any of them ('name' is mandatory, so the call to super() will raise an exception, but it should not crash because of the key error).
When we do a write(), we can call it without a 'name' or an 'extension' or any of them.
Alexandre Fayolle - camptocamp (alexandre-fayolle-c2c) wrote : | # |
you are right
Preview Diff
1 | === modified file 'product_images/__init__.py' |
2 | --- product_images/__init__.py 2011-11-17 17:48:39 +0000 |
3 | +++ product_images/__init__.py 2013-01-31 07:04:20 +0000 |
4 | @@ -1,3 +1,4 @@ |
5 | +# -*- coding: utf-8 -*- |
6 | ######################################################################### |
7 | # Copyright (C) 2009 Sharoon Thomas Open Labs Business Solutions # |
8 | # # |
9 | |
10 | === modified file 'product_images/__openerp__.py' |
11 | --- product_images/__openerp__.py 2013-01-21 06:49:06 +0000 |
12 | +++ product_images/__openerp__.py 2013-01-31 07:04:20 +0000 |
13 | @@ -1,3 +1,4 @@ |
14 | +# -*- coding: utf-8 -*- |
15 | ######################################################################### |
16 | # Copyright (C) 2009 Sharoon Thomas, Open Labs Business solutions # |
17 | # Copyright (C) 2012-Today Akretion www.akretion.com # |
18 | @@ -19,26 +20,24 @@ |
19 | |
20 | { |
21 | "name" : "Product Image Gallery", |
22 | - "version" : "0.1 ", |
23 | + "version" : "0.2", |
24 | "author" : "Sharoon Thomas, Open Labs Business Solutions, Akretion", |
25 | "website" : "http://openlabs.co.in/", |
26 | - "category" : "Added functionality - Product Extension", |
27 | + "category" : "Generic Modules", |
28 | "depends" : ['product_sequence'], |
29 | "description": """ |
30 | - This Module implements an Image Gallery for products. |
31 | - You can add images against every product. |
32 | +This Module implements an Image Gallery for products. |
33 | +You can add images to every product. |
34 | |
35 | - This module is generic but built for Magento ERP connector and |
36 | - the upcoming e-commerce system for Open ERP by Open Labs |
37 | +This module is generic but built for Magento ERP connector and |
38 | +the upcoming e-commerce system for Open ERP by Open Labs |
39 | """, |
40 | - "init_xml": [], |
41 | - "update_xml": [ |
42 | + "data": [ |
43 | 'security/ir.model.access.csv', |
44 | 'views/product_images_view.xml', |
45 | 'views/company_view.xml' |
46 | ], |
47 | - 'installable': False, |
48 | + 'installable': True, |
49 | "active": False, |
50 | } |
51 | - |
52 | # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: |
53 | |
54 | === modified file 'product_images/company.py' |
55 | --- product_images/company.py 2012-08-21 14:10:21 +0000 |
56 | +++ product_images/company.py 2013-01-31 07:04:20 +0000 |
57 | @@ -1,4 +1,4 @@ |
58 | -# -*- encoding: utf-8 -*- |
59 | +# -*- coding: utf-8 -*- |
60 | ############################################################################## |
61 | # |
62 | # Author Nicolas Bessi & Guewen Baconnier. Copyright Camptocamp SA |
63 | @@ -18,21 +18,23 @@ |
64 | # |
65 | ############################################################################## |
66 | |
67 | -from openerp.osv.orm import Model |
68 | -from openerp.osv import fields |
69 | - |
70 | -class ResCompany(Model): |
71 | +from openerp.osv import orm, fields |
72 | + |
73 | + |
74 | +class ResCompany(orm.Model): |
75 | """Override company to add images configuration""" |
76 | _inherit = "res.company" |
77 | _columns = { |
78 | - 'local_media_repository':fields.char( |
79 | - 'Images Repository Path', |
80 | - size=256, |
81 | - help='Local mounted path on OpenERP server where all your images are stored.' |
82 | - ), |
83 | + 'local_media_repository': fields.char( |
84 | + 'Images Repository Path', |
85 | + help='Local directory on the OpenERP server ' |
86 | + 'where all images are stored.'), |
87 | } |
88 | |
89 | def get_local_media_repository(self, cr, uid, id=None, context=None): |
90 | + if isinstance(id, (tuple, list)): |
91 | + assert len(id) == 1, "One ID expected" |
92 | + id = id[0] |
93 | if id: |
94 | return self.browse(cr, uid, id, context=context).local_media_repository |
95 | user = self.pool.get('res.users').browse(cr, uid, uid, context=context) |
96 | |
97 | === modified file 'product_images/product.py' |
98 | --- product_images/product.py 2012-08-21 14:10:21 +0000 |
99 | +++ product_images/product.py 2013-01-31 07:04:20 +0000 |
100 | @@ -1,4 +1,4 @@ |
101 | -# -*- encoding: utf-8 -*- |
102 | +# -*- coding: utf-8 -*- |
103 | ######################################################################### |
104 | # Copyright (C) 2009 Sharoon Thomas, Open Labs Business solutions # |
105 | # Copyright (C) 2011 Akretion Sébastien BEAU sebastien.beau@akretion.com# |
106 | @@ -19,12 +19,13 @@ |
107 | import os |
108 | import shutil |
109 | import logging |
110 | -import base64, urllib |
111 | - |
112 | -from openerp.osv.orm import Model |
113 | -from openerp.osv import fields |
114 | - |
115 | -class product_product(Model): |
116 | +import base64 |
117 | +import urllib |
118 | + |
119 | +from openerp.osv import orm, fields |
120 | + |
121 | + |
122 | +class product_product(orm.Model): |
123 | _inherit = "product.product" |
124 | |
125 | def copy(self, cr, uid, id, default=None, context=None): |
126 | @@ -43,7 +44,10 @@ |
127 | shutil.copytree(old_path, old_path + '-copy') |
128 | except: |
129 | logger = logging.getLogger('product_images_olbs') |
130 | - logger.exception('error while trying to copy images from %s to %s', old_path, old_path+'.copy') |
131 | + logger.exception('error while trying to copy images ' |
132 | + 'from %s to %s', |
133 | + old_path, |
134 | + old_path + '.copy') |
135 | |
136 | return super(product_product, self).copy(cr, uid, id, default, context=context) |
137 | |
138 | @@ -68,19 +72,21 @@ |
139 | return res |
140 | |
141 | _columns = { |
142 | - 'image_ids':fields.one2many( |
143 | + 'image_ids': fields.one2many( |
144 | 'product.images', |
145 | 'product_id', |
146 | - 'Product Images' |
147 | - ), |
148 | - 'product_image': fields.function(_get_main_image, type="binary", method=True), |
149 | + string='Product Images'), |
150 | + 'product_image': fields.function( |
151 | + _get_main_image, |
152 | + type="binary", |
153 | + string="Main Image"), |
154 | } |
155 | |
156 | def write(self, cr, uid, ids, vals, context=None): |
157 | if isinstance(ids, (int, long)): |
158 | ids = [ids] |
159 | # here we expect that the write on default_code is always on 1 product because there is an unique constraint on the default code |
160 | - if vals.get('default_code', False) and ids: |
161 | + if vals.get('default_code') and ids: |
162 | local_media_repository = self.pool.get('res.company').get_local_media_repository(cr, uid, context=context) |
163 | if local_media_repository: |
164 | old_product = self.read(cr, uid, ids[0], ['default_code', 'image_ids'], context=context) |
165 | @@ -95,15 +101,14 @@ |
166 | |
167 | def create_image_from_url(self, cr, uid, id, url, image_name=None, context=None): |
168 | (filename, header) = urllib.urlretrieve(url) |
169 | - f = open(filename , 'rb') |
170 | - data = f.read() |
171 | - f.close() |
172 | + with open(filename, 'rb') as f: |
173 | + data = f.read() |
174 | img = base64.encodestring(data) |
175 | - filename, extention = os.path.splitext(os.path.basename(url)) |
176 | + filename, extension = os.path.splitext(os.path.basename(url)) |
177 | data = {'name': image_name or filename, |
178 | - 'extention': extention, |
179 | - 'file': img, |
180 | - 'product_id': id, |
181 | - } |
182 | + 'extension': extension, |
183 | + 'file': img, |
184 | + 'product_id': id, |
185 | + } |
186 | new_image_id = self.pool.get('product.images').create(cr, uid, data, context=context) |
187 | return True |
188 | |
189 | === modified file 'product_images/product_images.py' |
190 | --- product_images/product_images.py 2012-12-09 15:51:15 +0000 |
191 | +++ product_images/product_images.py 2013-01-31 07:04:20 +0000 |
192 | @@ -1,4 +1,4 @@ |
193 | -# -*- encoding: utf-8 -*- |
194 | +# -*- coding: utf-8 -*- |
195 | ######################################################################### |
196 | # Copyright (C) 2009 Sharoon Thomas, Open Labs Business solutions # |
197 | # Copyright (C) 2011 Akretion Sébastien BEAU sebastien.beau@akretion.com# |
198 | @@ -16,24 +16,25 @@ |
199 | #You should have received a copy of the GNU General Public License # |
200 | #along with this program. If not, see <http://www.gnu.org/licenses/>. # |
201 | ######################################################################### |
202 | -from openerp.osv.orm import Model |
203 | -from openerp.osv import fields |
204 | -from openerp.osv.osv import except_osv |
205 | -import base64, urllib |
206 | -from tools.translate import _ |
207 | +import base64 |
208 | +import urllib |
209 | import os |
210 | |
211 | +from openerp.osv import fields, orm, osv |
212 | +from openerp.tools.translate import _ |
213 | + |
214 | import logging |
215 | _logger = logging.getLogger(__name__) |
216 | |
217 | #TODO find a good solution in order to roll back changed done on file system |
218 | -#TODO add the posibility to move from a store system to an other (example : moving existing image on database to file system) |
219 | - |
220 | -class product_images(Model): |
221 | +#TODO add the possibility to move from a store system to an other |
222 | +# (example : moving existing image on database to file system) |
223 | + |
224 | + |
225 | +class product_images(orm.Model): |
226 | "Products Image gallery" |
227 | _name = "product.images" |
228 | _description = __doc__ |
229 | - _table = "product_images" |
230 | |
231 | def unlink(self, cr, uid, ids, context=None): |
232 | if isinstance(ids, (int, long)): |
233 | @@ -45,25 +46,25 @@ |
234 | return super(product_images, self).unlink(cr, uid, ids, context=context) |
235 | |
236 | def create(self, cr, uid, vals, context=None): |
237 | - if vals.get('name', False) and not vals.get('extention', False): |
238 | - vals['name'], vals['extention'] = os.path.splitext(vals['name']) |
239 | + if vals.get('name') and not vals.get('extension'): |
240 | + vals['name'], vals['extension'] = os.path.splitext(vals['name']) |
241 | return super(product_images, self).create(cr, uid, vals, context=context) |
242 | |
243 | def write(self, cr, uid, ids, vals, context=None): |
244 | if not isinstance(ids, list): |
245 | ids = [ids] |
246 | - if vals.get('name', False) and not vals.get('extention', False): |
247 | - vals['name'], vals['extention'] = os.path.splitext(vals['name']) |
248 | + if vals.get('name') and not vals.get('extension'): |
249 | + vals['name'], vals['extension'] = os.path.splitext(vals['name']) |
250 | upd_ids = ids[:] |
251 | - if vals.get('name', False) or vals.get('extention', False): |
252 | + if vals.get('name') or vals.get('extension'): |
253 | images = self.browse(cr, uid, upd_ids, context=context) |
254 | for image in images: |
255 | old_full_path = self._image_path(cr, uid, image, context=context) |
256 | if not old_full_path: |
257 | continue |
258 | # all the stuff below is there to manage the files on the filesystem |
259 | - if vals.get('name', False) and (image.name != vals['name']) \ |
260 | - or vals.get('extention', False) and (image.extention != vals['extention']): |
261 | + if vals.get('name') and (image.name != vals['name']) \ |
262 | + or vals.get('extension') and (image.extension != vals['extension']): |
263 | super(product_images, self).write( |
264 | cr, uid, image.id, vals, context=context) |
265 | upd_ids.remove(image.id) |
266 | @@ -89,7 +90,7 @@ |
267 | full_path = os.path.join( |
268 | local_media_repository, |
269 | image.product_id.default_code, |
270 | - '%s%s' % (image.name or '', image.extention or '')) |
271 | + '%s%s' % (image.name or '', image.extension or '')) |
272 | return full_path |
273 | |
274 | def get_image(self, cr, uid, id, context=None): |
275 | @@ -97,7 +98,7 @@ |
276 | if image.link: |
277 | if image.url: |
278 | (filename, header) = urllib.urlretrieve(image.url) |
279 | - with open(filename , 'rb') as f: |
280 | + with open(filename, 'rb') as f: |
281 | img = base64.b64encode(f.read()) |
282 | else: |
283 | return False |
284 | @@ -117,7 +118,8 @@ |
285 | with open(full_path, 'rb') as f: |
286 | img = base64.b64encode(f.read()) |
287 | except Exception, e: |
288 | - _logger.error("Can not open the image %s, error : %s", full_path, e, exc_info=True) |
289 | + _logger.error("Can not open the image %s, error : %s", |
290 | + full_path, e, exc_info=True) |
291 | return False |
292 | else: |
293 | _logger.error("The image %s doesn't exist ", full_path) |
294 | @@ -133,13 +135,17 @@ |
295 | return res |
296 | |
297 | def _check_filestore(self, image_filestore): |
298 | - """check if the filestore is created, if not it create it automatically""" |
299 | + """check if the filestore is created, if not it create it |
300 | + automatically |
301 | + """ |
302 | try: |
303 | dir_path = os.path.dirname(image_filestore) |
304 | if not os.path.exists(dir_path): |
305 | os.makedirs(dir_path) |
306 | except OSError, e: |
307 | - raise except_osv(_('Error'), _('The image filestore can not be created, %s')%e) |
308 | + raise osv.except_osv( |
309 | + _('Error'), |
310 | + _('The image filestore can not be created, %s') % e) |
311 | return True |
312 | |
313 | def _save_file(self, path, b64_file): |
314 | @@ -154,21 +160,30 @@ |
315 | full_path = self._image_path(cr, uid, image, context=context) |
316 | if full_path: |
317 | return self._save_file(full_path, value) |
318 | - return self.write(cr, uid, id, {'file_db_store' : value}, context=context) |
319 | + return self.write(cr, uid, id, {'file_db_store': value}, context=context) |
320 | |
321 | _columns = { |
322 | - 'name':fields.char('Image Title', size=100, required=True), |
323 | - 'extention': fields.char('file extention', size=6), |
324 | - 'link':fields.boolean('Link?', help="Images can be linked from files on your file system or remote (Preferred)"), |
325 | - 'file_db_store':fields.binary('Image stored in database'), |
326 | - 'file':fields.function(_get_image, fnct_inv=_set_image, type="binary", filters='*.png,*.jpg,*.gif'), |
327 | - 'url':fields.char('File Location', size=250), |
328 | - 'comments':fields.text('Comments'), |
329 | - 'product_id':fields.many2one('product.product', 'Product') |
330 | + 'name': fields.char('Image Title', required=True), |
331 | + 'extension': fields.char('file extension', oldname='extention'), |
332 | + 'link': fields.boolean('Link?', |
333 | + help="Images can be linked from files on " |
334 | + "your file system or remote (Preferred)"), |
335 | + 'file_db_store': fields.binary('Image stored in database'), |
336 | + 'file': fields.function(_get_image, |
337 | + fnct_inv=_set_image, |
338 | + type="binary", |
339 | + string="File", |
340 | + filters='*.png,*.jpg,*.gif'), |
341 | + 'url': fields.char('File Location'), |
342 | + 'comments': fields.text('Comments'), |
343 | + 'product_id': fields.many2one('product.product', 'Product') |
344 | } |
345 | + |
346 | _defaults = { |
347 | - 'link': lambda *a: False, |
348 | + 'link': False, |
349 | } |
350 | - _sql_constraints = [('uniq_name_product_id', 'UNIQUE(product_id, name)', |
351 | - _('A product can have only one image with the same name'))] |
352 | |
353 | + _sql_constraints = [('uniq_name_product_id', |
354 | + 'UNIQUE(product_id, name)', |
355 | + _('A product can have only one ' |
356 | + 'image with the same name'))] |
357 | |
358 | === modified file 'product_images/views/company_view.xml' |
359 | --- product_images/views/company_view.xml 2011-11-18 10:13:17 +0000 |
360 | +++ product_images/views/company_view.xml 2013-01-31 07:04:20 +0000 |
361 | @@ -1,16 +1,16 @@ |
362 | +<?xml version="1.0" encoding="UTF-8"?> |
363 | <openerp> |
364 | <data> |
365 | <record model="ir.ui.view" id="view_company_form_product_images"> |
366 | <field name="name">res.company.form.inherit</field> |
367 | <field name="model">res.company</field> |
368 | <field name="inherit_id" ref="base.view_company_form"/> |
369 | - <field name="type">form</field> |
370 | <field name="arch" type="xml"> |
371 | - <notebook position="inside"> |
372 | - <page string="Product images"> |
373 | + <xpath expr="//page[@string='Configuration']/group[1]" position="inside"> |
374 | + <group name="product_images_grp" string="Product Images"> |
375 | <field name="local_media_repository"/> |
376 | - </page> |
377 | - </notebook> |
378 | + </group> |
379 | + </xpath> |
380 | </field> |
381 | </record> |
382 | </data> |
383 | |
384 | === modified file 'product_images/views/product_images_view.xml' |
385 | --- product_images/views/product_images_view.xml 2013-01-21 06:47:53 +0000 |
386 | +++ product_images/views/product_images_view.xml 2013-01-31 07:04:20 +0000 |
387 | @@ -1,55 +1,58 @@ |
388 | <?xml version="1.0" encoding="UTF-8"?> |
389 | <openerp> |
390 | - <data> |
391 | - <record id="view_product_image_form" model="ir.ui.view"> |
392 | - <field name="name">product.images.form</field> |
393 | - <field name="model">product.images</field> |
394 | - <field name="type">form</field> |
395 | - <field name="arch" type="xml"> |
396 | - <form string="Product Images"> |
397 | - <notebook colspan="4"> |
398 | - <page string="Image"> |
399 | - <group col="6" colspan="4"> |
400 | - <field name="name" colspan="2" /> |
401 | - <field name="extention" colspan="2" /> |
402 | - <field name="link" colspan="2" /> |
403 | - </group> |
404 | - <group attrs="{'invisible':[('link','=',0)]}" colspan="4"> |
405 | - <separator string="File Location and Preview (Only when saved)" colspan="4"/> |
406 | - <field name="url" colspan="4" widget="url" nolabel="1"/> |
407 | - </group> |
408 | - <field name="file" widget="image" nolabel="1" filename="name" colspan="4" attrs="{'readonly':[('link','!=',0)]}"/> |
409 | - </page> |
410 | - <page string="Comments"> |
411 | - <field name="comments" nolabel="1" colspan="4" /> |
412 | - </page> |
413 | - </notebook> |
414 | - </form> |
415 | - </field> |
416 | - </record> |
417 | - <record id="view_product_image_tree" model="ir.ui.view"> |
418 | - <field name="name">product.images.tree</field> |
419 | - <field name="model">product.images</field> |
420 | - <field name="type">tree</field> |
421 | - <field name="arch" type="xml"> |
422 | - <tree string="Product Images"> |
423 | - <field name="name" select="1" /> |
424 | - <field name="comments" select="2" /> |
425 | - </tree> |
426 | - </field> |
427 | - </record> |
428 | - <record id="view_product_form_img_inh" model="ir.ui.view"> |
429 | - <field name="name">product.product.images</field> |
430 | - <field name="model">product.product</field> |
431 | - <field name="inherit_id" ref="product.product_normal_form_view" /> |
432 | - <field name="type">form</field> |
433 | - <field name="arch" type="xml"> |
434 | - <xpath expr="/form/sheet/notebook" position="inside"> |
435 | - <page string="Images"> |
436 | - <field name="image_ids" nolabel="1" /> |
437 | - </page> |
438 | - </xpath> |
439 | - </field> |
440 | - </record> |
441 | - </data> |
442 | + <data> |
443 | + <record id="view_product_image_form" model="ir.ui.view"> |
444 | + <field name="name">product.images.form</field> |
445 | + <field name="model">product.images</field> |
446 | + <field name="arch" type="xml"> |
447 | + <form string="Product Images"> |
448 | + <notebook colspan="4"> |
449 | + <page string="Image"> |
450 | + <group col="6" colspan="4"> |
451 | + <field name="name" colspan="2" /> |
452 | + <field name="extension" colspan="2" /> |
453 | + <field name="link" colspan="2" /> |
454 | + </group> |
455 | + <group attrs="{'invisible': [('link', '=', False)]}" colspan="4"> |
456 | + <field name="url" colspan="4" widget="url"/> |
457 | + </group> |
458 | + <group> |
459 | + <field name="file" widget="image" nolabel="1" filename="name" |
460 | + colspan="4" attrs="{'readonly': [('link', '=', True)]}"/> |
461 | + </group> |
462 | + </page> |
463 | + <page string="Comments"> |
464 | + <group> |
465 | + <field name="comments" nolabel="1" colspan="4" /> |
466 | + </group> |
467 | + </page> |
468 | + </notebook> |
469 | + </form> |
470 | + </field> |
471 | + </record> |
472 | + |
473 | + <record id="view_product_image_tree" model="ir.ui.view"> |
474 | + <field name="name">product.images.tree</field> |
475 | + <field name="model">product.images</field> |
476 | + <field name="arch" type="xml"> |
477 | + <tree string="Product Images"> |
478 | + <field name="name" select="1" /> |
479 | + <field name="comments" select="2" /> |
480 | + </tree> |
481 | + </field> |
482 | + </record> |
483 | + |
484 | + <record id="view_product_form_img_inh" model="ir.ui.view"> |
485 | + <field name="name">product.product.images</field> |
486 | + <field name="model">product.product</field> |
487 | + <field name="inherit_id" ref="product.product_normal_form_view" /> |
488 | + <field name="arch" type="xml"> |
489 | + <xpath expr="/form/sheet/notebook" position="inside"> |
490 | + <page string="Images"> |
491 | + <field name="image_ids" nolabel="1" /> |
492 | + </page> |
493 | + </xpath> |
494 | + </field> |
495 | + </record> |
496 | + </data> |
497 | </openerp> |
498 | |
499 | === modified file 'product_sequence/__openerp__.py' |
500 | --- product_sequence/__openerp__.py 2013-01-21 06:49:06 +0000 |
501 | +++ product_sequence/__openerp__.py 2013-01-31 07:04:20 +0000 |
502 | @@ -1,4 +1,4 @@ |
503 | -# -*- encoding: utf-8 -*- |
504 | +# -*- coding: utf-8 -*- |
505 | ############################################################################## |
506 | # |
507 | # OpenERP, Open Source Management Solution |
508 | @@ -22,7 +22,7 @@ |
509 | |
510 | { |
511 | 'name' : 'Product Sequence', |
512 | - 'version' : '6.1.0', |
513 | + 'version' : '7.0', |
514 | "author": "Zikzakmedia SL", |
515 | "website": "http://www.zikzakmedia.com", |
516 | "license" : "AGPL-3", |
517 | @@ -35,11 +35,9 @@ |
518 | 'depends' : [ |
519 | 'product', |
520 | ], |
521 | - "init_xml" : [ |
522 | + "data" : [ |
523 | 'product_sequence.xml', |
524 | ], |
525 | - "update_xml" : [ |
526 | - ], |
527 | - 'installable': False, |
528 | + 'installable': True, |
529 | 'active': False, |
530 | } |
531 | |
532 | === modified file 'product_sequence/product_product.py' |
533 | --- product_sequence/product_product.py 2012-09-26 15:54:15 +0000 |
534 | +++ product_sequence/product_product.py 2013-01-31 07:04:20 +0000 |
535 | @@ -19,47 +19,64 @@ |
536 | # |
537 | ############################################################################## |
538 | |
539 | -from openerp.osv.orm import Model |
540 | -from openerp.osv import fields |
541 | +from openerp.osv import orm, fields |
542 | from openerp.tools.translate import _ |
543 | |
544 | -class product_product(Model): |
545 | + |
546 | +class product_product(orm.Model): |
547 | _inherit = 'product.product' |
548 | + |
549 | _columns = { |
550 | - 'default_code' : fields.char('Reference', size=64, required=True), |
551 | + 'default_code': fields.char('Reference', |
552 | + size=64, |
553 | + select=True, |
554 | + required=True), |
555 | } |
556 | + |
557 | _sql_constraints = [ |
558 | - ('uniq_default_code', 'unique(default_code)', "The reference must be unique"), |
559 | - ] |
560 | + ('uniq_default_code', |
561 | + 'unique(default_code)', |
562 | + 'The reference must be unique'), |
563 | + ] |
564 | + |
565 | _defaults = { |
566 | - 'default_code': lambda * a: '/', |
567 | + 'default_code': '/', |
568 | } |
569 | |
570 | def create(self, cr, uid, vals, context=None): |
571 | - if context is None: |
572 | - context = {} |
573 | if not 'default_code' in vals or vals['default_code'] == '/': |
574 | - vals['default_code'] = self.pool.get('ir.sequence').get(cr, uid, 'product.product') |
575 | + vals['default_code'] = self.pool.get('ir.sequence').get( |
576 | + cr, uid, 'product.product') |
577 | return super(product_product, self).create(cr, uid, vals, context) |
578 | |
579 | def write(self, cr, uid, ids, vals, context=None): |
580 | if not hasattr(ids, '__iter__'): |
581 | ids = [ids] |
582 | - if context is None: |
583 | - context = {} |
584 | - products_without_code = self.search(cr, uid, [('default_code', 'in', [False, '/']),('id', 'in', ids)], context=context) |
585 | + products_without_code = self.search( |
586 | + cr, uid, |
587 | + [('default_code', 'in', [False, '/']), |
588 | + ('id', 'in', ids)], |
589 | + context=context) |
590 | direct_write_ids = set(ids) - set(products_without_code) |
591 | - super(product_product, self).write(cr, uid, list(direct_write_ids), vals, context) |
592 | + super(product_product, self).write(cr, uid, |
593 | + list(direct_write_ids), |
594 | + vals, context=context) |
595 | for product_id in products_without_code: |
596 | - vals['default_code'] = self.pool.get('ir.sequence').get(cr, uid, 'product.product') |
597 | - super(product_product, self).write(cr, uid, product_id, vals, context) |
598 | + vals['default_code'] = self.pool.get('ir.sequence').get( |
599 | + cr, uid, 'product.product') |
600 | + super(product_product, self).write(cr, uid, |
601 | + product_id, |
602 | + vals, |
603 | + context=context) |
604 | return True |
605 | |
606 | - def copy(self, cr, uid, id, default={}, context=None): |
607 | + def copy(self, cr, uid, id, default=None, context=None): |
608 | + if default is None: |
609 | + default = {} |
610 | product = self.read(cr, uid, id, ['default_code'], context=context) |
611 | - if product['default_code']: |
612 | + if product['default_code']: |
613 | default.update({ |
614 | - 'default_code': product['default_code']+ _('-copy'), |
615 | + 'default_code': product['default_code'] + _('-copy'), |
616 | }) |
617 | |
618 | return super(product_product, self).copy(cr, uid, id, default, context) |
619 | |
620 | === modified file 'product_sequence/product_sequence.xml' |
621 | --- product_sequence/product_sequence.xml 2012-08-02 10:43:21 +0000 |
622 | +++ product_sequence/product_sequence.xml 2013-01-31 07:04:20 +0000 |
623 | @@ -1,11 +1,12 @@ |
624 | <?xml version="1.0" encoding="UTF-8" ?> |
625 | <openerp> |
626 | <data noupdate="1"> |
627 | + |
628 | <record id="seq_product_auto_type" model="ir.sequence.type"> |
629 | <field name="name">Product</field> |
630 | <field name="code">product.product</field> |
631 | </record> |
632 | - |
633 | + |
634 | <record id="seq_product_auto" model="ir.sequence"> |
635 | <field name="name">Product</field> |
636 | <field name="code">product.product</field> |
By the way, there is a LOT of room for improvements on this module.
At least, it installs on v7, but it is far to be very good, in my opinion.