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();
 }