diff --git a/connector_prestashop/models/prestashop_backend/common.py b/connector_prestashop/models/prestashop_backend/common.py index 8c74ed07d..3c5a2bd7b 100644 --- a/connector_prestashop/models/prestashop_backend/common.py +++ b/connector_prestashop/models/prestashop_backend/common.py @@ -295,6 +295,32 @@ def import_record(self, model_name, ext_id): import_record(session, model_name, self.id, ext_id) return True + @api.multi + def _get_locations_for_stock_quantities(self): + root_location = (self.stock_location_id or + self.warehouse_id.lot_stock_id) + locations = self.env['stock.location'].search([ + ('id', 'child_of', root_location.id), + ('prestashop_synchronized', '=', True), + ('usage', '=', 'internal'), + ]) + # if we choosed a location but none where flagged + # 'prestashop_synchronized', consider we want all of them in the tree + if not locations: + locations = self.env['stock.location'].search([ + ('id', 'child_of', root_location.id), + ('usage', '=', 'internal'), + ]) + if not locations: + # we must not pass an empty location or we would have the + # stock for every warehouse, which is the last thing we + # expect + raise exceptions.UserError( + _('No internal location found to compute the product ' + 'quantity.') + ) + return locations + class PrestashopShopGroup(models.Model): _name = 'prestashop.shop.group' diff --git a/connector_prestashop/models/product_product/common.py b/connector_prestashop/models/product_product/common.py index c8ff8a33a..86b429a1f 100644 --- a/connector_prestashop/models/product_product/common.py +++ b/connector_prestashop/models/product_product/common.py @@ -1,6 +1,8 @@ # -*- coding: utf-8 -*- # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). +from collections import defaultdict + from odoo import api, fields, models from odoo.addons import decimal_precision as dp @@ -152,14 +154,29 @@ class PrestashopProductCombination(models.Model): @api.multi def recompute_prestashop_qty(self): - for product_binding in self: - if product_binding.quantity != product_binding.qty_available: - product_binding.quantity = product_binding.qty_available + # group products by backend + backends = defaultdict(set) + for product in self: + backends[product.backend_id].add(product.id) + + for backend, product_ids in backends.iteritems(): + products = self.browse(product_ids) + products._recompute_prestashop_qty_backend(backend) return True - @api.model - def _prestashop_qty(self, product): - return product.qty_available + @api.multi + def _recompute_prestashop_qty_backend(self, backend): + locations = backend._get_locations_for_stock_quantities() + self_loc = self.with_context(location=locations.ids, + compute_child=False) + for product_binding in self_loc: + new_qty = product_binding._prestashop_qty() + if product_binding.quantity != new_qty: + product_binding.quantity = new_qty + return True + + def _prestashop_qty(self): + return self.qty_available @job(default_channel='root.prestashop') def export_inventory(self, backend, fields=None, **kwargs): diff --git a/connector_prestashop/models/product_template/common.py b/connector_prestashop/models/product_template/common.py index 07da481de..c704f826c 100644 --- a/connector_prestashop/models/product_template/common.py +++ b/connector_prestashop/models/product_template/common.py @@ -1,7 +1,9 @@ # -*- coding: utf-8 -*- # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html) -from odoo import api, fields, models +from collections import defaultdict + +from odoo import _, api, exceptions, fields, models from odoo.addons import decimal_precision as dp from odoo.addons.queue_job.job import job @@ -113,48 +115,29 @@ class PrestashopProductTemplate(models.Model): @api.multi def recompute_prestashop_qty(self): - for product_binding in self: - new_qty = product_binding._prestashop_qty() - if product_binding.quantity != new_qty: - product_binding.quantity = new_qty + # group products by backend + backends = defaultdict(set) + for product in self: + backends[product.backend_id].add(product.id) + + for backend, product_ids in backends.iteritems(): + products = self.browse(product_ids) + products._recompute_prestashop_qty_backend(backend) return True - def _prestashop_qty(self): - locations = self.env['stock.location'].search([ - ('id', 'child_of', self.backend_id.warehouse_id.lot_stock_id.id), - ('prestashop_synchronized', '=', True), - ('usage', '=', 'internal'), - ]) - return self.with_context(location=locations.ids).qty_available - - @job(default_channel='root.prestashop') - def import_products(self, backend, since_date=None, **kwargs): - filters = None - if since_date: - filters = {'date': '1', 'filter[date_upd]': '>[%s]' % (since_date)} - now_fmt = fields.Datetime.now() - self.env['prestashop.product.category'].with_delay( - priority=15 - ).import_batch(backend=backend, filters=filters, **kwargs) - self.env['prestashop.product.template'].with_delay( - priority=15 - ).import_batch(backend, filters, **kwargs) - backend.import_products_since = now_fmt + @api.multi + def _recompute_prestashop_qty_backend(self, backend): + locations = backend._get_locations_for_stock_quantities() + self_loc = self.with_context(location=locations.ids, + compute_child=False) + for product in self_loc: + new_qty = product._prestashop_qty() + if product.quantity != new_qty: + product.quantity = new_qty return True - @job(default_channel='root.prestashop') - def export_inventory(self, backend, fields=None, **kwargs): - """ Export the inventory configuration and quantity of a product. """ - env = backend.get_environment(self._name) - inventory_exporter = env.get_connector_unit(ProductInventoryExporter) - return inventory_exporter.run(self.id, fields, **kwargs) - - @api.model - @job(default_channel='root.prestashop') - def export_product_quantities(self, backend): - self.search([ - ('backend_id', 'in', self.env.backend.ids), - ]).recompute_prestashop_qty() + def _prestashop_qty(self): + return self.qty_available @prestashop