diff --git a/.gitignore b/.gitignore index ccb972e95bc5a..c6be69f442172 100644 --- a/.gitignore +++ b/.gitignore @@ -103,6 +103,9 @@ tests-legacy/resources/modules/ps_categorytree tests-legacy/resources/modules/ps_facetedsearch tests-legacy/resources/modules/ps_sharebuttons +# Installed with test data maybe via API push +tests-legacy/resources/modules/ps_reminder + tests/Resources/img/l/* !tests/Resources/img/l/.gitkeep tests/Resources/img/p/* diff --git a/classes/Product.php b/classes/Product.php index f07b53af2d132..e71be120ac3de 100644 --- a/classes/Product.php +++ b/classes/Product.php @@ -3700,7 +3700,9 @@ public static function priceCalculation( // fetch price & attribute price $cache_id_2 = $id_product . '-' . $id_shop; - if (!isset(self::$_pricesLevel2[$cache_id_2])) { + // We need to check the cache for this price AND attribute, if absent the whole product cache needs update + // This can happen if the cache was filled before the combination was created for example + if (!isset(self::$_pricesLevel2[$cache_id_2][(int) $id_product_attribute])) { $sql = new DbQuery(); $sql->select('product_shop.`price`, product_shop.`ecotax`'); $sql->from('product', 'p'); diff --git a/src/Adapter/Product/CommandHandler/RemoveAllAssociatedProductSuppliersHandler.php b/src/Adapter/Product/CommandHandler/RemoveAllAssociatedProductSuppliersHandler.php index 3c5f45763431f..506064e2c2bcd 100644 --- a/src/Adapter/Product/CommandHandler/RemoveAllAssociatedProductSuppliersHandler.php +++ b/src/Adapter/Product/CommandHandler/RemoveAllAssociatedProductSuppliersHandler.php @@ -79,7 +79,7 @@ public function handle(RemoveAllAssociatedProductSuppliersCommand $command): voi $product = $this->productRepository->get($command->getProductId()); $productSupplierIds = []; - foreach (ProductSupplier::getSupplierCollection($product->id) as $productSupplier) { + foreach (ProductSupplier::getSupplierCollection($product->id, false) as $productSupplier) { $productSupplierIds[] = new ProductSupplierId((int) $productSupplier->id); } diff --git a/tests/Integration/Behaviour/Features/Context/Domain/Product/CommonProductFeatureContext.php b/tests/Integration/Behaviour/Features/Context/Domain/Product/CommonProductFeatureContext.php index 8130e7217fb9c..f99997c363571 100644 --- a/tests/Integration/Behaviour/Features/Context/Domain/Product/CommonProductFeatureContext.php +++ b/tests/Integration/Behaviour/Features/Context/Domain/Product/CommonProductFeatureContext.php @@ -33,6 +33,7 @@ use PHPUnit\Framework\Assert; use PrestaShop\PrestaShop\Core\Domain\Product\Exception\ProductConstraintException; use PrestaShop\PrestaShop\Core\Domain\Product\Exception\ProductNotFoundException; +use Product; use RuntimeException; use Tests\Integration\Behaviour\Features\Context\Util\CombinationDetails; use Tests\Integration\Behaviour\Features\Context\Util\ProductCombinationFactory; @@ -67,6 +68,11 @@ public function addCombinationsToProduct(string $productReference, TableNode $ta foreach ($combinations as $combination) { $this->getSharedStorage()->set($combination->reference, (int) $combination->id); } + + // Product class has a lot of cache that is set as soon as the product is created, including for prices + // which are cached for each combinations. Since it was cached when the combinations did not exist we need + // to clear it so that the newly created combinations' prices are correctly computed next time they are needed. + Product::resetStaticCache(); } /** diff --git a/tests/Integration/Behaviour/Features/Context/Domain/Product/UpdateProductSuppliersFeatureContext.php b/tests/Integration/Behaviour/Features/Context/Domain/Product/UpdateProductSuppliersFeatureContext.php index 013a2b31347ea..21dded3348507 100644 --- a/tests/Integration/Behaviour/Features/Context/Domain/Product/UpdateProductSuppliersFeatureContext.php +++ b/tests/Integration/Behaviour/Features/Context/Domain/Product/UpdateProductSuppliersFeatureContext.php @@ -44,11 +44,11 @@ class UpdateProductSuppliersFeatureContext extends AbstractProductFeatureContext { /** - * @When I delete all product :productReference suppliers + * @When I remove all associated product :productReference suppliers * * @param string $productReference */ - public function deleteAllProductSuppliers(string $productReference): void + public function removeAssociatedProductSuppliers(string $productReference): void { try { $this->getCommandBus()->handle(new RemoveAllAssociatedProductSuppliersCommand( diff --git a/tests/Integration/Behaviour/Features/Scenario/Product/update_suppliers.feature b/tests/Integration/Behaviour/Features/Scenario/Product/update_suppliers.feature index 4a3b46bdfa5f1..82b3c49aa0031 100644 --- a/tests/Integration/Behaviour/Features/Scenario/Product/update_suppliers.feature +++ b/tests/Integration/Behaviour/Features/Scenario/Product/update_suppliers.feature @@ -1,5 +1,6 @@ # ./vendor/bin/behat -c tests/Integration/Behaviour/behat.yml -s product --tags update-suppliers @reset-database-before-feature +@clear-cache-before-feature @update-suppliers Feature: Update product suppliers from Back Office (BO) As a BO user @@ -60,7 +61,7 @@ Feature: Update product suppliers from Back Office (BO) | default supplier | supplier2 | | default supplier reference | my second supplier for product1 | - Scenario: Remove product suppliers + Scenario: Remove all associated product suppliers Given product product1 type should be standard And product product1 should have following suppliers: | product supplier reference | currency | price tax excluded | @@ -69,7 +70,7 @@ Feature: Update product suppliers from Back Office (BO) And product product1 should have following supplier values: | default supplier | supplier2 | | default supplier reference | my second supplier for product1 | - When I delete all product product1 suppliers + When I remove all associated product product1 suppliers Then product product1 should not have any suppliers assigned And product product1 should not have a default supplier And product product1 default supplier reference should be empty @@ -105,3 +106,122 @@ Feature: Update product suppliers from Back Office (BO) | sup white shirt M 1 | USD | 5 | whiteM | | sup white shirt L 2 | USD | 3 | whiteL | Then product product2 default supplier reference should be empty + + Scenario: Standard product wholesale price should depend on default supplier price + Given I add product "product3" with following information: + | name[en-US] | magic staff | + | is_virtual | false | + And product product3 type should be standard + And product product3 should not have any suppliers assigned + And product product3 should have following prices information: + | price | 0 | + | ecotax | 0 | + | tax rules group | | + | on_sale | false | + | wholesale_price | 0 | + | unit_price | 0 | + | unity | | + | unit_price_ratio | 0 | + When I set product product3 default supplier to supplier1 and following suppliers: + | reference | supplier reference | product supplier reference | currency | price tax excluded | + | product3supplier1 | supplier1 | my first supplier for product3 | USD | 10 | + Then product product3 should have following suppliers: + | product supplier reference | currency | price tax excluded | + | my first supplier for product3 | USD | 10 | + And product product3 should have following supplier values: + | default supplier | supplier1 | + And product product3 should have following prices information: + | price | 0 | + | ecotax | 0 | + | tax rules group | | + | on_sale | false | + | wholesale_price | 10 | + | unit_price | 0 | + | unity | | + | unit_price_ratio | 0 | + When I remove all associated product "product3" suppliers + Then product product3 should not have any suppliers assigned + And product product3 should not have a default supplier + And product product3 default supplier reference should be empty + And product product3 should have following prices information: + | price | 0 | + | ecotax | 0 | + | tax rules group | | + | on_sale | false | + | wholesale_price | 0 | + | unit_price | 0 | + | unity | | + | unit_price_ratio | 0 | + + Scenario: Combination product wholesale price should be reset when default supplier is assigned + Given I add product "product4" with following information: + | name[en-US] | regular T-shirt | + | is_virtual | false | + And product product4 should have following prices information: + | price | 0 | + | ecotax | 0 | + | tax rules group | | + | on_sale | false | + | wholesale_price | 0 | + | unit_price | 0 | + | unity | | + | unit_price_ratio | 0 | + And I update product product4 prices with following information: + | wholesale_price | 15 | + And product "product4" has following combinations: + | reference | quantity | attributes | + | whiteM | 15 | Size:M;Color:White | + | whiteL | 13 | Size:L;Color:White | + And product product4 type should be combination + And product product4 should not have any suppliers assigned + And product product4 default supplier reference should be empty + And product product4 should have following prices information: + | price | 0 | + | ecotax | 0 | + | tax rules group | | + | on_sale | false | + | wholesale_price | 15 | + | unit_price | 0 | + | unity | | + | unit_price_ratio | 0 | + When I set product product4 default supplier to supplier1 and following suppliers: + | reference | supplier reference | product supplier reference | currency | price tax excluded | combination | + | product4whiteM | supplier1 | sup white shirt M 1 | USD | 5 | whiteM | + | product4whiteL | supplier1 | sup white shirt L 2 | USD | 3 | whiteL | + Then product product4 should have following suppliers: + | product supplier reference | currency | price tax excluded | combination | + | sup white shirt M 1 | USD | 5 | whiteM | + | sup white shirt L 2 | USD | 3 | whiteL | + Then product product4 default supplier reference should be empty + And product product4 should have following prices information: + | price | 0 | + | ecotax | 0 | + | tax rules group | | + | on_sale | false | + | wholesale_price | 0 | + | unit_price | 0 | + | unity | | + | unit_price_ratio | 0 | + And I update product product4 prices with following information: + | wholesale_price | 11 | + And product product4 should have following prices information: + | price | 0 | + | ecotax | 0 | + | tax rules group | | + | on_sale | false | + | wholesale_price | 11 | + | unit_price | 0 | + | unity | | + | unit_price_ratio | 0 | + When I remove all associated product product4 suppliers + Then product product4 should not have any suppliers assigned + And product product4 default supplier reference should be empty + And product product4 should have following prices information: + | price | 0 | + | ecotax | 0 | + | tax rules group | | + | on_sale | false | + | wholesale_price | 0 | + | unit_price | 0 | + | unity | | + | unit_price_ratio | 0 |