From 32fb275aa1ffae0ef4eff3b2040720093056e473 Mon Sep 17 00:00:00 2001 From: Florent Xicluna Date: Fri, 29 Nov 2024 09:51:10 +0100 Subject: [PATCH] [IMP] product_import: Import products asynchronously --- product_import/__manifest__.py | 2 ++ product_import/tests/common.py | 3 +- product_import/tests/test_product_import.py | 2 +- product_import/wizard/product_import.py | 37 ++++++++++++--------- 4 files changed, 27 insertions(+), 17 deletions(-) diff --git a/product_import/__manifest__.py b/product_import/__manifest__.py index 6411437d653..8b040b603f2 100644 --- a/product_import/__manifest__.py +++ b/product_import/__manifest__.py @@ -13,6 +13,8 @@ "stock", # OCA/edi "base_business_document_import", + # OCA/queue + "queue_job", ], "data": [ "security/ir.model.access.csv", diff --git a/product_import/tests/common.py b/product_import/tests/common.py index dac4cb1b481..4a91bd2fd34 100644 --- a/product_import/tests/common.py +++ b/product_import/tests/common.py @@ -11,7 +11,8 @@ class TestCommon(SavepointCase): def setUpClass(cls): super().setUpClass() cls.env = cls.env(context=dict(cls.env.context, tracking_disable=True)) - cls.wiz_model = cls.env["product.import"] + # Execute directly, no job + cls.wiz_model = cls.env["product.import"].with_context(queue_job__no_delay=True) cls.supplier = cls.env["res.partner"].create({"name": "Catalogue Vendor"}) def _mock(self, method_name): diff --git a/product_import/tests/test_product_import.py b/product_import/tests/test_product_import.py index 408780a7169..f855e6f96ee 100644 --- a/product_import/tests/test_product_import.py +++ b/product_import/tests/test_product_import.py @@ -86,7 +86,7 @@ def test_get_company_id(self): def test_product_import(self): # product.product - products = self.wiz_model._create_products( + products = self.wiz_model._import_products( self.parsed_catalog, seller=self.supplier ) self.assertEqual(len(products), 3) diff --git a/product_import/wizard/product_import.py b/product_import/wizard/product_import.py index ef89714b4c3..3e66796c2b8 100644 --- a/product_import/wizard/product_import.py +++ b/product_import/wizard/product_import.py @@ -195,14 +195,15 @@ def _prepare_product(self, parsed_product, chatter_msg, seller=None): return product_vals @api.model - def create_product(self, parsed_product, chatter_msg, seller=None): + def create_update_product(self, parsed_product, chatter_msg, seller_id): + seller = self.env["res.partner"].browse(seller_id) product_vals = self._prepare_product(parsed_product, chatter_msg, seller=seller) if not product_vals: return False product = product_vals.pop("recordset", None) if product: product.write(product_vals) - logger.info("Product %d updated", product.id) + logger.debug("Product %s updated", product.default_code) else: product_active = product_vals.pop("active") product = self.env["product.product"].create(product_vals) @@ -211,23 +212,29 @@ def create_product(self, parsed_product, chatter_msg, seller=None): # all characteristics into product.template product.flush() product.action_archive() - logger.info("Product %d created", product.id) + logger.debug("Product %s created", product.default_code) return product @api.model - def _create_products(self, catalogue, seller, filename=None): - products = self.env["product.product"].browse() - for product in catalogue.get("products"): - record = self.create_product( - product, - catalogue["chatter_msg"], - seller=seller, - ) - if record: - products |= record + def _create_update_product(self, parsed_product, seller_id): + """Create / Update a product. + + This method is called from a queue job. + """ + messgs = [] + product = self.create_update_product(parsed_product, messgs, seller_id) + log_msg = f"Product created/updated {product.id}\n" + "\n".join(messgs) + return log_msg + + @api.model + def _import_products(self, catalogue, seller, filename=None): + for product_vals in catalogue["products"]: + # One job per product + self.with_delay()._create_update_product(product_vals, seller.id) self._bdimport.post_create_or_update(catalogue, seller, doc_filename=filename) - logger.info("Products updated for vendor %d", seller.id) - return products + logger.info( + "Update for vendor %s: %d products", seller.name, len(catalogue["products"]) + ) def import_button(self): self.ensure_one()