/**
  * Populate product with variation of attributes
  *
  * @param \Magento\Catalog\Api\Data\ProductInterface $product
  * @param array $attributes
  * @return \Magento\Catalog\Api\Data\ProductInterface[]
  */
 public function create(\Magento\Catalog\Api\Data\ProductInterface $product, $attributes)
 {
     $variations = $this->variationMatrix->getVariations($attributes);
     $products = [];
     foreach ($variations as $variation) {
         $price = $product->getPrice();
         /** @var \Magento\Catalog\Model\Product $item */
         $item = $this->productFactory->create();
         $item->setData($product->getData());
         $suffix = '';
         foreach ($variation as $attributeId => $valueInfo) {
             $suffix .= '-' . $valueInfo['value'];
             $customAttribute = $this->customAttributeFactory->create()->setAttributeCode($attributes[$attributeId]['attribute_code'])->setValue($valueInfo['value']);
             $customAttributes = array_merge($item->getCustomAttributes(), [$attributes[$attributeId]['attribute_code'] => $customAttribute]);
             $item->setData('custom_attributes', $customAttributes);
             $priceInfo = $valueInfo['price'];
             $price += (!empty($priceInfo['is_percent']) ? $product->getPrice() / 100.0 : 1.0) * $priceInfo['pricing_value'];
         }
         $item->setPrice($price);
         $item->setName($product->getName() . $suffix);
         $item->setSku($product->getSku() . $suffix);
         $item->setVisibility(\Magento\Catalog\Model\Product\Visibility::VISIBILITY_NOT_VISIBLE);
         $products[] = $item;
     }
     return $products;
 }
 /**
  * Retrieve custom attributes values.
  *
  * @return \Magento\Framework\Api\AttributeInterface[]|null
  */
 public function getCustomAttributes()
 {
     $output = [];
     foreach ($this->getData() as $key => $value) {
         $attribute = $this->attributeValueFactory->create();
         $output[] = $attribute->setAttributeCode($key)->setValue($value);
     }
     return $output;
 }
 /**
  * Assign Kana to destination obj
  *
  * @param \Magento\Framework\Event\Observer $observer
  * @return $this
  */
 public function execute(\Magento\Framework\Event\Observer $observer)
 {
     $order = $observer->getEvent()->getSource();
     $target = $observer->getEvent()->getTarget();
     $fKana = $this->attributeValueFactory->create();
     $fKana->setAttributeCode('firstnamekana')->setValue($order->getFirstnamekana());
     $lKana = $this->attributeValueFactory->create();
     $lKana->setAttributeCode('lastnamekana')->setValue($order->getLastnamekana());
     $key = AbstractExtensibleObject::CUSTOM_ATTRIBUTES_KEY;
     $target->setData($key, ['firstnamekana' => $fKana, 'lastnamekana' => $lKana]);
     return $this;
 }
 /**
  * Convert custom attribute data array to array of AttributeValue Data Object
  *
  * @param array $customAttributesValueArray
  * @param string $dataObjectClassName
  * @return AttributeValue[]
  */
 protected function convertCustomAttributeValue($customAttributesValueArray, $dataObjectClassName)
 {
     $result = [];
     $dataObjectClassName = ltrim($dataObjectClassName, '\\');
     $camelCaseAttributeCodeKey = lcfirst(SimpleDataObjectConverter::snakeCaseToUpperCamelCase(AttributeValue::ATTRIBUTE_CODE));
     foreach ($customAttributesValueArray as $key => $customAttribute) {
         if (!is_array($customAttribute)) {
             $customAttribute = [AttributeValue::ATTRIBUTE_CODE => $key, AttributeValue::VALUE => $customAttribute];
         }
         if (isset($customAttribute[AttributeValue::ATTRIBUTE_CODE])) {
             $customAttributeCode = $customAttribute[AttributeValue::ATTRIBUTE_CODE];
         } elseif (isset($customAttribute[$camelCaseAttributeCodeKey])) {
             $customAttributeCode = $customAttribute[$camelCaseAttributeCodeKey];
         } else {
             $customAttributeCode = null;
         }
         //Check if type is defined, else default to string
         $type = $this->customAttributeTypeLocator->getType($customAttributeCode, $dataObjectClassName);
         $type = $type ? $type : TypeProcessor::ANY_TYPE;
         $customAttributeValue = $customAttribute[AttributeValue::VALUE];
         if (is_array($customAttributeValue)) {
             //If type for AttributeValue's value as array is mixed, further processing is not possible
             if ($type === TypeProcessor::ANY_TYPE) {
                 $attributeValue = $customAttributeValue;
             } else {
                 $attributeValue = $this->_createDataObjectForTypeAndArrayValue($type, $customAttributeValue);
             }
         } else {
             $attributeValue = $this->convertValue($customAttributeValue, $type);
         }
         //Populate the attribute value data object once the value for custom attribute is derived based on type
         $result[$customAttributeCode] = $this->attributeValueFactory->create()->setAttributeCode($customAttributeCode)->setValue($attributeValue);
     }
     return $result;
 }
 /**
  * {@inheritdoc}
  */
 public function setCustomAttribute($attributeCode, $attributeValue)
 {
     $isAlreadyAdded = false;
     /** @var \Magento\Framework\Api\AttributeInterface[] $attributes */
     $attributes = is_array($this->getCustomAttributes()) ? $this->getCustomAttributes() : [];
     foreach ($attributes as $attribute) {
         if ($attribute->getAttributeCode() === $attributeCode) {
             $attribute->setValue($attributeValue);
             $isAlreadyAdded = true;
             break;
         }
     }
     if (!$isAlreadyAdded) {
         $attributes[] = $this->attributeValueFactory->create()->setAttributeCode($attributeCode)->setValue($attributeValue);
     }
     return $this->setData(self::CUSTOM_ATTRIBUTES, $attributes);
 }
 /**
  *  Test get item with any type
  * @SuppressWarnings(PHPMD.UnusedLocalVariable)
  */
 public function testItemAnyType()
 {
     $this->_markTestAsRestOnly('Test will fail for SOAP because attribute values get converted to strings.');
     $customerAttributes = [Item::CUSTOM_ATTRIBUTE_1 => [AttributeValue::ATTRIBUTE_CODE => Item::CUSTOM_ATTRIBUTE_1, AttributeValue::VALUE => '12345'], Item::CUSTOM_ATTRIBUTE_2 => [AttributeValue::ATTRIBUTE_CODE => Item::CUSTOM_ATTRIBUTE_2, AttributeValue::VALUE => 12345], Item::CUSTOM_ATTRIBUTE_3 => [AttributeValue::ATTRIBUTE_CODE => Item::CUSTOM_ATTRIBUTE_3, AttributeValue::VALUE => true]];
     $attributeValue1 = $this->valueFactory->create()->setAttributeCode(Item::CUSTOM_ATTRIBUTE_1)->setValue('12345');
     $attributeValue2 = $this->valueFactory->create()->setAttributeCode(Item::CUSTOM_ATTRIBUTE_2)->setValue(12345);
     $attributeValue3 = $this->valueFactory->create()->setAttributeCode(Item::CUSTOM_ATTRIBUTE_3)->setValue(true);
     $item = $this->itemFactory->create()->setItemId(1)->setName('testProductAnyType')->setCustomAttributes([$attributeValue1, $attributeValue2, $attributeValue3]);
     $serviceInfo = ['rest' => ['resourcePath' => $this->_restResourcePath . 'itemAnyType', 'httpMethod' => \Magento\Framework\Webapi\Rest\Request::HTTP_METHOD_POST], 'soap' => ['service' => $this->_soapService, 'operation' => $this->_soapService . 'ItemAnyType']];
     $requestData = $item->__toArray();
     $item = $this->_webApiCall($serviceInfo, ['entityItem' => $requestData]);
     $this->assertSame($attributeValue1->getValue(), $item['custom_attributes'][0]['value'], 'Serialized attribute value type does\'t match pre-defined type.');
     // string '12345' is expected
     $this->assertSame($attributeValue2->getValue(), $item['custom_attributes'][1]['value'], 'Serialized attribute value type does\'t match pre-defined type.');
     // integer 12345 is expected
     $this->assertSame($attributeValue3->getValue(), $item['custom_attributes'][2]['value'], 'Serialized attribute value type does\'t match pre-defined type.');
     // boolean true is expected
 }
 /**
  * {@inheritdoc}
  */
 public function setCustomAttribute($attributeCode, $attributeValue)
 {
     $customAttributesCodes = $this->getCustomAttributesCodes();
     /* If key corresponds to custom attribute code, populate custom attributes */
     if (in_array($attributeCode, $customAttributesCodes)) {
         $attribute = $this->customAttributeFactory->create();
         $attribute->setAttributeCode($attributeCode)->setValue($attributeValue);
         $this->_data[self::CUSTOM_ATTRIBUTES][$attributeCode] = $attribute;
     }
     return $this;
 }
 /**
  * Set an attribute value for a given attribute code
  *
  * @param string $attributeCode
  * @param mixed $attributeValue
  * @return $this
  */
 public function setCustomAttribute($attributeCode, $attributeValue)
 {
     $customAttributesCodes = $this->getCustomAttributesCodes();
     /* If key corresponds to custom attribute code, populate custom attributes */
     if (in_array($attributeCode, $customAttributesCodes)) {
         /** @var AttributeValue $attribute */
         $attribute = $this->attributeValueFactory->create();
         $attribute->setAttributeCode($attributeCode)->setValue($attributeValue);
         $this->_data[AbstractExtensibleObject::CUSTOM_ATTRIBUTES_KEY][$attributeCode] = $attribute;
     }
     return $this;
 }
 /**
  * Convert custom attribute data array to array of AttributeValue Data Object
  *
  * @param array $customAttributesValueArray
  * @param string $dataObjectClassName
  * @return AttributeValue[]
  * @throws SerializationException
  */
 protected function convertCustomAttributeValue($customAttributesValueArray, $dataObjectClassName)
 {
     $result = [];
     $dataObjectClassName = ltrim($dataObjectClassName, '\\');
     foreach ($customAttributesValueArray as $key => $customAttribute) {
         if (!is_array($customAttribute)) {
             $customAttribute = [AttributeValue::ATTRIBUTE_CODE => $key, AttributeValue::VALUE => $customAttribute];
         }
         list($customAttributeCode, $customAttributeValue) = $this->processCustomAttribute($customAttribute);
         $type = $this->customAttributeTypeLocator->getType($customAttributeCode, $dataObjectClassName);
         if ($this->typeProcessor->isTypeAny($type) || $this->typeProcessor->isTypeSimple($type) || !is_array($customAttributeValue)) {
             try {
                 $attributeValue = $this->convertValue($customAttributeValue, $type);
             } catch (SerializationException $e) {
                 throw new SerializationException(new Phrase('Attribute "%attribute_code" has invalid value. %details', ['attribute_code' => $customAttributeCode, 'details' => $e->getMessage()]));
             }
         } else {
             $attributeValue = $this->_createDataObjectForTypeAndArrayValue($type, $customAttributeValue);
         }
         //Populate the attribute value data object once the value for custom attribute is derived based on type
         $result[$customAttributeCode] = $this->attributeValueFactory->create()->setAttributeCode($customAttributeCode)->setValue($attributeValue);
     }
     return $result;
 }