Skip to content

Commit

Permalink
[TASK] Exclude stock handling from Translation
Browse files Browse the repository at this point in the history
Resolves: #46
  • Loading branch information
extcode committed Nov 20, 2019
1 parent 3969a06 commit ad21dbd
Show file tree
Hide file tree
Showing 5 changed files with 196 additions and 27 deletions.
104 changes: 79 additions & 25 deletions Classes/Utility/StockUtility.php
Expand Up @@ -3,6 +3,7 @@
namespace Extcode\CartProducts\Utility;

use TYPO3\CMS\Core\Cache\CacheManager;
use TYPO3\CMS\Core\Database\ConnectionPool;
use TYPO3\CMS\Core\Utility\GeneralUtility;

/**
Expand Down Expand Up @@ -48,34 +49,27 @@ public function handleStock($params)
{
$cartProduct = $params['cartProduct'];

if ($cartProduct->getProductType() == 'CartProducts') {
/** @var \Extcode\Cart\Domain\Repository\Product\ProductRepository $productRepository */
$productRepository = $this->objectManager->get(
\Extcode\CartProducts\Domain\Repository\Product\ProductRepository::class
);
/** @var \Extcode\Cart\Domain\Repository\Product\BeVariantRepository $beVariantRepository */
$beVariantRepository = $this->objectManager->get(
\Extcode\CartProducts\Domain\Repository\Product\BeVariantRepository::class
);

$product = $productRepository->findByUid($cartProduct->getProductId());
if ($product->isHandleStock()) {
if ($product->isHandleStockInVariants()) {
/** @var \Extcode\Cart\Domain\Model\Cart\BeVariant $cartBeVariant */
foreach ($cartProduct->getBeVariants() as $cartBeVariant) {
/** @var \Extcode\Cart\Domain\Model\Product\BeVariant $productBeVariant */
$productBeVariant = $beVariantRepository->findByUid($cartBeVariant->getId());
$productBeVariant->removeFromStock($cartBeVariant->getQuantity());
$beVariantRepository->update($productBeVariant);
}
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))
)
->execute()->fetch();

if ($product['handle_stock']) {
if ($product['handle_stock_in_variants']) {
$this->handleStockInBeVariant($cartProduct);
} else {
$product->removeFromStock($cartProduct->getQuantity());
$productRepository->update($product);
$this->handleStockInProduct($cartProduct);
}

$this->persistenceManager->persistAll();

$this->flushCache($product->getUid());
$this->flushCache($product['uid']);
}
}
}
Expand All @@ -91,4 +85,64 @@ protected function flushCache(int $productId)

$cacheManager->flushCachesInGroupByTag('pages', $cacheTag);
}

/**
* @param \Extcode\Cart\Domain\Model\Cart\Product $cartProduct
*/
protected function handleStockInProduct(\Extcode\Cart\Domain\Model\Cart\Product $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))
)
->execute()->fetch();

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

/**
* @param \Extcode\Cart\Domain\Model\Cart\Product $cartProduct
*/
protected function handleStockInBeVariant(\Extcode\Cart\Domain\Model\Cart\Product $cartProduct): 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))
)
->execute()->fetch();

$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())
->execute();
}
}
}
Expand Up @@ -311,7 +311,9 @@
'size' => 30,
'eval' => 'required,int',
'default' => 0,
]
],
'l10n_mode' => 'exclude',
'l10n_display' => 'defaultAsReadonly',
],

'product' => [
Expand Down
Expand Up @@ -774,6 +774,8 @@
'type' => 'check',
],
'onChange' => 'reload',
'l10n_mode' => 'exclude',
'l10n_display' => 'defaultAsReadonly',
],
'handle_stock_in_variants' => [
'exclude' => 1,
Expand All @@ -788,6 +790,8 @@
'type' => 'check',
],
'onChange' => 'reload',
'l10n_mode' => 'exclude',
'l10n_display' => 'defaultAsReadonly',
],
'stock' => [
'exclude' => 1,
Expand All @@ -803,7 +807,9 @@
'size' => 30,
'eval' => 'int',
'default' => 0,
]
],
'l10n_mode' => 'exclude',
'l10n_display' => 'defaultAsReadonly',
],

