use of com.commercetools.sync.products.AttributeMetaData in project commercetools-sync-java by commercetools.
the class ProductSyncUtilsTest method buildActions_FromDraftsWithSameForAllAttribute_ShouldBuildUpdateActions.
@Test
void buildActions_FromDraftsWithSameForAllAttribute_ShouldBuildUpdateActions() {
final ProductVariant masterVariant = oldProduct.getMasterVariant();
final AttributeDraft brandNameAttribute = AttributeDraft.of("brandName", "sameForAllBrand");
final ProductVariantDraft newMasterVariant = ProductVariantDraftBuilder.of(masterVariant).plusAttribute(brandNameAttribute).build();
final ProductVariantDraft variant = ProductVariantDraftBuilder.of().key("v2").sku("3065834").plusAttribute(brandNameAttribute).build();
final ProductDraft newProductDraft = createProductDraftBuilder(PRODUCT_KEY_1_WITH_PRICES_RESOURCE_PATH, ProductType.referenceOfId("anyProductType")).masterVariant(newMasterVariant).plusVariants(variant).build();
final Map<String, AttributeMetaData> attributesMetaData = new HashMap<>();
final AttributeMetaData brandName = AttributeMetaData.of(AttributeDefinitionBuilder.of("brandName", null, null).attributeConstraint(AttributeConstraint.SAME_FOR_ALL).build());
attributesMetaData.put("brandName", brandName);
final List<UpdateAction<Product>> updateActions = ProductSyncUtils.buildActions(oldProduct, newProductDraft, productSyncOptions, attributesMetaData);
// check that we only have one generated action for all the variants and no duplicates
// and is ordered correctly before addVariant action
assertThat(updateActions.size()).isEqualTo(3);
assertThat(updateActions).containsOnlyOnce(SetAttributeInAllVariants.of(AttributeDraft.of("brandName", "sameForAllBrand"), true));
assertThat(updateActions.get(0)).isEqualTo(SetAttributeInAllVariants.of(AttributeDraft.of("brandName", "sameForAllBrand"), true));
assertThat(updateActions.get(1)).isEqualTo(AddVariant.of(Arrays.asList(AttributeDraft.of("brandName", "sameForAllBrand")), null, "3065834", true).withKey("v2"));
assertThat(updateActions.get(2)).isEqualTo(Publish.of());
}
use of com.commercetools.sync.products.AttributeMetaData in project commercetools-sync-java by commercetools.
the class ProductUpdateActionUtilsTest method buildVariantsUpdateActions_doesNotRemoveMaster.
@Test
void buildVariantsUpdateActions_doesNotRemoveMaster() {
final ProductProjection productOld = createProductFromJson(OLD_PROD_WITH_VARIANTS);
final ProductDraft productDraftNew = createProductDraftFromJson(NEW_PROD_DRAFT_WITH_VARIANTS_MOVE_MASTER);
final ProductSyncOptions productSyncOptions = ProductSyncOptionsBuilder.of(mock(SphereClient.class)).syncFilter(SyncFilter.of()).build();
final Map<String, AttributeMetaData> attributesMetaData = new HashMap<>();
final AttributeMetaData priceInfo = AttributeMetaData.of(AttributeDefinitionBuilder.of("priceInfo", null, null).build());
attributesMetaData.put("priceInfo", priceInfo);
final List<UpdateAction<Product>> updateActions = buildVariantsUpdateActions(productOld, productDraftNew, productSyncOptions, attributesMetaData);
// check remove variants are the first in the list, but not the master variant
assertThat(updateActions.subList(0, 3)).containsExactlyInAnyOrder(RemoveVariant.ofVariantId(2, true), RemoveVariant.ofVariantId(3, true), RemoveVariant.ofVariantId(4, true));
// change master variant must be always after variants are added/updated,
// because it is set by SKU and we should be sure the master variant is already added and SKUs
// are actual.
assertThat(updateActions).endsWith(ChangeMasterVariant.ofSku("var-7-sku", true));
// Old master variant should NOT be removed because it exists in
// NEW_PROD_DRAFT_WITH_VARIANTS_MOVE_MASTER
final ProductVariant oldMasterVariant = productOld.getMasterVariant();
assertThat(updateActions).filteredOn(action -> {
// verify old master variant is not removed
if (action instanceof RemoveVariant) {
RemoveVariant removeVariantAction = (RemoveVariant) action;
return Objects.equals(oldMasterVariant.getId(), removeVariantAction.getId()) || Objects.equals(oldMasterVariant.getSku(), removeVariantAction.getSku());
}
return false;
}).isEmpty();
}
use of com.commercetools.sync.products.AttributeMetaData in project commercetools-sync-java by commercetools.
the class ProductUpdateActionUtils method collectAllVariantUpdateActions.
@Nonnull
private static List<UpdateAction<Product>> collectAllVariantUpdateActions(@Nonnull final List<UpdateAction<Product>> sameForAllUpdateActions, @Nonnull final ProductProjection oldProduct, @Nonnull final ProductDraft newProduct, @Nonnull final ProductVariant oldProductVariant, @Nonnull final ProductVariantDraft newProductVariant, @Nonnull final Map<String, AttributeMetaData> attributesMetaData, @Nonnull final ProductSyncOptions syncOptions) {
final ArrayList<UpdateAction<Product>> updateActions = new ArrayList<>();
final SyncFilter syncFilter = syncOptions.getSyncFilter();
updateActions.addAll(buildActionsIfPassesFilter(syncFilter, ATTRIBUTES, () -> emptyIfNull(buildProductVariantAttributesUpdateActions(oldProduct, newProduct, oldProductVariant, newProductVariant, attributesMetaData, syncOptions)).stream().filter(collectedUpdateAction -> hasDuplicateSameForAllAction(sameForAllUpdateActions, collectedUpdateAction)).collect(Collectors.toList())));
updateActions.addAll(buildActionsIfPassesFilter(syncFilter, IMAGES, () -> buildProductVariantImagesUpdateActions(oldProductVariant, newProductVariant)));
updateActions.addAll(buildActionsIfPassesFilter(syncFilter, PRICES, () -> buildProductVariantPricesUpdateActions(oldProduct, newProduct, oldProductVariant, newProductVariant, syncOptions)));
updateActions.addAll(buildActionsIfPassesFilter(syncFilter, ASSETS, () -> buildProductVariantAssetsUpdateActions(oldProduct, newProduct, oldProductVariant, newProductVariant, syncOptions)));
buildActionIfPassesFilter(syncFilter, SKU, () -> buildProductVariantSkuUpdateAction(oldProductVariant, newProductVariant)).ifPresent(updateActions::add);
return updateActions;
}
use of com.commercetools.sync.products.AttributeMetaData in project commercetools-sync-java by commercetools.
the class ProductVariantAttributeUpdateActionUtils method buildProductVariantAttributeUpdateAction.
/**
* Compares the attributes of a {@link AttributeDraft} and a {@link Attribute} to build either a
* {@link io.sphere.sdk.products.commands.updateactions.SetAttribute} or a {@link
* io.sphere.sdk.products.commands.updateactions.SetAttributeInAllVariants}.
*
* <p>If the attribute is sameForAll a {@link
* io.sphere.sdk.products.commands.updateactions.SetAttributeInAllVariants} is built. Otherwise, a
* {@link io.sphere.sdk.products.commands.updateactions.SetAttribute} is built.
*
* <p>If both the {@link AttributeDraft} and the {@link Attribute} have identical values, then no
* update action is needed and hence an empty {@link List} is returned.
*
* @param variantId the id of the variant of that the attribute belong to. It is used only in the
* error messages if any.
* @param oldProductVariantAttribute the {@link Attribute} which should be updated.
* @param newProductVariantAttribute the {@link AttributeDraft} where we get the new value.
* @param attributesMetaData a map of attribute name -> {@link AttributeMetaData}; which
* defines attribute information: its name and whether it has the constraint "SameForAll" or
* not.
* @return A filled optional with the update action or an empty optional if the attributes are
* identical.
* @throws BuildUpdateActionException thrown if attribute as not found in the {@code
* attributeMetaData} or if the attribute is required and the new value is null.
*/
@Nonnull
public static Optional<UpdateAction<Product>> buildProductVariantAttributeUpdateAction(final int variantId, @Nullable final Attribute oldProductVariantAttribute, @Nonnull final AttributeDraft newProductVariantAttribute, @Nonnull final Map<String, AttributeMetaData> attributesMetaData) throws BuildUpdateActionException {
final String newProductVariantAttributeName = newProductVariantAttribute.getName();
final JsonNode newProductVariantAttributeValue = newProductVariantAttribute.getValue();
final JsonNode oldProductVariantAttributeValue = oldProductVariantAttribute != null ? oldProductVariantAttribute.getValueAsJsonNode() : null;
final AttributeMetaData attributeMetaData = attributesMetaData.get(newProductVariantAttributeName);
if (attributeMetaData == null) {
final String errorMessage = format(ATTRIBUTE_NOT_IN_ATTRIBUTE_METADATA, newProductVariantAttributeName);
throw new BuildUpdateActionException(errorMessage);
}
return attributeMetaData.isSameForAll() ? buildUpdateAction(oldProductVariantAttributeValue, newProductVariantAttributeValue, () -> SetAttributeInAllVariants.of(newProductVariantAttribute, true)) : buildUpdateAction(oldProductVariantAttributeValue, newProductVariantAttributeValue, () -> SetAttribute.of(variantId, newProductVariantAttribute, true));
}
use of com.commercetools.sync.products.AttributeMetaData in project commercetools-sync-java by commercetools.
the class ProductSyncUtils method buildActions.
/**
* Compares all the fields (including the variants see {@link
* ProductUpdateActionUtils#buildVariantsUpdateActions(ProductProjection, ProductDraft,
* ProductSyncOptions, Map)}) of a {@link ProductProjection} and a {@link ProductDraft}, given
* that each of these fields pass the specified {@link SyncFilter}. It returns a {@link List} of
* {@link UpdateAction}<{@link Product}> as a result. If no update action is needed, for
* example in case where both the {@link ProductProjection} and the {@link ProductDraft} have the
* same names, an empty {@link List} is returned. Then it applies a specified filter function in
* the {@link ProductSyncOptions} instance on the resultant list and returns this result.
*
* @param oldProduct the productprojection which should be updated.
* @param newProduct the product draft where we get the new data.
* @param syncOptions the sync options wrapper which contains options related to the sync process
* supplied by the user. For example, custom callbacks to call in case of warnings or errors
* occurring on the build update action process. And other options (See {@link
* ProductSyncOptions} for more info).
* @param attributesMetaData a map of attribute name -> {@link AttributeMetaData}; which
* defines each attribute's information: its name and whether it has the constraint
* "SameForAll" or not.
* @return A list of product-specific update actions.
*/
@Nonnull
public static List<UpdateAction<Product>> buildActions(@Nonnull final ProductProjection oldProduct, @Nonnull final ProductDraft newProduct, @Nonnull final ProductSyncOptions syncOptions, @Nonnull final Map<String, AttributeMetaData> attributesMetaData) {
final SyncFilter syncFilter = syncOptions.getSyncFilter();
final List<UpdateAction<Product>> updateActions = new ArrayList<>(filterEmptyOptionals(buildActionIfPassesFilter(syncFilter, ActionGroup.NAME, () -> buildChangeNameUpdateAction(oldProduct, newProduct)), buildActionIfPassesFilter(syncFilter, ActionGroup.DESCRIPTION, () -> buildSetDescriptionUpdateAction(oldProduct, newProduct)), buildActionIfPassesFilter(syncFilter, ActionGroup.SLUG, () -> buildChangeSlugUpdateAction(oldProduct, newProduct)), buildActionIfPassesFilter(syncFilter, ActionGroup.SEARCHKEYWORDS, () -> buildSetSearchKeywordsUpdateAction(oldProduct, newProduct)), buildActionIfPassesFilter(syncFilter, ActionGroup.METATITLE, () -> buildSetMetaTitleUpdateAction(oldProduct, newProduct)), buildActionIfPassesFilter(syncFilter, ActionGroup.METADESCRIPTION, () -> buildSetMetaDescriptionUpdateAction(oldProduct, newProduct)), buildActionIfPassesFilter(syncFilter, ActionGroup.METAKEYWORDS, () -> buildSetMetaKeywordsUpdateAction(oldProduct, newProduct)), buildActionIfPassesFilter(syncFilter, ActionGroup.TAXCATEGORY, () -> buildSetTaxCategoryUpdateAction(oldProduct, newProduct).map(action -> (UpdateAction<Product>) action)), buildActionIfPassesFilter(syncFilter, ActionGroup.STATE, () -> buildTransitionStateUpdateAction(oldProduct, newProduct).map(action -> (UpdateAction<Product>) action))));
final List<UpdateAction<Product>> productCategoryUpdateActions = buildActionsIfPassesFilter(syncFilter, ActionGroup.CATEGORIES, () -> buildCategoryActions(oldProduct, newProduct));
updateActions.addAll(productCategoryUpdateActions);
updateActions.addAll(buildVariantsUpdateActions(oldProduct, newProduct, syncOptions, attributesMetaData));
// lastly publish/unpublish product
final boolean hasNewUpdateActions = updateActions.size() > 0;
buildPublishOrUnpublishUpdateAction(oldProduct, newProduct, hasNewUpdateActions).ifPresent(updateActions::add);
return prioritizeUpdateActions(updateActions, oldProduct.getMasterVariant().getId());
}
Aggregations