<?php
namespace Virgin\ProductModelExtension\Services;
use DateInterval;
use DateTime;
use DateTimeImmutable;
use Exception;
use Shopware\Core\Checkout\Promotion\Aggregate\PromotionDiscount\PromotionDiscountEntity;
use Shopware\Core\Checkout\Promotion\Exception\DiscountCalculatorNotFoundException;
use Shopware\Core\Checkout\Promotion\PromotionEntity;
use Shopware\Core\Content\Product\ProductEntity;
use Shopware\Core\Framework\DataAbstractionLayer\EntityRepository;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Criteria;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\EqualsAnyFilter;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\EqualsFilter;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\MultiFilter;
use Shopware\Core\Framework\Rule\Exception\UnsupportedOperatorException;
use Shopware\Core\Framework\Rule\Rule;
use Shopware\Core\System\SalesChannel\SalesChannelContext;
use Swag\PayPal\PayPal\Api\Payment\Transaction\RelatedResource\Sale;
use Symfony\Component\HttpFoundation\Session\Session;
use Symfony\Contracts\Translation\TranslatorInterface;
use Virgin\ProductModelExtension\Custom\ProductType\ProductTypeEntity;
use Virgin\ProductModelExtension\Custom\Service\Configuration\ConfigurationEntity;
use Virgin\ProductModelExtension\Custom\Service\ServiceEntity;
use Virgin\SystemIntegration\Services\RestApiClient;
class ProductService
{
const string ALL_BASE_SERVICES = 'Servizi del Club';
const string ALL_BASE_SERVICES_DESCRIPTION = 'Elenco dei servizi base inclusi';
const string SERVICE_DIGITAL_WORKOUT = 'Allenamento Digitale';
const string SERVICE_BOOKING = 'Priority Booking';
const string SERVICE_ALTER_EGO = 'Alter Ego';
const string SERVICE_MULTICLUB = 'Multiclub';
const string SERVICE_ASCIUGAMANO = 'Asciugamano';
const string SERVICE_KIT_DOCCIA = 'Kit Doccia';
const string SERVICE_GUESTPASS_REVOLUTION = 'Guest Pass Revolution';
const string SERVICE_GUESTPASS_AMICO = 'Guest Pass Amico';
const string BOCCONI_STRING = 'BOCCONI';
/**
* @var EntityRepository
*/
private EntityRepository $productRepository;
/**
* @var EntityRepository
*/
private EntityRepository $durationRepository;
/**
* @var EntityRepository
*/
private EntityRepository $serviceLevelRepository;
/**
* @var EntityRepository
*/
private EntityRepository $serviceRepository;
/**
* @var EntityRepository
*/
private EntityRepository $mediaRepository;
/**
* @var EntityRepository
*/
private EntityRepository $promotionRepository;
/**
* @var EntityRepository
*/
private EntityRepository $ruleConditionRepository;
/**
* @var RestApiClient
*/
private RestApiClient $restApiClient;
/**
* @var Session
*/
private $session;public function __construct(
EntityRepository $productRepository,
EntityRepository $durationRepository,
EntityRepository $serviceLevelRepository,
EntityRepository $serviceRepository,
EntityRepository $mediaRepository,
EntityRepository $promotionRepository,
EntityRepository $ruleConditionRepository,
RestApiClient $restApiClient
,
Session $session
)
{
$this->productRepository = $productRepository;
$this->durationRepository = $durationRepository;
$this->serviceLevelRepository = $serviceLevelRepository;
$this->serviceRepository = $serviceRepository;
$this->mediaRepository = $mediaRepository;
$this->promotionRepository = $promotionRepository;
$this->ruleConditionRepository = $ruleConditionRepository;
$this->restApiClient = $restApiClient;
$this->session = $session;
}
/**
* @param ProductEntity $product
* @param SalesChannelContext $salesChannelContext
* @param null $duration
* @param null $prorataDate
* @return array
* @throws Exception
*/
public function getProductCardInformation(ProductEntity $product, SalesChannelContext $salesChannelContext, $duration = null, $prorataDate = null): array
{
$productConfigurations = $this->getProductConfigurations($product, $salesChannelContext);
$services = $productConfigurations['services'];
$workouts = $productConfigurations['workouts'];
$promo = $this->getPromoInfo($product, $salesChannelContext);
//todo remove session
if (isset($_SESSION['exerp_promotion_code'])) {
unset($_SESSION['exerp_promotion_code']);
}
$prices = $this->getProductPrices($product, $salesChannelContext, $promo, $prorataDate);
$level = $this->serviceLevelRepository->search(new Criteria(array_filter([$product->getExtensions()['foreignKeys']->jsonSerialize()['serviceLevelId']])), $salesChannelContext->getContext())->first();
if ($product->getExtensions() && isset($product->getExtensions()['duration']) && $product->getExtensions()['duration']!=null) {
$durationValue = $product->getExtensions()['duration']->getName();
} else {
$duration = $this->durationRepository->search(new Criteria(array_filter([$product->getExtensions()['foreignKeys']->jsonSerialize()['durationId']])), $salesChannelContext->getContext())->first();
$durationValue = $duration->getName();
}
return [
'product' => $product,
'useAdminFee' => array_key_exists('use_admin_fee', $product->getCustomFields()) && $product->getCustomFields()['use_admin_fee'],
'services' => $services,
'workouts' => $workouts,
'prices' => $prices,
'upgrades' => null,
'level' => $level->getPriority(),
'levelName' => $level->getName(),
'promo' => $promo,
'duration' => $durationValue
];
}
/**
* @param ProductEntity $product
* @param SalesChannelContext $salesChannelContext
* @return array
*/
private function getProductConfigurations(ProductEntity $product, SalesChannelContext $salesChannelContext): array
{
$services = [];
if ($this->isDigital($product)){
$mainServiceList = [self::SERVICE_GUESTPASS_REVOLUTION];
$otherServiceList = [];
} else {
$mainServiceList = [
self::ALL_BASE_SERVICES,
self::SERVICE_DIGITAL_WORKOUT,
self::SERVICE_BOOKING,
self::SERVICE_MULTICLUB,
self::SERVICE_ALTER_EGO,
];
$otherServiceList = [
self::SERVICE_ASCIUGAMANO,
self::SERVICE_KIT_DOCCIA,
self::SERVICE_GUESTPASS_AMICO,
];
}
$mainServices = [];
$otherServices = [];
$workouts = [];
foreach ($mainServiceList as $mainServiceName) {
$item = [];
if (self::ALL_BASE_SERVICES == $mainServiceName) {
$item['name'] = self::ALL_BASE_SERVICES;
$item['modalInfo'] = [
'id' => str_replace(strtolower(self::ALL_BASE_SERVICES), ' ', '-'),
'title' => self::ALL_BASE_SERVICES,
'description' => self::ALL_BASE_SERVICES_DESCRIPTION
];
$item['services'] = [];
$item['active'] = true;
} else {
$service = $this->getServiceByName($mainServiceName, $salesChannelContext);
if ($service){
$item['name'] = $service->getName();
$item['modalInfo'] = [
'id' => $service->getId(),
'title' => $service->getTitle(),
'title2' => $service->getTitle2(),
'description' => $service->getDescription(),
'media' => $service->getImage()
];
$item['position'] = $service->getPosition();
$item['active'] = false;
}
}
$mainServices[$mainServiceName] = $item;
}
foreach ($otherServiceList as $otherServiceName){
$service = $this->getServiceByName($otherServiceName, $salesChannelContext);
if ($service){
$item['name'] = $service->getName();
$item['modalInfo'] = [
'id' => $service->getId(),
'title' => $service->getTitle(),
'title2' => $service->getTitle2(),
'description' => $service->getDescription(),
'media' => $service->getImage()
];
$item['position'] = $service->getPosition();
$item['active'] = false;
$otherServices[$otherServiceName] = $item;
}
}
if ($product->getExtension('configurations')) {
$configurations = $product->getExtension('configurations')->getElements();
/** @var ConfigurationEntity $configuration */
foreach ($configurations as $configuration) {
$service = $this->getServiceById($configuration->getServiceId(), $salesChannelContext);
if ($service) {
if (isset($mainServices[$service->getName()])) {
$mainServices[$service->getName()]['active'] = true;
$mainServices[$service->getName()]['bannerText'] = $configuration->getLabel();
$mainServices[$service->getName()]['name'] = $service->getName();
$mainServices[$service->getName()]['bannerText'] = $configuration->getLabel();
$mainServices[$service->getName()]['modalInfo'] = [
'id' => $service->getId(),
'title' => $service->getTitle(),
'title2' => $service->getTitle2(),
'description' => $service->getDescription(),
'media' => $service->getImage()
];
} else if (isset($otherServices[$service->getName()])) {
$otherServices[$service->getName()]['active'] = true;
$otherServices[$service->getName()]['bannerText'] = $configuration->getLabel();
$otherServices[$service->getName()]['name'] = $service->getName();
$otherServices[$service->getName()]['bannerText'] = $configuration->getLabel();
$otherServices[$service->getName()]['modalInfo'] = [
'id' => $service->getId(),
'title' => $service->getTitle(),
'title2' => $service->getTitle2(),
'description' => $service->getDescription(),
'media' => $service->getImage()
];
} else {
$item = [];
$item['name'] = $service->getName();
$item['bannerText'] = $configuration->getLabel();
$item['modalInfo'] = [
'id' => $service->getId(),
'title' => $service->getTitle(),
'title2' => $service->getTitle2(),
'description' => $service->getDescription(),
'media' => $service->getImage()
];
$item['position'] = $service->getPosition();
$item['active'] = $configuration->getIncluded();
if ($service->getWorkout()) {
$workouts[] = $item;
} else if ($configuration->getBase()) {
$mainServices[self::ALL_BASE_SERVICES]['services'][] = $item;
}
}
}
}
if ($this->isDigital($product)) {
$otherServices = $workouts;
}
$services = ["main" => $mainServices, "otherServices" => $otherServices];
}
if (isset($workouts)) {
uasort($workouts, function ($a, $b) {
return $a['position'] - $b['position'];
});
}
return ["services" => $services, "workouts" => $workouts ?? []];
}
/**
* @param string $name
* @param SalesChannelContext $salesChannelContext
* @return ServiceEntity|null
*/
private function getServiceByName(string $name, SalesChannelContext $salesChannelContext): ?ServiceEntity
{
$criteria = new Criteria();
$criteria->addFilter(new EqualsFilter('service.name', $name));
$criteria->addAssociation('image');
return $this->serviceRepository->search($criteria, $salesChannelContext->getContext())->first();
}
/**
* @param string $serviceId
* @param SalesChannelContext $salesChannelContext
* @return ServiceEntity|null
*/
private function getServiceById(string $serviceId, SalesChannelContext $salesChannelContext): ?ServiceEntity
{
$criteria = new Criteria();
$criteria->addFilter(new EqualsFilter('service.id', $serviceId));
$criteria->addAssociation('image');
return $this->serviceRepository->search($criteria, $salesChannelContext->getContext())->first();
}
/**
* @param ProductEntity $product
* @param SalesChannelContext $salesChannelContext
* @return array[]
*/
public function getPromoInfo(ProductEntity $product, SalesChannelContext $salesChannelContext): array
{
$customerId = $salesChannelContext->getCustomer()?->getId();
$requiredDalAssociations = ['personaRules', 'personaCustomers', 'cartRules', 'orderRules', 'discounts.discountRules', 'discounts.promotionDiscountPrices', 'setgroups', 'setgroups.setGroupRules',];
$criteria = new Criteria();
foreach ($requiredDalAssociations as $association) {
$criteria->addAssociation($association);
}
$criteria->addAssociation('virginPromotionAttributes');
$criteria->addFilter(new MultiFilter(MultiFilter::CONNECTION_AND, [new EqualsFilter('useCodes', 0), new EqualsFilter('useIndividualCodes', 0), new EqualsFilter('active', 1),]));
$promos = $this->promotionRepository->search($criteria, $salesChannelContext->getContext())->getElements();
$exerpPromo = [];
$swPromo = [];
/** @var PromotionEntity $promo */
foreach ($promos as $promo) {
$attributes = $promo->getExtensions()['virginPromotionAttributes']->getElements();
$attributes = reset($attributes);
if ($promo->isActive()
&& $this->isPromoValid($promo)
&& $promo->isOrderCountValid()
&& (
$promo->hasDiscount()
|| ($attributes && ($attributes)->getisExerpPromotion()))
&& (
($attributes && $attributes->getIsSpecialPromoFlow())
|| ($customerId && $promo->isOrderCountPerCustomerCountValid($customerId)))
) {
$cartRules = $promo->getCartRules();
$personaRules = $promo->getPersonaRules();
$promoCartValid = true;
$promoUserValid = true;
foreach ($cartRules as $rule) {
$criteria = new Criteria();
$criteria->addFilter(new EqualsFilter('rule_condition.ruleId', $rule->getId()));
$criteria->addFilter(new MultiFilter(MultiFilter::CONNECTION_OR, [new EqualsFilter('rule_condition.type', 'cartLineItemsInCart'), new EqualsFilter('rule_condition.type', 'cartLineItem'), new EqualsFilter('rule_condition.type', 'cartLineItemTag'),]));
$condition = $this->ruleConditionRepository->search($criteria, $salesChannelContext->getContext())->first();
$promoCartValid = false;
if ($condition) {
if ($condition->getType() == 'cartLineItemTag') {
if ($product->getTags() && count($product->getTags()->getElements()) != 0) {
foreach ($product->getTagIds() as $tag) {
if ($this->match($condition->getValue()['operator'], $condition->getValue()['identifiers'], [$tag])) {
$promoCartValid = true;
break;
}
}
}
} else {
if ($this->match($condition->getValue()['operator'], $condition->getValue()['identifiers'], [$product->getId()])) {
$promoCartValid = true;
}
}
}
}
foreach ($personaRules as $rule) {
$criteria = new Criteria();
$criteria->addFilter(new MultiFilter(MultiFilter::CONNECTION_AND, [new EqualsFilter('rule_condition.type', 'customerCustomerGroup'), new EqualsFilter('rule_condition.ruleId', $rule->getId()),]));
$condition = $this->ruleConditionRepository->search($criteria, $salesChannelContext->getContext())->first();
if ($condition) {
if (isset($_SESSION['gift_user_params']) && str_contains(strtolower($salesChannelContext->getCurrentCustomerGroup()->getName()), strtolower(self::BOCCONI_STRING))) {
$customerGroupHasPromo = $this->match($condition->getValue()['operator'], $condition->getValue()['customerGroupIds'], [$_SESSION['gift_user_params']['customerGroupId']]);
} else {
$customerGroupHasPromo = $this->match($condition->getValue()['operator'], $condition->getValue()['customerGroupIds'], [$salesChannelContext->getCurrentCustomerGroup()->getId()]);
}
if ($customerGroupHasPromo) {
$promoUserValid = true;
} else {
$promoUserValid = false;
}
}
}
if ($promoUserValid && $promoCartValid) {
$attributes = $promo->getExtensions()['virginPromotionAttributes']->getElements();
if (count($attributes) && reset($attributes)->getisExerpPromotion()) {
$exerpPromo[] = $promo;
} else {
$swPromo[] = $promo;
}
}
}
}
return ['exerpPromo' => $exerpPromo, 'swPromo' => $swPromo];
}
/**
* @param PromotionEntity $promo
* @return bool
*/
private function isPromoValid(PromotionEntity $promo): bool
{
$now = new DateTime("now");
$dateValid = $promo->getValidFrom() === null || ($promo->getValidFrom() !== null && $now > $promo->getValidFrom());
if ($promo->getValidUntil() !== null) {
$dateValid = $dateValid && $now < $promo->getValidUntil();
}
if ($this->session->get('prorata_date') && $promo->getValidUntil() && $this->session->get('prorata_date') > $promo->getValidUntil()->getTimestamp()) {
return false;
}
return $dateValid;
}
/**
* @param $operator
* @param $identifiers
* @param $target
* @return bool
*/
public function match($operator, $identifiers, $target): bool
{
return match ($operator) {
Rule::OPERATOR_EQ => !empty(array_intersect($identifiers, $target)),
Rule::OPERATOR_NEQ => empty(array_intersect($identifiers, $target)),
default => throw new UnsupportedOperatorException($operator, Rule::class),
};
}
/**
* @param ProductEntity $product
* @param SalesChannelContext $salesChannelContext
* @param null $promo
* @param string|null $prorataDate
* @return array
* @throws Exception
*/
public function getProductPrices(ProductEntity $product, SalesChannelContext $salesChannelContext, $promo = null, string $prorataDate = null): array
{
$prorataDate = $prorataDate ?? date('Y-m-d');
if (isset($product->getExtensions()['productType']) && $product->getExtensions()['productType']->getName() == ProductTypeEntity::SUBSCRIPTION) {
if (isset($product->getExtensions()['club'])) {
if ($product->getExtensions()['club']->getIsPresale()) {
$prorataDate = $product->getExtensions()['club']->getPurchaseDate()->format('Y-m-d');
}
}
} elseif (isset($product->getExtensions()['productType']) && $product->getExtensions()['productType']->getName() == ProductTypeEntity::REVOLUTION_DIGITALE) {
if (isset($product->getCustomFields()['free_trial_days']) && $product->getCustomFields()['free_trial_days'] > 0) {
$prorataDate = (new DateTimeImmutable())->add(new DateInterval('PT' . ($product->getCustomFields()['free_trial_days'] * 24) . 'H'))->format('Y-m-d');
}
}
$basePrice = $product->getPrice()->getElements()[$salesChannelContext->getCurrency()->getId()]->getGross();
$infoSub = $this->getProrataActivationPrices($product, $prorataDate);
if (!isset($infoSub->status) && $infoSub != null) {
$activationPrices = ['activationBase' => (float)$infoSub->creationPrice, 'activationPromo' => (float)$infoSub->creationNormalPrice];
$prorataPrices = ['prorataBase' => (float)$infoSub->proRataPrice, 'prorataPromo' => (float)$infoSub->proRataSponsoredAmount];
$type = $product->getCustomFields()['virgin_exerp_type'];
if ($type == "CASH") {
if (isset($product->getExtensions()['productType']) && $product->getExtensions()['productType']->getName() == ProductTypeEntity::SUBSCRIPTION) {
if (array_key_exists('use_admin_fee', $product->getCustomFields()) && $product->getCustomFields()['use_admin_fee'] == true) {
$basePrice = (float)$infoSub->totalAmount - (float)$infoSub->creationPrice - (float)$infoSub->adminFeePrice;
} else {
$basePrice = (float)$infoSub->totalAmount - (float)$infoSub->creationPrice;
}
} else {
$basePrice = (float)$infoSub->totalAmount;
}
} else {
$basePrice = (float)($infoSub->startupCampaignPrice ?? $infoSub->normalPeriodPrice);
}
}
if (isset($promo) && (count($promo['swPromo']) > 0 || count($promo['exerpPromo']) > 0)) {
$promoPrices = $this->getPromoPrice($product, $salesChannelContext, $promo, $prorataDate);
if (empty($promoPrices['firstDeductionDate'])) {
$promoPrices['firstDeductionDate'] = $infoSub->firstDeductionDate;
}
} else {
$promoPrices = ['prorata' => $prorataPrices['prorataBase'] ?? 0, 'activation' => $activationPrices['activationBase'] ?? 0, 'adminFee' => $infoSub->adminFeePrice ?? 0, 'product' => $basePrice, 'firstDeductionDate' => $infoSub->firstDeductionDate ?? $prorataDate,];
}
return ['prorataDate' => $prorataDate, 'isPresale' => ($product->getExtensions()['club']??null) && $product->getExtensions()['club']->getIsPresale(),'adminFee' => $infoSub->adminFeePrice ?? 0, 'prorata' => $prorataPrices ?? 0, 'activation' => $activationPrices ?? 0, 'base_price' => $basePrice, 'promo_price' => $promoPrices ?? null, 'first_deduction_date' => $promoPrices['firstDeductionDate'],];
}
/**
* @param ProductEntity $product
* @param $prorataDate
* @param $promoCode
* @return mixed
* @throws \DateMalformedStringException
*/
public function getProrataActivationPrices(ProductEntity $product, $prorataDate, $promoCode = null): mixed
{
$prorataDate = $prorataDate < (new DateTime())->format('Y-m-d') ? (new DateTime())->format('Y-m-d') : $prorataDate;
$dateTime = new DateTime($prorataDate);
// presale deve essere false
if (!(($product->getExtensions()['club'] ?? null)?->getIsPresale()) && $dateTime->format('j') === '1'){
$prorataDate = $dateTime->format('Y-m-d');
}
$subReq = ['campainCode' => $promoCode ?? ($_SESSION['exerp_promotion_code'] ?? ''), 'centerId' => $product->getCustomFields()['virgin_exerp_centerid'], 'clearingHouseType' => $this->restApiClient::CLEARING_HOUSE_EFT, 'personType' => $this->restApiClient::PERSONTYPE_PRIVATE, 'starDate' => $prorataDate, 'subscriptionId' => $product->getCustomFields()['virgin_exerp_productid'],];
return $this->restApiClient->getSubscritionContractDetails($subReq);
}
/**
* @param ProductEntity $product
* @param SalesChannelContext $salesChannelContext
* @param $promotions
* @param $prorataDate
* @return array
*/
private function getPromoPrice(ProductEntity $product, SalesChannelContext $salesChannelContext, $promotions, $prorataDate): array
{
$infoSubBase = $this->getProrataActivationPrices($product, $prorataDate);
if (!isset($infoSubBase->status) && $infoSubBase != null) {
$prorataPrice = $infoSubBase->proRataPrice;
$activationPrice = $infoSubBase->creationPrice;
$adminFeePrice = $infoSubBase->adminFeePrice ?? 0;
$productPrice = (float)($infoSubBase->startupCampaignPrice ?? $infoSubBase->normalPeriodPrice);
}
foreach ($promotions['exerpPromo'] as $promo) {
$attributes = $promo->getExtensions()['virginPromotionAttributes']->getElements();
$infoSub = $this->getProrataActivationPrices($product, $prorataDate, reset($attributes)->getExerpCode());
$firstDeductionDate = $infoSub->firstDeductionDate;
if (!isset($infoSub->status) && $infoSub != null) {
$prorataPrice = $infoSub->proRataPrice;
$activationPrice = $infoSub->creationPrice;
$adminFeePrice = $infoSubBase->adminFeePrice ?? 0;
$productPrice = (float)($infoSub->startupCampaignPrice ?? $infoSub->normalPeriodPrice);
}
}
foreach ($promotions['swPromo'] as $promo) {
/** @var PromotionDiscountEntity $discount */
foreach ($promo->getDiscounts() as $discount) {
foreach ($discount->getDiscountRules()->getElements() as $discountRules) {
if (strtolower($discountRules->getName()) == 'attivazione') {
$type = 'activation';
}
if (strtolower($discountRules->getName()) == 'prorata') {
$type = 'prorata';
}
if (strtolower($discountRules->getName()) != 'prorata' && strtolower($discountRules->getName()) != 'attivazione') {
$type = 'product';
}
if (isset($type)) {
switch ($type) {
case 'activation':
$price = $activationPrice;
break;
case 'prorata':
$price = $prorataPrice;
break;
default:
$price = $productPrice;
}
} else {
$price = $productPrice;
}
switch ($discount->getType()) {
case PromotionDiscountEntity::TYPE_ABSOLUTE:
$newPrice = $price - $discount->getValue();
break;
case PromotionDiscountEntity::TYPE_PERCENTAGE:
$discountPrice = ($price * $discount->getValue()) / 100;
if (!is_null($discount->getMaxValue())) {
if (abs($discountPrice) > abs($discount->getMaxValue())) {
$newPrice = $price - $discount->getMaxValue();
} else {
$newPrice = $price - $discountPrice;
}
} else {
$newPrice = $price - $discountPrice;
}
break;
case PromotionDiscountEntity::TYPE_FIXED_UNIT:
case PromotionDiscountEntity::TYPE_FIXED:
$newPrice = $discount->getValue();
break;
default:
throw new DiscountCalculatorNotFoundException($discount->getType());
}
if (isset($type)) {
switch ($type) {
case 'activation':
$activationPrice = $newPrice;
break;
case 'prorata':
$prorataPrice = $newPrice;
break;
default:
$productPrice = $newPrice;
}
} else {
$productPrice = $newPrice;
}
}
}
}
return ['adminFee' => (float)$adminFeePrice, 'prorata' => (float)$prorataPrice, 'activation' => (float)$activationPrice, 'product' => (float)$productPrice, 'firstDeductionDate' => $firstDeductionDate ?? "",];
}
/**
* @param string $productId
* @param SalesChannelContext $salesChannelContext
* @return ProductEntity|null
*/
public function getProductById(string $productId, SalesChannelContext $salesChannelContext): ?ProductEntity
{
$criteria = new Criteria();
$criteria->addAssociation('configurations');
$criteria->addAssociation('productType');
$criteria->addAssociation('duration');
$criteria->addAssociation('tags');
$criteria->addAssociation('club');
$criteria->addAssociation('serviceLevel');
$criteria->addFilter(new EqualsFilter("id", $productId));
return $this->productRepository->search($criteria, $salesChannelContext->getContext())->first();
}
/**
* @param string $clubId
* @param array $tagIds
* @param SalesChannelContext $salesChannelContext
* @return array
*/
public function getProductsByTags(string $clubId, array $tagIds, SalesChannelContext $salesChannelContext): array
{
$realProductCriteria = new Criteria();
$realProductCriteria->addFilter(new EqualsFilter('product.clubId', $clubId));
if ($tagIds) {
$realProductCriteria->addFilter(new EqualsAnyFilter('product.tags.id', $tagIds));
}
$realProductCriteria->addFilter(new EqualsFilter('product.active', true));
$realProductCriteria->addAssociation('configurations');
$realProductCriteria->addAssociation('productType');
$realProductCriteria->addAssociation('duration');
$realProductCriteria->addAssociation('tags');
$realProductCriteria->addAssociation('club');
/** @var ProductEntity[] $realProductEntities */
return $this->productRepository->search($realProductCriteria, $salesChannelContext->getContext())->getElements();
}
private function getMediaById(string $imageId, SalesChannelContext $salesChannelContext)
{
$criteria = new Criteria();
$criteria->addFilter(new EqualsFilter('media.id', $imageId));
return $this->mediaRepository->search($criteria, $salesChannelContext->getContext())->first();
}
/**
* @param ProductEntity $productEntity
* @return bool
*/
public function isDigital(ProductEntity $productEntity): bool
{
/** @var ProductTypeEntity $productType */
$productType = $productEntity->getExtensions()['productType'];
if ($productType){
return $productType->getName()==ProductTypeEntity::REVOLUTION_DIGITALE;
}
return false;
}
}