Skip to content

Commit

Permalink
Merge branch '2.4-develop' of https://github.com/mage-os/mirror-magento2
Browse files Browse the repository at this point in the history
 into 2.4-develop
  • Loading branch information
mage-os-ci committed May 14, 2024
2 parents e9cf9ee + 49cc612 commit a3bcb53
Show file tree
Hide file tree
Showing 10 changed files with 1,387 additions and 58 deletions.
133 changes: 133 additions & 0 deletions app/code/Magento/Bundle/Model/Product/OriginalPrice.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
<?php
/************************************************************************
*
* Copyright 2024 Adobe
* All Rights Reserved.
*
* NOTICE: All information contained herein is, and remains
* the property of Adobe and its suppliers, if any. The intellectual
* and technical concepts contained herein are proprietary to Adobe
* and its suppliers and are protected by all applicable intellectual
* property laws, including trade secret and copyright laws.
* Dissemination of this information or reproduction of this material
* is strictly forbidden unless prior written permission is obtained
* from Adobe.
* ************************************************************************
*/
declare(strict_types=1);

namespace Magento\Bundle\Model\Product;

use Magento\Catalog\Model\Product;
use Magento\Framework\Serialize\Serializer\Json;

/**
* Get original price for bundle products
*/
class OriginalPrice
{
/**
* @param Json $serializer
*/
public function __construct(private readonly Json $serializer)
{
}

/**
* Get Original Total price for Bundle items
*
* @param Product $product
* @return float
*/
public function getTotalBundleItemsOriginalPrice(Product $product): float
{
$price = 0.0;

if (!$product->hasCustomOptions()) {
return $price;
}

$selectionIds = $this->getBundleSelectionIds($product);

if (empty($selectionIds)) {
return $price;
}

$selections = $product->getTypeInstance()->getSelectionsByIds($selectionIds, $product);
foreach ($selections->getItems() as $selection) {
if (!$selection->isSalable()) {
continue;
}

$selectionQty = $product->getCustomOption('selection_qty_' . $selection->getSelectionId());
if ($selectionQty) {
$price += $this->getSelectionOriginalTotalPrice(
$product,
$selection,
(float) $selectionQty->getValue()
);
}
}

return $price;
}

/**
* Calculate total original price of selection
*
* @param Product $bundleProduct
* @param Product $selectionProduct
* @param float $selectionQty
*
* @return float
*/
private function getSelectionOriginalTotalPrice(
Product $bundleProduct,
Product $selectionProduct,
float $selectionQty
): float {
$price = $this->getSelectionOriginalPrice($bundleProduct, $selectionProduct);

return $price * $selectionQty;
}

/**
* Calculate the original price of selection
*
* @param Product $bundleProduct
* @param Product $selectionProduct
*
* @return float
*/
public function getSelectionOriginalPrice(Product $bundleProduct, Product $selectionProduct): float
{
if ($bundleProduct->getPriceType() == Price::PRICE_TYPE_DYNAMIC) {
return (float) $selectionProduct->getPrice();
}
if ($selectionProduct->getSelectionPriceType()) {
// percent
return $bundleProduct->getPrice() * ($selectionProduct->getSelectionPriceValue() / 100);
}

// fixed
return (float) $selectionProduct->getSelectionPriceValue();
}

/**
* Retrieve array of bundle selection IDs
*
* @param Product $product
* @return array
*/
private function getBundleSelectionIds(Product $product): array
{
$customOption = $product->getCustomOption('bundle_selection_ids');
if ($customOption) {
$selectionIds = $this->serializer->unserialize($customOption->getValue());
if (is_array($selectionIds)) {
return $selectionIds;
}
}
return [];
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
<?php
/************************************************************************
*
* Copyright 2024 Adobe
* All Rights Reserved.
*
* NOTICE: All information contained herein is, and remains
* the property of Adobe and its suppliers, if any. The intellectual
* and technical concepts contained herein are proprietary to Adobe
* and its suppliers and are protected by all applicable intellectual
* property laws, including trade secret and copyright laws.
* Dissemination of this information or reproduction of this material
* is strictly forbidden unless prior written permission is obtained
* from Adobe.
* ************************************************************************
*/
declare(strict_types=1);

namespace Magento\Bundle\Plugin\Quote;

use Magento\Bundle\Model\Product\OriginalPrice;
use Magento\Bundle\Model\Product\Type;
use Magento\Quote\Model\Quote;
use Magento\Quote\Model\Quote\Address\Total\Subtotal;
use Magento\Quote\Api\Data\ShippingAssignmentInterface;
use Magento\Quote\Model\Quote\Address\Total;

/**
* Update bundle base original price
*/
class UpdateBundleQuoteItemBaseOriginalPrice
{
/**
* @param OriginalPrice $price
*/
public function __construct(
private readonly OriginalPrice $price
) {
}

/**
* Update bundle base original price
*
* @param Subtotal $subject
* @param Subtotal $result
* @param Quote $quote
* @param ShippingAssignmentInterface $shippingAssignment
* @param Total $total
*
* @return Subtotal
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
*/
public function afterCollect(
Subtotal $subject,
Subtotal $result,
Quote $quote,
ShippingAssignmentInterface $shippingAssignment,
Total $total
): Subtotal {
foreach ($quote->getAllVisibleItems() as $quoteItem) {
if ($quoteItem->getProductType() === Type::TYPE_CODE) {
$price = $quoteItem->getProduct()->getPrice();
$price += $this->price->getTotalBundleItemsOriginalPrice($quoteItem->getProduct());
$quoteItem->setBaseOriginalPrice($price);
}
}
return $result;
}
}
5 changes: 5 additions & 0 deletions app/code/Magento/Bundle/etc/di.xml
Original file line number Diff line number Diff line change
Expand Up @@ -284,4 +284,9 @@
</argument>
</arguments>
</type>
<type name="Magento\Quote\Model\Quote\Address\Total\Subtotal">
<plugin name="update_bundle_quote_item_base_original_price"
type="Magento\Bundle\Plugin\Quote\UpdateBundleQuoteItemBaseOriginalPrice"
sortOrder="10"/>
</type>
</config>
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ public function resolve(Field $field, $context, ResolveInfo $info, array $value

$price = $product->getPrice();
$finalPrice = $product->getFinalPrice();
$discountPercentage = 100 - (($finalPrice * 100) / $price);
$discountPercentage = ($price) ? (100 - (($finalPrice * 100) / $price)) : 0;
return [
'main_price' => $price,
'main_final_price' => $finalPrice,
Expand Down
57 changes: 37 additions & 20 deletions app/code/Magento/GroupedProduct/Model/Product/Type/Grouped.php
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
<?php
/**
* Grouped product type implementation
*
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
namespace Magento\GroupedProduct\Model\Product\Type;

use Magento\Catalog\Api\ProductRepositoryInterface;
use Magento\Catalog\Model\Product;
use Magento\Framework\DataObject;
use Magento\Framework\File\UploaderFactory;

/**
Expand All @@ -19,7 +19,7 @@
*/
class Grouped extends \Magento\Catalog\Model\Product\Type\AbstractType
{
const TYPE_CODE = 'grouped';
public const TYPE_CODE = 'grouped';

/**
* Cache key for Associated Products
Expand Down Expand Up @@ -57,15 +57,11 @@ class Grouped extends \Magento\Catalog\Model\Product\Type\AbstractType
protected $_canConfigure = true;

/**
* Catalog product status
*
* @var \Magento\Catalog\Model\Product\Attribute\Source\Status
*/
protected $_catalogProductStatus;

/**
* Store manager
*
* @var \Magento\Store\Model\StoreManagerInterface
*/
protected $_storeManager;
Expand Down Expand Up @@ -201,7 +197,7 @@ public function getParentIdsByChild($childId)
/**
* Retrieve array of associated products
*
* @param \Magento\Catalog\Model\Product $product
* @param Product $product
* @return array
*/
public function getAssociatedProducts($product)
Expand All @@ -214,7 +210,16 @@ public function getAssociatedProducts($product)
$collection = $this->getAssociatedProductCollection(
$product
)->addAttributeToSelect(
['name', 'price', 'special_price', 'special_from_date', 'special_to_date', 'tax_class_id', 'image']
[
'name',
'price',
'special_price',
'special_from_date',
'special_to_date',
'tax_class_id',
'image',
'thumbnail'
]
)->addFilterByRequiredOptions()->setPositionOrder()->addStoreFilter(
$this->getStoreFilter($product)
)->addAttributeToFilter(
Expand Down Expand Up @@ -347,22 +352,34 @@ protected function getProductInfo(\Magento\Framework\DataObject $buyRequest, $pr
return __('Please specify the quantity of product(s).')->render();
}
foreach ($associatedProducts as $subProduct) {
if (!isset($productsInfo[$subProduct->getId()])) {
if ($isStrictProcessMode && !$subProduct->getQty() && $subProduct->isSalable()) {
return __('Please specify the quantity of product(s).')->render();
}
if (isset($buyRequest['qty']) && !isset($buyRequest['super_group'])) {
$subProductQty = (float)$subProduct->getQty() * (float)$buyRequest['qty'];
$productsInfo[$subProduct->getId()] = $subProduct->isSalable() ? $subProductQty : 0;
} else {
$productsInfo[$subProduct->getId()] = $subProduct->isSalable() ? (float)$subProduct->getQty() : 0;
}
if (isset($productsInfo[$subProduct->getId()])) {
continue;
}
if ($isStrictProcessMode && !$subProduct->getQty() && $subProduct->isSalable()) {
return __('Please specify the quantity of product(s).')->render();
}
$productsInfo[$subProduct->getId()] = $this->getSubProductQtyInfo($buyRequest, $subProduct);
}

return $productsInfo;
}

/**
* Gets qty info for sub product in group
*
* @param DataObject $buyRequest
* @param Product $subProduct
* @return float
*/
private function getSubProductQtyInfo(
DataObject $buyRequest,
Product $subProduct,
): float {
if (isset($buyRequest['qty']) && !isset($buyRequest['super_group'])) {
return $subProduct->isSalable() ? $subProduct->getQty() * (float)$buyRequest['qty'] : 0.0;
}
return $subProduct->isSalable() ? $subProduct->getQty() : 0.0;
}

/**
* Prepare product and its configuration to be added to some products list.
*
Expand Down
Loading

0 comments on commit a3bcb53

Please sign in to comment.