Skip to content

Commit

Permalink
[TASK] Refactor EventListener to use doctrine repositories
Browse files Browse the repository at this point in the history
  • Loading branch information
extcode committed Oct 11, 2024
1 parent 7a07278 commit 82460d6
Show file tree
Hide file tree
Showing 5 changed files with 152 additions and 112 deletions.
39 changes: 34 additions & 5 deletions Classes/Domain/DoctrineRepository/Product/BeVariantRepository.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
*/

use TYPO3\CMS\Core\Database\ConnectionPool;
use TYPO3\CMS\Core\Database\Query\QueryBuilder;

class BeVariantRepository
{
Expand All @@ -19,16 +20,44 @@ public function __construct(

public function getStock(int $uid): int
{
$queryBuilder = $this
->connectionPool
->getConnectionForTable('tx_cartproducts_domain_model_product_bevariant')
->createQueryBuilder();
$queryBuilder = $this->getQueryBuilder();

return $queryBuilder
->select('stock')
->from('tx_cartproducts_domain_model_product_bevariant')
->where(
$queryBuilder->expr()->eq('uid', $queryBuilder->createNamedParameter($uid, \PDO::PARAM_INT))
)->executeQuery()->fetchOne();
)
->orWhere(
$queryBuilder->expr()->eq('l10n_parent', $queryBuilder->createNamedParameter($uid, \PDO::PARAM_INT))
)
->executeQuery()
->fetchOne();
}

public function addQuantityToStock(int $uid, int $quantity): void
{
$currentStock = $this->getStock($uid);

$queryBuilder = $this->getQueryBuilder();

$queryBuilder
->update('tx_cartproducts_domain_model_product_bevariant')
->where(
$queryBuilder->expr()->eq('uid', $queryBuilder->createNamedParameter($uid, \PDO::PARAM_INT))
)
->orWhere(
$queryBuilder->expr()->eq('l10n_parent', $queryBuilder->createNamedParameter($uid, \PDO::PARAM_INT))
)
->set('stock', $currentStock - $quantity)
->executeStatement();
}

private function getQueryBuilder(): QueryBuilder
{
return $this
->connectionPool
->getConnectionForTable('tx_cartproducts_domain_model_product_bevariant')
->createQueryBuilder();
}
}
39 changes: 34 additions & 5 deletions Classes/Domain/DoctrineRepository/Product/ProductRepository.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
*/

use TYPO3\CMS\Core\Database\ConnectionPool;
use TYPO3\CMS\Core\Database\Query\QueryBuilder;

class ProductRepository
{
Expand All @@ -19,16 +20,44 @@ public function __construct(

public function getStock(int $uid): int
{
$queryBuilder = $this
->connectionPool
->getConnectionForTable('tx_cartproducts_domain_model_product_product')
->createQueryBuilder();
$queryBuilder = $this->getQueryBuilder();

return $queryBuilder
->select('stock')
->from('tx_cartproducts_domain_model_product_product')
->where(
$queryBuilder->expr()->eq('uid', $queryBuilder->createNamedParameter($uid, \PDO::PARAM_INT))
)->executeQuery()->fetchOne();
)
->orWhere(
$queryBuilder->expr()->eq('l10n_parent', $queryBuilder->createNamedParameter($uid, \PDO::PARAM_INT))
)
->executeQuery()
->fetchOne();
}

public function addQuantityToStock(int $uid, int $quantity)
{
$currentStock = $this->getStock($uid);

$queryBuilder = $this->getQueryBuilder();

$queryBuilder
->update('tx_cartproducts_domain_model_product_product')
->where(
$queryBuilder->expr()->eq('uid', $queryBuilder->createNamedParameter($uid, \PDO::PARAM_INT))
)
->orWhere(
$queryBuilder->expr()->eq('l10n_parent', $queryBuilder->createNamedParameter($uid, \PDO::PARAM_INT))
)
->set('stock', $currentStock + $quantity)
->executeStatement();
}

private function getQueryBuilder(): QueryBuilder
{
return $this
->connectionPool
->getConnectionForTable('tx_cartproducts_domain_model_product_product')
->createQueryBuilder();
}
}
108 changes: 60 additions & 48 deletions Classes/EventListener/CheckProductAvailability.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,86 +10,98 @@
* For the full copyright and license information, please read the
* LICENSE file that was distributed with this source code.
*/

