packages/sylius-google-analytics-plugin/src/Factory/ItemFactory.php line 86

Open in your IDE?
  1. <?php
  2. /**
  3.  * @author Jakub Lech <info@smartbyte.pl>
  4.  *
  5.  * For the full copyright and license information, please view the LICENSE
  6.  * file that was distributed with this source code.
  7.  */
  8. declare(strict_types=1);
  9. namespace Spinbits\SyliusGoogleAnalytics4Plugin\Factory;
  10. use Spinbits\GoogleAnalytics4EventsDtoS\Item\Item;
  11. use Sylius\Component\Channel\Context\ChannelContextInterface;
  12. use Sylius\Component\Core\Model\Channel;
  13. use Sylius\Component\Core\Model\ChannelPricingInterface;
  14. use Sylius\Component\Core\Model\Order;
  15. use Sylius\Component\Core\Model\OrderItem;
  16. use Sylius\Component\Core\Model\Product;
  17. use Sylius\Component\Core\Model\ProductVariant;
  18. use Sylius\Component\Core\Model\Taxon;
  19. use Sylius\Component\Order\Model\OrderItemInterface;
  20. use Sylius\Component\Product\Model\ProductInterface;
  21. use Sylius\Component\Product\Model\ProductVariantInterface;
  22. use Sylius\Component\Currency\Context\CurrencyContextInterface;
  23. use Sylius\Component\Product\Resolver\ProductVariantResolverInterface;
  24. class ItemFactory
  25. {
  26.     private ChannelContextInterface $channelContext;
  27.     private CurrencyContextInterface $currencyContext;
  28.     private ProductVariantResolverInterface $productVariantResolver;
  29.     public function __construct(
  30.         ChannelContextInterface $channelContext,
  31.         CurrencyContextInterface $currencyContext,
  32.         ProductVariantResolverInterface $productVariantResolver
  33.     ) {
  34.         $this->channelContext $channelContext;
  35.         $this->currencyContext $currencyContext;
  36.         $this->productVariantResolver $productVariantResolver;
  37.     }
  38.     public function fromProductVariant(ProductVariantInterface $variant): Item
  39.     {
  40.         /** @var ProductVariant $variant */
  41.         /** @var Channel $channel */
  42.         $channel $this->channelContext->getChannel();
  43.         /** @var ChannelPricingInterface|null $pricing */
  44.         /** @var ProductVariant $variant */
  45.         $pricing $variant->getChannelPricingForChannel($channel);
  46.         $price $pricing->getPrice() ?? $pricing->getOriginalPrice() ?? 0;
  47.         /** @var Product|null $product */
  48.         $product $variant->getProduct();
  49.         /** @var Taxon|null $mainTaxon */
  50.         $mainTaxon $product->getMainTaxon();
  51.         return new Item(
  52.             (string) $variant->getId(),
  53.             (string) $variant->getCode(),
  54.             round($price/1002),
  55.             $this->currencyContext->getCurrencyCode(),
  56.             0,
  57.             1,
  58.             null,
  59.             null,
  60.             null,
  61.             null,
  62.             $this->getCategories($product),
  63.             '',
  64.             '',
  65.             $variant->getName(),
  66.             $channel->getName(),
  67.         );
  68.     }
  69.     public function fromProduct(ProductInterface $product): Item
  70.     {
  71.         if ($product->getEnabledVariants()->isEmpty()) {
  72.             return $this->returnMissingItem('variant missing for product '. (string) $product->getId());
  73.         }
  74.         /** @var ProductVariantInterface $variant */
  75.         $variant $this->productVariantResolver->getVariant($product);
  76.         return $this->fromProductVariant($variant);
  77.     }
  78.     public function fromOrderItem(OrderItemInterface $orderItem): Item
  79.     {
  80.         /** @var OrderItem $orderItem */
  81.         $variant $orderItem->getVariant();
  82.         if (null === $variant) {
  83.             return $this->returnMissingItem('variant missing for orderItem: '. (string) $orderItem->getId());
  84.         }
  85.         /** @var ProductVariantInterface $variant */
  86.         $item $this->fromProductVariant($variant);
  87.         $price = ($orderItem->getUnitPrice() > 0) ? $orderItem->getUnitPrice()/100 : (float) $item->getPrice()/100;
  88.         return $item
  89.             ->setQuantity($orderItem->getQuantity())
  90.             ->setPrice((float) $price)
  91.             ->setDiscount(($orderItem->getUnitPrice() - $orderItem->getFullDiscountedUnitPrice())/100)
  92.             ->setCoupon(implode(', '$this->getCoupons($orderItem)))
  93.             ;
  94.     }
  95.     private function getCategories(?ProductInterface $product): array
  96.     {
  97.         /** @var Product|null $product */
  98.         if (null === $product) {
  99.             return [];
  100.         }
  101.         $taxons = [];
  102.         /** @var Taxon $taxon */
  103.         foreach ($product->getTaxons() as $taxon) {
  104.             $taxons[] = (string) $taxon->getName();
  105.         }
  106.         return $taxons;
  107.     }
  108.     /**
  109.      * @param OrderItemInterface $orderItem
  110.      * @return array<array-key, string>
  111.      */
  112.     private function getCoupons(OrderItemInterface $orderItem): array
  113.     {
  114.         /** @var Order|null $order */
  115.         $order $orderItem->getOrder();
  116.         if (null === $order) {
  117.             return [];
  118.         }
  119.         $result = [];
  120.         foreach ($order->getPromotions() as $promotion)
  121.         {
  122.             $result[] = (string) $promotion->getName();
  123.         }
  124.         return $result;
  125.     }
  126.     private function returnMissingItem(string $message): Item
  127.     {
  128.         //we can not throw exception in this process so we return empty Item with notification
  129.         return new Item(
  130.             '0',
  131.             $message,
  132.             0,
  133.             $this->currencyContext->getCurrencyCode()
  134.         );
  135.     }
  136. }