#51 refactor: traer categorias anidadas en un solo request de productos
Issue #51: discriminacion y administracion de categorias de productos. - product.read ahora solicita template.categories.name; se elimina la llamada separada model.product.category.read - ProductTrytonService y CategoryTrytonService construyen el mapa {id_tryton: nombre} desde 'template.categories.' de los productos leídos - import_from_external pasa de 3 llamadas RPC a 2
This commit is contained in:
@@ -53,15 +53,14 @@ class CategoryTrytonService:
|
||||
return self._empty_report()
|
||||
tryton_products = self._get_product_details(product_ids, context)
|
||||
|
||||
category_ids = set()
|
||||
for tryton_product in tryton_products:
|
||||
category_ids.update(self._extract_category_ids(tryton_product))
|
||||
if not category_ids:
|
||||
category_names = self._extract_category_names(tryton_products)
|
||||
if not category_names:
|
||||
return self._empty_report()
|
||||
|
||||
tryton_categories = self._get_category_details(
|
||||
sorted(category_ids), context
|
||||
)
|
||||
tryton_categories = [
|
||||
{"id": category_id, "name": category_names[category_id]}
|
||||
for category_id in sorted(category_names)
|
||||
]
|
||||
|
||||
checked = [
|
||||
{"id": c.get("id"), "name": c.get("name")}
|
||||
@@ -121,21 +120,27 @@ class CategoryTrytonService:
|
||||
return self.client.call(method, params) or []
|
||||
|
||||
def _get_product_details(self, product_ids, context):
|
||||
tryton_fields = ["id", "name", "template.categories"]
|
||||
tryton_fields = [
|
||||
"id",
|
||||
"name",
|
||||
"template.categories",
|
||||
"template.categories.name",
|
||||
]
|
||||
method = "model.product.product.read"
|
||||
params = (product_ids, tryton_fields, context)
|
||||
return self.client.call(method, params)
|
||||
|
||||
@staticmethod
|
||||
def _extract_category_ids(tryton_product):
|
||||
"""Extrae los IDs de categorías de la respuesta RPC de Tryton"""
|
||||
template = tryton_product.get("template.") or {}
|
||||
return template.get("categories") or []
|
||||
|
||||
def _get_category_details(self, category_ids, context):
|
||||
method = "model.product.category.read"
|
||||
params = (category_ids, ["id", "name"], context)
|
||||
return self.client.call(method, params)
|
||||
def _extract_category_names(tryton_products):
|
||||
"""Extrae el mapa {id_tryton: nombre} de las categorías anidadas en
|
||||
la respuesta de product.read (clave 'template.categories.name',
|
||||
agrupada bajo 'template.' como 'categories.')"""
|
||||
names = {}
|
||||
for tryton_product in tryton_products:
|
||||
template = tryton_product.get("template.") or {}
|
||||
for category in template.get("categories.") or []:
|
||||
names[category.get("id")] = category.get("name")
|
||||
return names
|
||||
|
||||
def _empty_report(self):
|
||||
return {
|
||||
|
||||
@@ -107,19 +107,16 @@ class ProductTrytonService:
|
||||
reporte {"created": [...], "updated": [...]}
|
||||
"""
|
||||
empty_report = {"created": [], "updated": []}
|
||||
category_ids = {
|
||||
category_id
|
||||
for tryton_product in tryton_products
|
||||
for category_id in self._extract_category_ids(tryton_product)
|
||||
}
|
||||
if not category_ids:
|
||||
category_names = self._extract_category_names(tryton_products)
|
||||
if not category_names:
|
||||
return {}, empty_report
|
||||
|
||||
categories = {}
|
||||
report = {"created": [], "updated": []}
|
||||
tryton_categories = self._get_category_details(
|
||||
sorted(category_ids), context
|
||||
)
|
||||
tryton_categories = [
|
||||
{"id": category_id, "name": category_names[category_id]}
|
||||
for category_id in sorted(category_names)
|
||||
]
|
||||
for tryton_category in tryton_categories:
|
||||
try:
|
||||
category, status, changes = upsert_category(tryton_category)
|
||||
@@ -149,11 +146,17 @@ class ProductTrytonService:
|
||||
template = tryton_product.get("template.") or {}
|
||||
return template.get("categories") or []
|
||||
|
||||
def _get_category_details(self, category_ids, context):
|
||||
"""Obtiene los nombres de categorías desde Tryton"""
|
||||
method = "model.product.category.read"
|
||||
params = (category_ids, ["id", "name"], context)
|
||||
return self.client.call(method, params)
|
||||
@staticmethod
|
||||
def _extract_category_names(tryton_products):
|
||||
"""Extrae el mapa {id_tryton: nombre} de las categorías anidadas en
|
||||
la respuesta de product.read (clave 'template.categories.name',
|
||||
agrupada bajo 'template.' como 'categories.')"""
|
||||
names = {}
|
||||
for tryton_product in tryton_products:
|
||||
template = tryton_product.get("template.") or {}
|
||||
for category in template.get("categories.") or []:
|
||||
names[category.get("id")] = category.get("name")
|
||||
return names
|
||||
|
||||
def _sync_product_categories(self, product, tryton_product, categories):
|
||||
"""Vincula al producto las categorías importadas desde Tryton"""
|
||||
@@ -271,6 +274,7 @@ class ProductTrytonService:
|
||||
"default_uom.rec_name",
|
||||
"list_price",
|
||||
"template.categories",
|
||||
"template.categories.name",
|
||||
]
|
||||
method = "model.product.product.read"
|
||||
params = (product_ids, tryton_fields, context)
|
||||
|
||||
Reference in New Issue
Block a user