Merge lp:~camptocamp/openerp-connector-magento/7.0-update-stock-1330450 into lp:~openerp-connector-core-editors/openerp-connector-magento/7.0

Proposed by Guewen Baconnier @ Camptocamp
Status: Rejected
Rejected by: Guewen Baconnier @ Camptocamp
Proposed branch: lp:~camptocamp/openerp-connector-magento/7.0-update-stock-1330450
Merge into: lp:~openerp-connector-core-editors/openerp-connector-magento/7.0
Diff against target: 124 lines (+71/-14)
1 file modified
magentoerpconnect/product.py (+71/-14)
To merge this branch: bzr merge lp:~camptocamp/openerp-connector-magento/7.0-update-stock-1330450
Reviewer Review Type Date Requested Status
OpenERP Connector Core Editors Pending
Review via email: mp+223393@code.launchpad.net

Commit message

Update of Magento stock quantity: reduced the memory footprint and improved
performance by using read() instead of browse() and proceeding by steps of 1000 records at a time.

Description of the change

To post a comment you must log in.
Revision history for this message
Guewen Baconnier @ Camptocamp (gbaconnier-c2c) wrote :

Unmerged revisions

1003. By Guewen Baconnier @ Camptocamp

Update of Magento stock quantity: reduced the memory footprint and improved
performance by using read() instead of browse() and proceeding by steps of 1000
records at a time.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'magentoerpconnect/product.py'
--- magentoerpconnect/product.py 2014-06-14 20:30:26 +0000
+++ magentoerpconnect/product.py 2014-06-17 12:15:30 +0000
@@ -25,6 +25,7 @@
25import base6425import base64
26import xmlrpclib26import xmlrpclib
27import sys27import sys
28from collections import defaultdict
28from openerp.osv import orm, fields29from openerp.osv import orm, fields
29from openerp.tools.translate import _30from openerp.tools.translate import _
30from openerp.addons.connector.queue.job import job, related_action31from openerp.addons.connector.queue.job import job, related_action
@@ -54,6 +55,11 @@
54_logger = logging.getLogger(__name__)55_logger = logging.getLogger(__name__)
5556
5657
58def chunks(items, length):
59 for index in xrange(0, len(items), length):
60 yield items[index:index + length]
61
62
57class magento_product_product(orm.Model):63class magento_product_product(orm.Model):
58 _name = 'magento.product.product'64 _name = 'magento.product.product'
59 _inherit = 'magento.binding'65 _inherit = 'magento.binding'
@@ -123,35 +129,86 @@
123 "A product with the same ID on Magento already exists")129 "A product with the same ID on Magento already exists")
124 ]130 ]
125131
132 RECOMPUTE_QTY_STEP = 1000 # products at a time
133
126 def recompute_magento_qty(self, cr, uid, ids, context=None):134 def recompute_magento_qty(self, cr, uid, ids, context=None):
135 """ Check if the quantity in the stock location configured
136 on the backend has changed since the last export.
137
138 If it has changed, write the updated quantity on `magento_qty`.
139 The write on `magento_qty` will trigger an `on_record_write`
140 event that will create an export job.
141
142 It groups the products by backend to avoid to read the backend
143 informations for each product.
144 """
127 if not hasattr(ids, '__iter__'):145 if not hasattr(ids, '__iter__'):
128 ids = [ids]146 ids = [ids]
129147
130 for product in self.browse(cr, uid, ids, context=context):148 # group products by backend
131 new_qty = self._magento_qty(cr, uid, product, context=context)149 backends = defaultdict(list)
132 if new_qty != product.magento_qty:150 for product in self.read(cr, uid, ids, ['backend_id', 'magento_qty'],
133 self.write(cr, uid, product.id,151 context=context):
134 {'magento_qty': new_qty},152 backends[product['backend_id'][0]].append(product)
135 context=context)153
154 for backend_id, products in backends.iteritems():
155 backend_obj = self.pool['magento.backend']
156 backend = backend_obj.browse(cr, uid, backend_id, context=context)
157 self._recompute_magento_qty_backend(cr, uid, backend, products,
158 context=context)
136 return True159 return True
137160
138 def _magento_qty(self, cr, uid, product, context=None):161 def _recompute_magento_qty_backend(self, cr, uid, backend, products,
162 read_fields=None, context=None):
163 """ Recompute the products quantity for one backend.
164
165 If field names are passed in ``read_fields`` (as a list), they
166 will be read in the product that is used in
167 :meth:`~._magento_qty`.
168
169 """
139 if context is None:170 if context is None:
140 context = {}171 context = {}
141 backend = product.backend_id
142 stock = backend.warehouse_id.lot_stock_id
143172
144 if backend.product_stock_field_id:173 if backend.product_stock_field_id:
145 stock_field = backend.product_stock_field_id.name174 stock_field = backend.product_stock_field_id.name
146 else:175 else:
147 stock_field = 'virtual_available'176 stock_field = 'virtual_available'
148177
178 location = backend.warehouse_id.lot_stock_id
149 location_ctx = context.copy()179 location_ctx = context.copy()
150 location_ctx['location'] = stock.id180 location_ctx['location'] = location.id
151 product_stk = self.read(cr, uid, product.id,181
152 [stock_field],182 product_fields = ['magento_qty', stock_field]
153 context=location_ctx)183 if read_fields:
154 return product_stk[stock_field]184 product_fields += read_fields
185
186 product_ids = [product['id'] for product in products]
187 for chunk_ids in chunks(product_ids, self.RECOMPUTE_QTY_STEP):
188 for product in self.read(cr, uid, chunk_ids, product_fields,
189 context=location_ctx):
190 new_qty = self._magento_qty(cr, uid, product,
191 backend,
192 location,
193 stock_field,
194 context=location_ctx)
195 if new_qty != product['magento_qty']:
196 self.write(cr, uid, product['id'],
197 {'magento_qty': new_qty},
198 context=context)
199
200 def _magento_qty(self, cr, uid, product, backend, location,
201 stock_field, context=None):
202 """ Return the current quantity for one product.
203
204 Can be inherited to change the way the quantity is computed,
205 according to a backend / location.
206
207 If you need to read additional fields on the product, see the
208 ``read_fields`` argument of :meth:`~._recompute_magento_qty_backend`
209
210 """
211 return product[stock_field]
155212
156213
157class product_product(orm.Model):214class product_product(orm.Model):