function it_marks_a_variant_group_as_updated_when_its_attributes_are_removed_or_updated($registry, EntityManager $em, ProductTemplateInterface $productTemplate, GroupInterface $group, GroupRepositoryInterface $groupRepo) { $productTemplate->getId()->willReturn(956); $registry->getRepository(Argument::type('string'))->willReturn($groupRepo); $groupRepo->getVariantGroupByProductTemplate($productTemplate)->willReturn($group); $this->guessUpdates($em, $productTemplate, UpdateGuesserInterface::ACTION_UPDATE_ENTITY)->shouldReturn([$group]); }
function it_updates_a_variant_group($attributeRepository, $groupTypeRepository, $productBuilder, GroupInterface $variantGroup, AttributeInterface $attribute, GroupTypeInterface $type, GroupTranslation $translatable, ProductInterface $product, ProductTemplateInterface $productTemplate) { $groupTypeRepository->findOneByIdentifier('VARIANT')->willReturn($type); $attributeRepository->findOneByIdentifier('main_color')->willReturn($attribute); $attributeRepository->findOneByIdentifier('secondary_color')->willReturn($attribute); $variantGroup->getTranslation()->willReturn($translatable); $translatable->setLabel('T-shirt super beau')->shouldBeCalled(); $variantGroup->setCode('mycode')->shouldBeCalled(); $variantGroup->setLocale('fr_FR')->shouldBeCalled(); $variantGroup->setType($type)->shouldBeCalled(); $variantGroup->getId()->willReturn(null); $variantGroup->addAxisAttribute(Argument::any())->shouldBeCalled(); $productTemplate->getValuesData()->willReturn([]); $productTemplate->setValues(Argument::any())->shouldBeCalled(); $productTemplate->setValuesData(['main_color' => [['locale' => null, 'scope' => null, 'data' => 'white']]])->shouldBeCalled(); $variantGroup->getProductTemplate()->willReturn($productTemplate); $variantGroup->setProductTemplate($productTemplate)->shouldBeCalled(); $productValue = new ProductValue(); $identifierValue = new ProductValue(); $productBuilder->createProduct()->willReturn($product); $product->getValues()->willReturn(new ArrayCollection([$productValue, $identifierValue])); $product->getIdentifier()->willReturn($identifierValue); $values = ['code' => 'mycode', 'axis' => ['main_color', 'secondary_color'], 'type' => 'VARIANT', 'labels' => ['fr_FR' => 'T-shirt super beau'], 'values' => ['main_color' => [['locale' => null, 'scope' => null, 'data' => 'white']]]]; $this->update($variantGroup, $values, []); }
function it_removes_attributes_from_a_product_template(ProductTemplateInterface $template, AttributeInterface $name) { $name->getCode()->willReturn('name'); $template->getValuesData()->willReturn(['name' => 'foo', 'color' => 'bar']); $template->setValuesData(['color' => 'bar'])->shouldBeCalled(); $this->removeAttribute($template, $name); }
/** * {@inheritdoc} */ public function update(ProductTemplateInterface $template, array $products) { $updates = $template->getValuesData(); foreach ($updates as $attributeCode => $values) { foreach ($values as $data) { $this->updateProducts($products, $attributeCode, $data); } } }
function it_updates_products_with_variant_group_template_values_using_product_updater($productFieldUpdater, ProductTemplateInterface $template, ProductInterface $product) { $updates = ['description' => [['locale' => 'en_US', 'scope' => 'ecommerce', 'data' => 'Foo'], ['locale' => 'en_US', 'scope' => 'mobile', 'data' => 'Bar']], 'color' => [['locale' => null, 'scope' => null, 'data' => 'red']], 'price' => [['locale' => 'fr_FR', 'scope' => null, 'data' => [['data' => 10, 'currency' => 'EUR'], ['data' => 20, 'currency' => 'USD']]]], 'image' => [['locale' => null, 'scope' => 'mobile', 'data' => ['filePath' => '/uploads/image.jpg', 'originalFilename' => 'Image.jpg']]]]; $template->getValuesData()->willReturn($updates); $productFieldUpdater->setData($product, 'description', 'Foo', ['locale' => 'en_US', 'scope' => 'ecommerce'])->shouldBeCalled(); $productFieldUpdater->setData($product, 'description', 'Bar', ['locale' => 'en_US', 'scope' => 'mobile'])->shouldBeCalled(); $productFieldUpdater->setData($product, 'color', 'red', ['locale' => null, 'scope' => null])->shouldBeCalled(); $productFieldUpdater->setData($product, 'price', [['data' => 10, 'currency' => 'EUR'], ['data' => 20, 'currency' => 'USD']], ['locale' => 'fr_FR', 'scope' => null])->shouldBeCalled(); $productFieldUpdater->setData($product, 'image', ['filePath' => '/uploads/image.jpg', 'originalFilename' => 'Image.jpg'], ['locale' => null, 'scope' => 'mobile'])->shouldBeCalled(); $this->update($template, [$product]); }
function it_updates_normalized_product_template_values_if_media_values_have_been_handled($normalizer, ProductTemplateInterface $imageTemplate, ProductTemplateInterface $textTemplate, ProductValueInterface $imageValue, ProductValueInterface $textValue, FileInfoInterface $imageMedia) { $normalizer->normalize(Argument::cetera())->willReturn([]); $imageTemplate->getValues()->willReturn([$imageValue]); $imageValue->getMedia()->willReturn($imageMedia); $imageMedia->isRemoved()->willReturn(true); $imageValue->setMedia(null)->shouldBeCalled(); $imageTemplate->setValuesData([])->shouldBeCalled(); $textTemplate->getValues()->willReturn([$textValue]); $textTemplate->setValuesData([])->shouldNotBeCalled(); $this->handleProductTemplateMedia($imageTemplate); $this->handleProductTemplateMedia($textTemplate); }
/** * Build product values from template values raw data * * @param ProductTemplateInterface $template * @param AttributeInterface[] $attributes * @param string $locale * * @return ProductValueInterface[] */ protected function buildProductValuesFromTemplateValuesData(ProductTemplateInterface $template, array $attributes, $locale) { $options = ['locale' => $locale, 'disable_grouping_separator' => true]; $values = $this->denormalizer->denormalize($template->getValuesData(), 'ProductValue[]', 'json', $options); $product = new $this->productClass(); foreach ($values as $value) { $product->addValue($value); } foreach ($attributes as $attribute) { $this->productBuilder->addAttributeToProduct($product, $attribute); } $this->productBuilder->addMissingProductValues($product); return $product->getValues(); }
function it_normalizes_a_variant_group_with_its_values($transNormalizer, $valuesDenormalizer, $group, GroupTypeInterface $groupType, AttributeInterface $attr, ProductTemplateInterface $productTemplate) { $groupType->getCode()->willReturn('VARIANT'); $groupType->isVariant()->willReturn(true); $group->getCode()->willReturn('laser_sabers'); $valuesData = ['name' => 'Light saber model', 'size' => '120']; $context = ['with_variant_group_values' => true]; $format = 'csv'; $productTemplate->getValuesData()->willReturn($valuesData); $group->getProductTemplate()->willReturn($productTemplate); $group->getType()->willReturn($groupType); $attr->getCode()->willReturn('light_color'); $group->getAxisAttributes()->willReturn([$attr]); $transNormalizer->normalize($group, $format, $context)->willReturn([]); $this->normalize($group, $format, $context)->shouldReturn(['code' => 'laser_sabers', 'type' => 'VARIANT', 'axis' => ['light_color'], 'values' => ['name' => 'Light saber model', 'size' => '120']]); }
function it_skips_a_variant_group_when_object_is_invalid($repository, $variantUpdater, $validator, GroupInterface $variantGroup, ProductTemplateInterface $productTemplate, ConstraintViolationListInterface $violationList) { $repository->getIdentifierProperties()->willReturn(['code']); $repository->findOneByIdentifier(Argument::any())->willReturn($variantGroup); $groupType = new GroupType(); $groupType->setVariant(true); $productTemplate->getValues()->willReturn(new ArrayCollection()); $variantGroup->getType()->willReturn($groupType); $variantGroup->getId()->willReturn(42); $variantGroup->getProductTemplate()->willReturn($productTemplate); $values = $this->getValues(); $variantUpdater->update($variantGroup, $values)->shouldBeCalled(); $validator->validate($variantGroup)->willReturn($violationList); $this->process($values)->shouldReturn($variantGroup); $variantUpdater->update($variantGroup, $values)->willThrow(new \InvalidArgumentException('Attributes: This property cannot be changed.')); $violation = new ConstraintViolation('Error', 'foo', [], 'bar', 'code', 'mycode'); $violations = new ConstraintViolationList([$violation]); $validator->validate($variantGroup)->willReturn($violations); $this->shouldThrow('Akeneo\\Component\\Batch\\Item\\InvalidItemException')->during('process', [$values]); }
/** * Filter empty values that are not used in a template then denormalize the product values objects from CSV fields * * @param array $rawProductValues * @param ProductTemplateInterface $template * * @return ProductValueInterface[] */ protected function denormalizeValuesFromItemData(array $rawProductValues, ProductTemplateInterface $template = null) { $templateCodes = null !== $template ? array_keys($template->getValuesData()) : []; foreach ($rawProductValues as $index => $data) { $attributeInfos = $this->fieldNameBuilder->extractAttributeFieldNameInfos($index); $attribute = $attributeInfos['attribute']; if ('' === trim($data) && !in_array($attribute->getCode(), $templateCodes)) { unset($rawProductValues[$index]); } } return $this->denormalizer->denormalize($rawProductValues, 'ProductValue[]', 'csv'); }
function it_has_attribute_in_a_variant_group_template(AttributeInterface $attribute, GroupInterface $group, GroupTypeInterface $groupType, ArrayCollection $groupAttributes, ProductTemplateInterface $template) { $groupType->isVariant()->willReturn(true); $groupAttributes->contains($attribute)->willReturn(false); $template->hasValueForAttribute($attribute)->shouldBeCalled()->willReturn(true); $group->getType()->willReturn($groupType); $group->getProductTemplate()->willReturn($template); $group->getAxisAttributes()->willReturn($groupAttributes); $group->addProduct($this)->willReturn($this); $this->addGroup($group); $this->hasAttributeInVariantGroup($attribute)->shouldReturn(true); }
/** * Normalizes and returns the media values of a product template * * @param ProductTemplateInterface|null $template * * @return \Pim\Component\Catalog\Model\ProductValueInterface[] */ protected function getProductTemplateMediaValues(ProductTemplateInterface $template = null) { if (null === $template) { return []; } $values = $this->denormalizer->denormalize($template->getValuesData(), 'ProductValue[]', 'json'); return $values->filter(function ($value) { return in_array($value->getAttribute()->getAttributeType(), [AttributeTypes::IMAGE, AttributeTypes::FILE]); })->toArray(); }
/** * Updates normalized product template values (required after handling new media added to a template) * * @param ProductTemplateInterface $template */ protected function updateNormalizedValues(ProductTemplateInterface $template) { $valuesData = $this->normalizer->normalize($template->getValues(), 'json', ['entity' => 'product']); $template->setValuesData($valuesData); }
function it_normalizes_a_variant_group_with_its_values_on_versioning_context($transNormalizer, $valuesDenormalizer, $group, CustomSerializer $serializer, GroupTypeInterface $groupType, AttributeInterface $attr, ProductTemplateInterface $productTemplate, ProductValueInterface $productValue1) { $groupType->getCode()->willReturn('VARIANT'); $groupType->isVariant()->willReturn(true); $group->getCode()->willReturn('lego'); $valuesData = ['name' => 'Light saber model', 'size' => '120']; $context = ['versioning' => true]; $format = 'csv'; $productTemplate->getValuesData()->willReturn($valuesData); $valuesDenormalizer->denormalize($valuesData, 'ProductValue[]', 'json')->willReturn([$productValue1]); $newContext = array_merge($context, ['with_variant_group_values' => true]); $serializer->normalize($productValue1, $format, ['entity' => 'product'] + $newContext)->willReturn(['age' => '6+']); $group->getProductTemplate()->willReturn($productTemplate); $group->getType()->willReturn($groupType); $attr->getCode()->willReturn('model'); $group->getAxisAttributes()->willReturn([$attr]); $transNormalizer->normalize($group, $format, $context)->willReturn([]); $this->setSerializer($serializer); $this->normalize($group, $format, $context)->shouldReturn(['code' => 'lego', 'type' => 'VARIANT', 'axis' => 'model', 'age' => '6+']); }
function it_updates_a_variant_group_and_skip_invalid_values($groupRepository, $denormalizer, $validator, $stepExecution, Group $variantGroup, GroupType $type, ProductTemplateInterface $template, ProductValueInterface $value, AttributeInterface $attribute) { $groupRepository->getIdentifierProperties()->willReturn(['code']); $groupRepository->findOneByIdentifier('tshirt')->willReturn($variantGroup); $variantGroup->getId()->willReturn(42); $variantGroup->getType()->willReturn($type); $type->isVariant()->willReturn(true); $denormalizer->denormalize(['code' => 'tshirt', 'axis' => 'color', 'label-en_US' => 'Tshirt', 'type' => 'VARIANT'], 'Pim\\Bundle\\CatalogBundle\\Entity\\Group', 'csv', ['entity' => $variantGroup])->shouldBeCalled()->willReturn($variantGroup); $template->getValuesData()->willReturn([]); $variantGroup->getProductTemplate()->willReturn($template); $denormalizer->denormalize(['name' => 'Nice product'], 'ProductValue[]', 'csv')->shouldBeCalled()->willReturn(new ArrayCollection([$value])); $value->getAttribute()->willReturn($attribute); $attribute->getCode()->willReturn('name'); $violation = new ConstraintViolation('There is a small problem', 'foo', [], 'bar', 'name', 'Nice product'); $violations = new ConstraintViolationList([$violation]); $validator->validate($value)->shouldBeCalled()->willReturn($violations); $stepExecution->incrementSummaryInfo('skip')->shouldBeCalled(); $this->shouldThrow(new InvalidItemException("name: There is a small problem: Nice product\n", ['code' => 'tshirt', 'axis' => 'color', 'label-en_US' => 'Tshirt', 'name' => 'Nice product', 'type' => 'VARIANT']))->duringProcess(['code' => 'tshirt', 'axis' => 'color', 'label-en_US' => 'Tshirt', 'name' => 'Nice product']); }
/** * {@inheritdoc} */ public function getVariantGroupByProductTemplate(ProductTemplateInterface $productTemplate) { $qb = $this->createQueryBuilder('g'); $qb->innerJoin('g.productTemplate', 'pt')->where($qb->expr()->eq('pt', ':productTemplate'))->setParameter(':productTemplate', $productTemplate->getId()); return $qb->getQuery()->getOneOrNullResult(); }