use Extcode\Cart\Domain\Model\Cart\BeVariant as CartProductBeVariant;
use Extcode\Cart\Domain\Model\Cart\Product as CartProduct;
use Extcode\Cart\Event\CheckProductAvailabilityEvent;
use Extcode\CartProducts\Domain\Model\Product\Product;
use Extcode\CartProducts\Domain\Repository\Product\ProductRepository;
use Extcode\CartProducts\Domain\DoctrineRepository\Product\BeVariantRepository;
use Extcode\CartProducts\Domain\DoctrineRepository\Product\ProductRepository;
use TYPO3\CMS\Core\Messaging\FlashMessage;
use TYPO3\CMS\Core\Type\ContextualFeedbackSeverity;
use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3\CMS\Extbase\Utility\LocalizationUtility;

class CheckProductAvailability
{
private CheckProductAvailabilityEvent $event;

public function __construct(
private readonly ProductRepository $productRepository
private readonly ProductRepository $productRepository,
private readonly BeVariantRepository $beVariantRepository,
) {}

public function __invoke(CheckProductAvailabilityEvent $event): void
{
$cart = $event->getCart();
$this->event = $event;
$cartProduct = $event->getProduct();
$quantity = $event->getQuantity();

$mode = $event->getMode();

if ($cartProduct->getProductType() !== 'CartProducts') {
if ($cartProduct->getProductType() !== 'CartProducts' || $cartProduct->isHandleStock() === false) {
return;
}

$querySettings = $this->productRepository->createQuery()->getQuerySettings();
$querySettings->setRespectStoragePage(false);
$this->productRepository->setDefaultQuerySettings($querySettings);
if ($cartProduct->isHandleStockInVariants()) {
foreach ($cartProduct->getBeVariants() as $cartProductBeVariant) {
$this->checkStockForBeVariant($cartProductBeVariant, $cartProduct);
}
} else {
$this->checkStockForProduct($cartProduct);
}
}

$product = $this->productRepository->findByIdentifier($cartProduct->getProductId());
private function checkStockForProduct(CartProduct $cartProduct): void
{
$cart = $this->event->getCart();
$mode = $this->event->getMode();

$quantity = $this->event->getQuantity();
if (is_array($quantity)) {
$compareQuantity = array_sum($quantity);
} else {
$compareQuantity = (int)$quantity;
}

if (
!$product instanceof Product ||
!$product->isHandleStock()
) {
return;
if (($mode === 'add') && $cart->getProductById($cartProduct->getId())) {
$compareQuantity += $cart->getProductById($cartProduct->getId())->getQuantity();
}

if (!$product->isHandleStockInVariants()) {
if (is_array($quantity)) {
$compareQuantity = array_sum($quantity);
} else {
$compareQuantity = $quantity;
}
if (($mode === 'add') && $cart->getProductById($cartProduct->getId())) {
$compareQuantity += $cart->getProductById($cartProduct->getId())->getQuantity();
}
$currentStock = $this->productRepository->getStock($cartProduct->getProductId());

if ($compareQuantity > $product->getStock()) {
$this->falseAvailability($event);
}
if ($compareQuantity > $currentStock) {
$this->falseAvailability();
}
}

return;
public function checkStockForBeVariant(CartProductBeVariant $cartProductBeVariant, CartProduct $cartProduct): void
{
$cart = $this->event->getCart();
$mode = $this->event->getMode();

$quantity = $this->event->getQuantity();
if (is_array($quantity)) {
$compareQuantity = array_sum($quantity);
} else {
$compareQuantity = (int)$quantity;
}

$compareQuantity = (int)$quantity;
if (
$mode === 'add' &&
$cart->getProductById($cartProduct->getId()) &&
$cart->getProductById($cartProduct->getId())->getBeVariantById($cartProductBeVariant->getId())
) {
$compareQuantity += $cart->getProductById($cartProduct->getId())->getBeVariantById($cartProductBeVariant->getId())->getQuantity();
}

foreach ($cartProduct->getBeVariants() as $beVariant) {
if (
$mode === 'add' &&
$cart->getProductById($cartProduct->getId()) &&
$cart->getProductById($cartProduct->getId())->getBeVariantById($beVariant->getId())
) {
$compareQuantity += (int)$cart->getProductById($cartProduct->getId())->getBeVariantById($beVariant->getId())->getQuantity();
}
$currentStock = $this->beVariantRepository->getStock((int)$cartProductBeVariant->getId());

if ($compareQuantity > $beVariant->getStock()) {
$this->falseAvailability($event);
}
if ($compareQuantity > $currentStock) {
$this->falseAvailability();
}
}

/**
* @param CheckProductAvailabilityEvent $event
*/
protected function falseAvailability(CheckProductAvailabilityEvent $event): void
private function falseAvailability(): void
{
$event->setAvailable(false);
$event->addMessage(
$this->event->setAvailable(false);
$this->event->addMessage(
GeneralUtility::makeInstance(
FlashMessage::class,
LocalizationUtility::translate(
Expand Down
4 changes: 2 additions & 2 deletions Classes/EventListener/Order/Stock/CheckStock.php
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ public function __invoke(ProcessOrderCheckStockEvent $event): void

if ($cartProduct->isHandleStockInVariants()) {
foreach ($cartProduct->getBeVariants() as $cartProductBeVariant) {
$this->checkStockForBackendVariant($cartProductBeVariant, $cartProduct);
$this->checkStockForBeVariant($cartProductBeVariant, $cartProduct);
}
} else {
$this->checkStockForProduct($cartProduct);
Expand All @@ -60,7 +60,7 @@ private function checkStockForProduct(CartProduct $cartProduct): void
}
}

public function checkStockForBackendVariant(CartProductBeVariant $cartProductBeVariant, CartProduct $cartProduct): void
public function checkStockForBeVariant(CartProductBeVariant $cartProductBeVariant, CartProduct $cartProduct): void
{
$quantityInStock = $this->beVariantRepository->getStock((int)$cartProductBeVariant->getId());

Expand Down
74 changes: 22 additions & 52 deletions Classes/EventListener/Order/Stock/HandleStock.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,77 +11,47 @@
* LICENSE file that was distributed with this source code.
*/

use Extcode\Cart\Domain\Model\Cart\BeVariant as CartProductBeVariant;
use Extcode\Cart\Domain\Model\Cart\Product as CartProduct;
use Extcode\Cart\Event\Order\EventInterface;
use TYPO3\CMS\Core\Database\ConnectionPool;
use TYPO3\CMS\Core\Utility\GeneralUtility;
use Extcode\CartProducts\Domain\DoctrineRepository\Product\BeVariantRepository;
use Extcode\CartProducts\Domain\DoctrineRepository\Product\ProductRepository;

class HandleStock
{
public function __construct(
private readonly ProductRepository $productRepository,
private readonly BeVariantRepository $beVariantRepository,
) {}

public function __invoke(EventInterface $event): void
{
$cartProducts = $event->getCart()->getProducts();

foreach ($cartProducts as $cartProduct) {
if ($cartProduct->getProductType() === 'CartProducts') {
$productConnection = GeneralUtility::makeInstance(ConnectionPool::class)
->getConnectionForTable('tx_cartproducts_domain_model_product_product');
$productQueryBuilder = $productConnection->createQueryBuilder();

$product = $productQueryBuilder
->select('uid', 'handle_stock', 'handle_stock_in_variants')
->from('tx_cartproducts_domain_model_product_product')->where($productQueryBuilder->expr()->eq('uid', $productQueryBuilder->createNamedParameter($cartProduct->getProductId(), \PDO::PARAM_INT)))->executeQuery()->fetchAssociative();
if ($cartProduct->getProductType() !== 'CartProducts' || $cartProduct->isHandleStock() === false) {
continue;
}

if ($product['handle_stock']) {
if ($product['handle_stock_in_variants']) {
$this->handleStockInBeVariant($cartProduct);
} else {
$this->handleStockInProduct($cartProduct);
}
if ($cartProduct->isHandleStockInVariants()) {
foreach ($cartProduct->getBeVariants() as $cartProductBeVariant) {
$this->handleStockInBeVariant($cartProductBeVariant);
}
} else {
$this->handleStockInProduct($cartProduct);
}
}
}

protected function handleStockInProduct(CartProduct $cartProduct): void
private function handleStockInProduct(CartProduct $cartProduct): void
{
$productConnection = GeneralUtility::makeInstance(ConnectionPool::class)
->getConnectionForTable('tx_cartproducts_domain_model_product_product');
$productQueryBuilder = $productConnection->createQueryBuilder();

$product = $productQueryBuilder
->select('stock')
->from('tx_cartproducts_domain_model_product_product')->where($productQueryBuilder->expr()->eq('uid', $productQueryBuilder->createNamedParameter($cartProduct->getProductId(), \PDO::PARAM_INT)))->executeQuery()->fetchAssociative();

$productQueryBuilder
->update('tx_cartproducts_domain_model_product_product')
->where(
$productQueryBuilder->expr()->eq('uid', $productQueryBuilder->createNamedParameter($cartProduct->getProductId(), \PDO::PARAM_INT))
)
->orWhere(
$productQueryBuilder->expr()->eq('l10n_parent', $productQueryBuilder->createNamedParameter($cartProduct->getProductId(), \PDO::PARAM_INT))
)->set('stock', $product['stock'] - $cartProduct->getQuantity())->executeStatement();
$quantityToAdd = -1 * ($cartProduct->getQuantity());
$this->productRepository->addQuantityToStock($cartProduct->getProductId(), $quantityToAdd);
}

protected function handleStockInBeVariant(CartProduct $cartProduct): void
private function handleStockInBeVariant(CartProductBeVariant $cartProductBeVariant): void
{
$beVariantConnection = GeneralUtility::makeInstance(ConnectionPool::class)
->getConnectionForTable('tx_cartproducts_domain_model_product_bevariant');

foreach ($cartProduct->getBeVariants() as $cartBeVariant) {
$beVariantQueryBuilder = $beVariantConnection->createQueryBuilder();
$beVariant = $beVariantQueryBuilder
->select('stock')
->from('tx_cartproducts_domain_model_product_bevariant')->where($beVariantQueryBuilder->expr()->eq('uid', $beVariantQueryBuilder->createNamedParameter($cartBeVariant->getId(), \PDO::PARAM_INT)))->executeQuery()->fetchAssociative();

$beVariantQueryBuilder
->update('tx_cartproducts_domain_model_product_bevariant')
->where(
$beVariantQueryBuilder->expr()->eq('uid', $beVariantQueryBuilder->createNamedParameter($cartBeVariant->getId(), \PDO::PARAM_INT))
)
->orWhere(
$beVariantQueryBuilder->expr()->eq('l10n_parent', $beVariantQueryBuilder->createNamedParameter($cartBeVariant->getId(), \PDO::PARAM_INT))
)->set('stock', $beVariant['stock'] - $cartBeVariant->getQuantity())->executeStatement();
}
$quantityToAdd = -1 * ($cartProductBeVariant->getQuantity());
$this->beVariantRepository->addQuantityToStock((int)$cartProductBeVariant->getId(), $quantityToAdd);
}
}

0 comments on commit 82460d6

Please sign in to comment.