'tags' => [
Expand Down
@@ -0,0 +1,87 @@
.. include:: ../../Includes.txt

========================================================
Important: #46 - Exclude Stock Handling from Translation
========================================================

See :issue:`46`

Description
===========

For each product you can activate the stock management in the backend. Up to now, stock management was carried out
independently for each language.
The online shops implemented with the extension sell products with translated product titles and descriptions, but
not translated products.
Therefore there should be a collective stock for all translations of a product.

.. IMPORTANT::
Check your database for differences in translated products.
If any query shows a result, please take a closer look at the products
or its backend variants and update them.
If you are sure, the respective update query can also be used to adapt
the data of the translations to the original language. For different
stock levels in the products or their backend variants, this should be
compared with the actual stock level.

.. code-block:: sql
:caption: **Check and Update handle_stock in Products**
SELECT orig.uid AS orig_uid, orig.title AS orig_title, orig.handle_stock AS orig_handle_stock, trans.uid AS trans_uid, trans.title AS trans_title, trans.handle_stock AS trans_handle_stock
FROM `tx_cartproducts_domain_model_product_product` AS orig
JOIN `tx_cartproducts_domain_model_product_product` AS trans ON orig.uid = trans.l10n_parent
WHERE orig.handle_stock <> trans.handle_stock
UPDATE `tx_cartproducts_domain_model_product_product` AS trans
JOIN `tx_cartproducts_domain_model_product_product` AS orig ON orig.uid = trans.l10n_parent
SET trans.handle_stock = orig.handle_stock
WHERE orig.handle_stock <> trans.handle_stock
.. code-block:: sql
:caption: **Check and Update handle_stock_in_variants in Products**
SELECT orig.uid AS orig_uid, orig.title AS orig_title, orig.handle_stock_in_variants AS orig_handle_stock_in_variants, trans.uid AS trans_uid, trans.title AS trans_title, trans.handle_stock_in_variants AS trans_handle_stock_in_variants
FROM `tx_cartproducts_domain_model_product_product` AS orig
JOIN `tx_cartproducts_domain_model_product_product` AS trans ON orig.uid = trans.l10n_parent
WHERE orig.handle_stock_in_variants <> trans.handle_stock_in_variants
UPDATE `tx_cartproducts_domain_model_product_product` AS trans
JOIN `tx_cartproducts_domain_model_product_product` AS orig ON orig.uid = trans.l10n_parent
SET trans.handle_stock_in_variants = orig.handle_stock_in_variants
WHERE orig.handle_stock_in_variants <> trans.handle_stock_in_variants
.. code-block:: sql
:caption: **Check and Update stock in Products**
SELECT orig.uid AS orig_uid, orig.title AS orig_title, orig.stock AS orig_stock, trans.uid AS trans_uid, trans.title AS trans_title, trans.stock AS trans_stock
FROM `tx_cartproducts_domain_model_product_product` AS orig
JOIN `tx_cartproducts_domain_model_product_product` AS trans ON orig.uid = trans.l10n_parent
WHERE orig.stock <> trans.stock
UPDATE `tx_cartproducts_domain_model_product_product` AS trans
JOIN `tx_cartproducts_domain_model_product_product` AS orig ON orig.uid = trans.l10n_parent
SET trans.stock = orig.stock
WHERE orig.stock <> trans.stock
.. code-block:: sql
:caption: **Check and Update stock in Backend Variants**
SELECT orig.product, orig_product.title, orig.uid AS orig_uid, orig.stock AS orig_stock, trans.uid AS trans_uid, trans.stock AS trans_stock
FROM `tx_cartproducts_domain_model_product_bevariant` AS orig
JOIN `tx_cartproducts_domain_model_product_bevariant` AS trans ON orig.uid = trans.l10n_parent
JOIN `tx_cartproducts_domain_model_product_product` AS orig_product ON orig.product = orig_product.uid
WHERE orig.stock IS NOT NULL AND orig.stock <> trans.stock;
UPDATE `tx_cartproducts_domain_model_product_bevariant` AS trans
JOIN `tx_cartproducts_domain_model_product_bevariant` AS orig ON orig.uid = trans.l10n_parent
SET trans.stock = orig.stock
WHERE orig.stock IS NOT NULL AND orig.stock <> trans.stock
Saving the products in the backend should update the field as well.

.. NOTE::

If you require the old language-specific stock management, this version **must not** be installed.
Please contact me in this case, so that an appropriate solution can be developed.

.. index:: TCA
Expand Up @@ -15,4 +15,24 @@ The product must of course have the same type in all languages.
Therefore, this change will remove the product type in the translations and
take the type of the original language.

.. IMPORTANT::
Check your database for differences in translated products.
If you are sure, the respective update query can also be used to adapt
the data of the translations to the original language.

.. code-block:: sql
:caption: **Check and Update product_type in Products**
SELECT orig.uid AS orig_uid, orig.title AS orig_title, orig.product_type AS orig_product_type, trans.uid AS trans_uid, trans.title AS trans_title, trans.product_type AS trans_product_type
FROM `tx_cartproducts_domain_model_product_product` AS orig
JOIN `tx_cartproducts_domain_model_product_product` AS trans ON orig.uid = trans.l10n_parent
WHERE orig.product_type <> trans.product_type
UPDATE `tx_cartproducts_domain_model_product_product` AS trans
JOIN `tx_cartproducts_domain_model_product_product` AS orig ON orig.uid = trans.l10n_parent
SET trans.product_type = orig.product_type
WHERE orig.product_type <> trans.product_type
Saving the products in the backend should update the field as well.

.. index:: TCA

0 comments on commit ad21dbd

Please sign in to comment.