Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 14 additions & 1 deletion connector_extension/components/binder.py
Original file line number Diff line number Diff line change
Expand Up @@ -493,8 +493,21 @@ def to_binding_from_internal_key(self, relation):
# TODO: check if we can put this in a hook
external_alt_id = self.dict2id(id_values, in_field=False, alt_field=True)
if self.is_id_null(external_alt_id):
return self.model
record = self._get_external_record_alt_fallback(relation, id_values)
return self._to_binding_from_external_record(relation, record)
record = self._get_external_record_alt(relation, id_values)
return self._to_binding_from_external_record(relation, record)

def _get_external_record_alt_fallback(self, relation, id_values):
"""Hook called when the external alternate key is incomplete (some
of its fields are null) and the external record cannot be searched
directly. Override it to find the external record by indirect means.
By default it returns no record, keeping the standard behaviour:
the record will be created on the external system.
"""
return {}

def _to_binding_from_external_record(self, relation, record):
if record:
external_id = self.dict2id(record, in_field=False)
binding = self.wrap_record(relation)
Expand Down
23 changes: 23 additions & 0 deletions connector_woocommerce/models/product_template/binder.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,29 @@ def external_alt_id(self):
def internal_alt_id(self):
return ["default_code"]

def _get_external_record_alt_fallback(self, relation, id_values):
# A variable product template carries no SKU of its own on WooCommerce
# (the SKUs belong to its variations), so it can never be found through
# the alternate key. Derive the external parent product through one of
# its variations instead.
if not relation.has_attributes:
return super()._get_external_record_alt_fallback(relation, id_values)
adapter = self.component(usage="backend.adapter")
variants = relation.with_context(active_test=False).product_variant_ids
for binding in variants.woocommerce_bind_ids.filtered(
lambda x: x.backend_id == self.backend_record
):
if binding.woocommerce_idparent:
return adapter.read(binding.woocommerce_idparent)
variation_adapter = self.component(
usage="backend.adapter", model_name="woocommerce.product.product"
)
for sku in variants.filtered("default_code").mapped("default_code"):
for variation in variation_adapter.search_read([("sku", "=", sku)]):
if variation.get("parent_id"):
return adapter.read(variation["parent_id"])
return super()._get_external_record_alt_fallback(relation, id_values)

# def _additional_external_binding_fields(self, external_data, relation):
# return {
# **super()._additional_external_binding_fields(external_data, relation),
Expand Down
28 changes: 17 additions & 11 deletions connector_woocommerce_wpml/models/product_product/binder.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,15 +41,21 @@ def wpml_additional_external_binding_fields(self, external_data, relation):
def _get_external_record_alt(self, relation, id_values):
res = super()._get_external_record_alt(relation, id_values)
if res:
relation_wp_lang = self.env["res.lang"]._get_wpml_code_from_iso_code(
relation.env.context.get("lang")
)
if res.get("lang") != relation_wp_lang:
if res.get("translations") and res["translations"].get(
relation_wp_lang
):
adapter = self.component(usage="backend.adapter")
res = adapter.read(res["translations"][relation_wp_lang])
else:
return None
res = self._wpml_redirect_record_lang(relation, res)
return res

def _get_external_record_alt_fallback(self, relation, id_values):
record = super()._get_external_record_alt_fallback(relation, id_values)
if record:
record = self._wpml_redirect_record_lang(relation, record)
return record or {}

def _wpml_read_translation(self, relation, record, translation_id):
# A variation is read under its parent product: resolve the parent
# for the requested language through the template binding.
template_binder = self.binder_for("woocommerce.product.template")
template_binding = template_binder.wrap_record(relation.product_tmpl_id)
if not template_binding:
return None
adapter = self.component(usage="backend.adapter")
return adapter.read([template_binding.woocommerce_idproduct, translation_id])
18 changes: 7 additions & 11 deletions connector_woocommerce_wpml/models/product_template/binder.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,15 +34,11 @@ def wpml_additional_external_binding_fields(self, external_data, relation):
def _get_external_record_alt(self, relation, id_values):
res = super()._get_external_record_alt(relation, id_values)
if res:
relation_wp_lang = self.env["res.lang"]._get_wpml_code_from_iso_code(
relation.env.context.get("lang")
)
if res.get("lang") != relation_wp_lang:
if res.get("translations") and res["translations"].get(
relation_wp_lang
):
adapter = self.component(usage="backend.adapter")
res = adapter.read(res["translations"][relation_wp_lang])
else:
return None
res = self._wpml_redirect_record_lang(relation, res)
return res

def _get_external_record_alt_fallback(self, relation, id_values):
record = super()._get_external_record_alt_fallback(relation, id_values)
if record:
record = self._wpml_redirect_record_lang(relation, record)
return record or {}
40 changes: 40 additions & 0 deletions connector_woocommerce_wpml/models/product_wpml_mixin/binder.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,3 +30,43 @@ def wpml_additional_external_binding_fields(self, external_data, relation):
**super()._additional_external_binding_fields(external_data, relation),
"woocommerce_lang": external_data["lang"],
}

def wpml_get_master_binding(self, relation):
return self.model.with_context(active_test=False).search(
[
(self._odoo_field, "=", relation.id),
(self._backend_field, "=", self.backend_record.id),
("woocommerce_master_lang", "=", True),
],
limit=1,
)

def _wpml_read_translation(self, relation, record, translation_id):
adapter = self.component(usage="backend.adapter")
return adapter.read(translation_id)

def _wpml_redirect_record_lang(self, relation, record):
relation_wp_lang = self.env["res.lang"]._get_wpml_code_from_iso_code(
relation.env.context.get("lang")
)
if record.get("lang") != relation_wp_lang:
if record.get("translations") and record["translations"].get(
relation_wp_lang
):
return self._wpml_read_translation(
relation, record, record["translations"][relation_wp_lang]
)
return None
return record

def _get_external_record_alt_fallback(self, relation, id_values):
record = super()._get_external_record_alt_fallback(relation, id_values)
if not record:
# Non-master languages don't export the SKU, so their alternate
# key is always incomplete: reach the external record through the
# master language binding instead.
master_binding = self.wpml_get_master_binding(relation)
if master_binding:
adapter = self.component(usage="backend.adapter")
record = adapter.read(self.dict2id(master_binding, in_field=True))
return record or {}
Loading