commercetools / commercetools-sync-java

Java library for importing and syncing (taking care of changes) data into one or more commercetools projects from external data files or from another commercetools project.
https://commercetools.github.io/commercetools-sync-java
Apache License 2.0
32 stars 37 forks source link

Reference resolution on CartDiscount target predicate #1155

Closed valtechtmn closed 9 months ago

valtechtmn commented 9 months ago

Hi again,

I'm trying to sync my cart discounts between two CT env. Source has a cart discount where the target predicate is an entity, say for example a Category. In such case the predicate is written like so :

"target": {
                "type": "lineItems",
                "predicate": "categories.id contains any (\"ac3a2023-7774-4b75-a2e9-113f6a6f2c9e\")"
            },

And it is also added in the references :

"references": [
                {
                    "typeId": "category",
                    "id": "ac3a2023-7774-4b75-a2e9-113f6a6f2c9e"
                }
            ]

But when attempting to sync we are faced with the following error :

http response formatted body: {
  "statusCode" : 400,
  "message" : "The referenced object of type 'category' with identifier '9a4e52cc-5346-4cfb-ba7e-21e1e46a9243' was not found. It either doesn't exist, or it can't be accessed from this endpoint (e.g., if the endpoint filters by store or customer account).",
  "errors" : [ {
    "code" : "ReferencedResourceNotFound",
    "message" : "The referenced object of type 'category' with identifier '9a4e52cc-5346-4cfb-ba7e-21e1e46a9243' was not found. It either doesn't exist, or it can't be accessed from this endpoint (e.g., if the endpoint filters by store or customer account).",
    "typeId" : "category",
    "id" : "9a4e52cc-5346-4cfb-ba7e-21e1e46a9243"
  } ]
}

This also happens with discount targeting products and I believe channels. I'm able to reproduce this behavior in an integration test on this repo. Am I again doing something wrong or is this a loophole in the CartDiscountSync ?

Thanks for your continued support !

lojzatran commented 9 months ago

Hi @valtechtmn

Thank you for reporting the issue. Can you link the integration test that reproduce this behaviour?

valtechtmn commented 9 months ago

Hi @lojzatran

Yep sorry just figured out how to do that : https://github.com/commercetools/commercetools-sync-java/pull/1156

lojzatran commented 9 months ago

Hi @valtechtmn

I had check your issue and we currently do not support syncing references in Cart discount.

The problem is that we would need to parse the predicate string itself to know if it contains references or not.

You also mentioned that the references are added as a field of cart discount. This field is added only for the cart discount that are already created in commercetools. This could work in a case of syncing from one project to another. On the other hand, when syncing from the external source, user has to supply CartDiscountDraft and there is no references field here. Therefore we would need to implement the predicate parsing.

I created an internal ticket for this problem, but I don‘t think we would do it any time soon. If you think this needs higher priority, please create a support ticket: https://support.commercetools.com/.

Thank you.

valtechtmn commented 9 months ago

Hi @lojzatran

Thanks for looking into this. That's unfortunate, about half of our CartDiscount target an entity making the sync not as powerful. But I understand that it would be quite a large amount of work to parse the predicate string to resolve the references. It might be worth adding a note in the documentation to highlight that this is not covered.

As a sidenote, if I was to attempt to implement this in my project, are there any utility code from your project that I should take a strong look at ? Particularly once I gather all the ids from the source environment to then get all the keys and find the corresponding ids on the target environment ?

Cheers

jenschude commented 9 months ago

Btw a solution could be to use a category.key instead of an id. They should stay stable across projects. I know it's some kind of effort to change the predicates, but we are limited here on the possibilities the API itself provides. https://docs.commercetools.com/api/projects/predicates#lineitem-field-identifiers

valtechtmn commented 9 months ago

Hi @jenschude

Are you saying that if I managed to modify all the references in target predicates from ID to KEY then the sync would be able to work smoothly ?

jenschude commented 9 months ago

In case the categories with the specific keys are in the target project it should work. The key field is meant for external identifiers. And you can keep the keys synchronized and stable across different projects as they are under your control.

valtechtmn commented 9 months ago

Oh yeah of course as long as the category is already there, and it should be since we sync categories as well, then there is no reference resolution needed. That's a decent compromise for now. Cheers.