| Current Path : /var/www/www.indacotrentino.com/www/vendor/magento/module-quote/Model/Quote/Item/ |
| Current File : /var/www/www.indacotrentino.com/www/vendor/magento/module-quote/Model/Quote/Item/AbstractItem.php |
<?php
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
namespace Magento\Quote\Model\Quote\Item;
use Magento\Quote\Model\Quote\Item;
use Magento\Framework\Api\AttributeValueFactory;
/**
* Quote item abstract model
*
* Price attributes:
* - price - initial item price, declared during product association
* - original_price - product price before any calculations
* - calculation_price - prices for item totals calculation
* - custom_price - new price that can be declared by user and recalculated during calculation process
* - original_custom_price - original defined value of custom price without any conversion
*
* @api
* @method float getDiscountAmount()
* @method \Magento\Quote\Model\Quote\Item\AbstractItem setDiscountAmount(float $amount)
* @method float getBaseDiscountAmount()
* @method \Magento\Quote\Model\Quote\Item\AbstractItem setBaseDiscountAmount(float $amount)
* @method float getDiscountPercent()
* @method \Magento\Quote\Model\Quote\Item\AbstractItem setDiscountPercent()
* @method float getOriginalDiscountAmount()
* @method \Magento\Quote\Model\Quote\Item\AbstractItem setOriginalDiscountAmount()
* @method float getBaseOriginalDiscountAmount()
* @method \Magento\Quote\Model\Quote\Item\AbstractItem setBaseOriginalDiscountAmount()
* @method float getDiscountCalculationPrice()
* @method \Magento\Quote\Model\Quote\Item\AbstractItem setDiscountCalculationPrice()
* @method float getBaseDiscountCalculationPrice()
* @method \Magento\Quote\Model\Quote\Item\AbstractItem setBaseDiscountCalculationPrice($price)
* @method int[] getAppliedRuleIds()
* @method \Magento\Quote\Model\Quote\Item\AbstractItem setAppliedRuleIds(array $ruleIds)
* @method float getBaseTaxAmount()
* @method float getBaseDiscountTaxCompensation()
* @method float getBaseRowTotal()
* @method float getQtyOrdered()
* @method float getRowTotalInclTax()
* @method float getTaxAmount()
* @method float getDiscountTaxCompensation()
* @method float getRowTotal()
* @method float getPriceInclTax()
* @SuppressWarnings(PHPMD.CouplingBetweenObjects)
* @since 100.0.2
*/
abstract class AbstractItem extends \Magento\Framework\Model\AbstractExtensibleModel implements
\Magento\Catalog\Model\Product\Configuration\Item\ItemInterface
{
/**
* @var Item|null
*/
protected $_parentItem = null;
/**
* @var \Magento\Quote\Model\Quote\Item\AbstractItem[]
*/
protected $_children = [];
/**
* @var array
*/
protected $_messages = [];
/**
* List of custom options
*
* @var array
*/
protected $_optionsByCode;
/**
* @var \Magento\Catalog\Api\ProductRepositoryInterface
*/
protected $productRepository;
/**
* @var \Magento\Framework\Pricing\PriceCurrencyInterface
*/
protected $priceCurrency;
/**
* @param \Magento\Framework\Model\Context $context
* @param \Magento\Framework\Registry $registry
* @param \Magento\Framework\Api\ExtensionAttributesFactory $extensionFactory
* @param AttributeValueFactory $customAttributeFactory
* @param \Magento\Catalog\Api\ProductRepositoryInterface $productRepository
* @param \Magento\Framework\Pricing\PriceCurrencyInterface $priceCurrency
* @param \Magento\Framework\Model\ResourceModel\AbstractResource $resource
* @param \Magento\Framework\Data\Collection\AbstractDb $resourceCollection
* @param array $data
*/
public function __construct(
\Magento\Framework\Model\Context $context,
\Magento\Framework\Registry $registry,
\Magento\Framework\Api\ExtensionAttributesFactory $extensionFactory,
AttributeValueFactory $customAttributeFactory,
\Magento\Catalog\Api\ProductRepositoryInterface $productRepository,
\Magento\Framework\Pricing\PriceCurrencyInterface $priceCurrency,
\Magento\Framework\Model\ResourceModel\AbstractResource $resource = null,
\Magento\Framework\Data\Collection\AbstractDb $resourceCollection = null,
array $data = []
) {
parent::__construct(
$context,
$registry,
$extensionFactory,
$customAttributeFactory,
$resource,
$resourceCollection,
$data
);
$this->productRepository = $productRepository;
$this->priceCurrency = $priceCurrency;
}
/**
* Retrieve Quote instance
*
* @return \Magento\Quote\Model\Quote
*/
abstract public function getQuote();
/**
* Retrieve address model
*
* @return \Magento\Quote\Model\Quote\Address
*/
abstract public function getAddress();
/**
* Retrieve product model object associated with item
*
* @return \Magento\Catalog\Model\Product
*/
public function getProduct()
{
$product = $this->_getData('product');
if ($product === null && $this->getProductId()) {
$product = clone $this->productRepository->getById(
$this->getProductId(),
false,
$this->getQuote()->getStoreId()
);
$this->setProduct($product);
}
/**
* Reset product final price because it related to custom options
*/
$product->setFinalPrice(null);
if (is_array($this->_optionsByCode)) {
$product->setCustomOptions($this->_optionsByCode);
}
return $product;
}
/**
* Returns special download params (if needed) for custom option with type = 'file'
* Needed to implement \Magento\Catalog\Model\Product\Configuration\Item\Interface.
* Return null, as quote item needs no additional configuration.
*
* @return null|\Magento\Framework\DataObject
*/
public function getFileDownloadParams()
{
return null;
}
/**
* Specify parent item id before saving data
*
* @return $this
*/
public function beforeSave()
{
parent::beforeSave();
if ($this->getParentItem()) {
$this->setParentItemId($this->getParentItem()->getId());
}
return $this;
}
/**
* Set parent item
*
* @param Item $parentItem
* @return $this
*/
public function setParentItem($parentItem)
{
if ($parentItem) {
$this->_parentItem = $parentItem;
$parentItem->addChild($this);
}
return $this;
}
/**
* Get parent item
*
* @return Item
*/
public function getParentItem()
{
return $this->_parentItem;
}
/**
* Get child items
*
* @return \Magento\Quote\Model\Quote\Item\AbstractItem[]
*/
public function getChildren()
{
return $this->_children;
}
/**
* Add child item
*
* @param \Magento\Quote\Model\Quote\Item\AbstractItem $child
* @return $this
*/
public function addChild($child)
{
$this->setHasChildren(true);
$this->_children[] = $child;
return $this;
}
/**
* Adds message(s) for quote item. Duplicated messages are not added.
*
* @param mixed $messages
* @return $this
*/
public function setMessage($messages)
{
$messagesExists = $this->getMessage(false);
if (!is_array($messages)) {
$messages = [$messages];
}
foreach ($messages as $message) {
if (!in_array($message, $messagesExists)) {
$this->addMessage($message);
}
}
return $this;
}
/**
* Add message of quote item to array of messages
*
* @param string $message
* @return $this
*/
public function addMessage($message)
{
$this->_messages[] = $message;
return $this;
}
/**
* Get messages array of quote item
*
* @param bool $string flag for converting messages to string
* @return array|string
*/
public function getMessage($string = true)
{
if ($string) {
return join("\n", $this->_messages);
}
return $this->_messages;
}
/**
* Removes message by text
*
* @param string $text
* @return $this
*/
public function removeMessageByText($text)
{
foreach ($this->_messages as $key => $message) {
if ($message == $text) {
unset($this->_messages[$key]);
}
}
return $this;
}
/**
* Clears all messages
*
* @return $this
*/
public function clearMessage()
{
$this->unsMessage();
// For older compatibility, when we kept message inside data array
$this->_messages = [];
return $this;
}
/**
* Retrieve store model object
*
* @return \Magento\Store\Model\Store
*/
public function getStore()
{
return $this->getQuote()->getStore();
}
/**
* Checking item data
*
* @return $this
*/
public function checkData()
{
$this->setHasError(false);
$this->clearMessage();
$qty = $this->_getData('qty');
try {
$this->setQty($qty);
} catch (\Magento\Framework\Exception\LocalizedException $e) {
$this->setHasError(true);
$this->setMessage($e->getMessage());
} catch (\Exception $e) {
$this->setHasError(true);
$this->setMessage(__('Item qty declaration error'));
}
try {
$this->getProduct()->getTypeInstance()->checkProductBuyState($this->getProduct());
} catch (\Magento\Framework\Exception\LocalizedException $e) {
$this->setHasError(true)->setMessage($e->getMessage());
$this->getQuote()->setHasError(
true
)->addMessage(
__('Some of the products below do not have all the required options.')
);
} catch (\Exception $e) {
$this->setHasError(true)->setMessage(__('Something went wrong during the item options declaration.'));
$this->getQuote()->setHasError(true)->addMessage(__('We found an item options declaration error.'));
}
if ($this->getProduct()->getHasError()) {
$this->setHasError(true)->setMessage(__('Some of the selected options are not currently available.'));
$this->getQuote()->setHasError(true)->addMessage($this->getProduct()->getMessage(), 'options');
}
if ($this->getHasConfigurationUnavailableError()) {
$this->setHasError(
true
)->setMessage(
__('Selected option(s) or their combination is not currently available.')
);
$this->getQuote()->setHasError(
true
)->addMessage(
__('Some item options or their combination are not currently available.'),
'unavailable-configuration'
);
$this->unsHasConfigurationUnavailableError();
}
return $this;
}
/**
* Get original (not related with parent item) item quantity
*
* @return int|float
*/
public function getQty()
{
return $this->_getData('qty');
}
/**
* Get total item quantity (include parent item relation)
*
* @return int|float
*/
public function getTotalQty()
{
if ($this->getParentItem()) {
return $this->getQty() * $this->getParentItem()->getQty();
}
return $this->getQty();
}
/**
* Calculate item row total price
*
* @return $this
*/
public function calcRowTotal()
{
$qty = $this->getTotalQty();
// Round unit price before multiplying to prevent losing 1 cent on subtotal
$total = $this->priceCurrency->round($this->getCalculationPriceOriginal()) * $qty;
$baseTotal = $this->priceCurrency->round($this->getBaseCalculationPriceOriginal()) * $qty;
$this->setRowTotal($this->priceCurrency->round($total));
$this->setBaseRowTotal($this->priceCurrency->round($baseTotal));
return $this;
}
/**
* Get item price used for quote calculation process.
*
* This method get custom price (if it is defined) or original product final price
*
* @return float
*/
public function getCalculationPrice()
{
$price = $this->_getData('calculation_price');
if ($price === null) {
if ($this->hasCustomPrice()) {
$price = $this->getCustomPrice();
} else {
$price = $this->getConvertedPrice();
}
$this->setData('calculation_price', $price);
}
return $price;
}
/**
* Get item price used for quote calculation process.
*
* This method get original custom price applied before tax calculation
*
* @return float
*/
public function getCalculationPriceOriginal()
{
$price = $this->_getData('calculation_price');
if ($price === null) {
if ($this->hasOriginalCustomPrice()) {
$price = $this->getOriginalCustomPrice();
} else {
$price = $this->getConvertedPrice();
}
$this->setData('calculation_price', $price);
}
return $price;
}
/**
* Get calculation price used for quote calculation in base currency.
*
* @return float
*/
public function getBaseCalculationPrice()
{
if (!$this->hasBaseCalculationPrice()) {
if ($this->hasCustomPrice()) {
$price = (double)$this->getCustomPrice();
if ($price) {
$rate = $this->priceCurrency->convert($price, $this->getStore()) / $price;
$price = $price / $rate;
}
} else {
$price = $this->getPrice();
}
$this->setBaseCalculationPrice($price);
}
return $this->_getData('base_calculation_price');
}
/**
* Get original calculation price used for quote calculation in base currency.
*
* @return float
*/
public function getBaseCalculationPriceOriginal()
{
if (!$this->hasBaseCalculationPrice()) {
if ($this->hasOriginalCustomPrice()) {
$price = (double)$this->getOriginalCustomPrice();
if ($price) {
$rate = $this->priceCurrency->convert($price, $this->getStore()) / $price;
$price = $price / $rate;
}
} else {
$price = $this->getPrice();
}
$this->setBaseCalculationPrice($price);
}
return $this->_getData('base_calculation_price');
}
/**
* Get original price (retrieved from product) for item.
*
* Original price value is in quote selected currency
*
* @return float
*/
public function getOriginalPrice()
{
$price = $this->_getData('original_price');
if ($price === null) {
$price = $this->priceCurrency->convert($this->getBaseOriginalPrice(), $this->getStore());
$this->setData('original_price', $price);
}
return $price;
}
/**
* Set original price to item (calculation price will be refreshed too)
*
* @param float $price
* @return \Magento\Quote\Model\Quote\Item\AbstractItem
*/
public function setOriginalPrice($price)
{
return $this->setData('original_price', $price);
}
/**
* Get Original item price (got from product) in base website currency
*
* @return float
*/
public function getBaseOriginalPrice()
{
return $this->_getData('base_original_price');
}
/**
* Specify custom item price (used in case when we have apply not product price to item)
*
* @param float $value
* @return \Magento\Quote\Model\Quote\Item\AbstractItem
*/
public function setCustomPrice($value)
{
$this->setCalculationPrice($value);
$this->setBaseCalculationPrice(null);
return $this->setData('custom_price', $value);
}
/**
* Get item price. Item price currency is website base currency.
*
* @return float
*/
public function getPrice()
{
return $this->_getData('price');
}
/**
* Specify item price (base calculation price and converted price will be refreshed too)
*
* @param float $value
* @return $this
*/
public function setPrice($value)
{
$this->setBaseCalculationPrice(null);
$this->setConvertedPrice(null);
return $this->setData('price', $value);
}
/**
* Get item price converted to quote currency
*
* @return float
*/
public function getConvertedPrice()
{
$price = $this->_getData('converted_price');
if ($price === null) {
$price = $this->priceCurrency->convert($this->getPrice(), $this->getStore());
$this->setData('converted_price', $price);
}
return $price;
}
/**
* Set new value for converted price
*
* @param float $value
* @return $this
*/
public function setConvertedPrice($value)
{
$this->setCalculationPrice(null);
$this->setData('converted_price', $value);
return $this;
}
/**
* Clone quote item
*
* @return $this
*/
public function __clone()
{
$this->setId(null);
$this->_parentItem = null;
$this->_children = [];
$this->_messages = [];
return $this;
}
/**
* Checking if there children calculated or parent item when we have parent quote item and its children
*
* @return bool
*/
public function isChildrenCalculated()
{
if ($this->getParentItem()) {
$calculate = $this->getParentItem()->getProduct()->getPriceType();
} else {
$calculate = $this->getProduct()->getPriceType();
}
if (null !== $calculate &&
(int)$calculate === \Magento\Catalog\Model\Product\Type\AbstractType::CALCULATE_CHILD
) {
return true;
}
return false;
}
/**
* Checking can we ship product separately
*
* Checking can we ship product separately (each child separately)
* or each parent product item can be shipped only like one item
*
* @return bool
*/
public function isShipSeparately()
{
if ($this->getParentItem()) {
$shipmentType = $this->getParentItem()->getProduct()->getShipmentType();
} else {
$shipmentType = $this->getProduct()->getShipmentType();
}
if (null !== $shipmentType &&
(int)$shipmentType === \Magento\Catalog\Model\Product\Type\AbstractType::SHIPMENT_SEPARATELY
) {
return true;
}
return false;
}
/**
* Returns the total discount amounts of all the child items.
*
* If there are no children, returns the discount amount of this item.
*
* @return float
*/
public function getTotalDiscountAmount()
{
$totalDiscountAmount = 0;
/* \Magento\Quote\Model\Quote\Item\AbstractItem[] */
$children = $this->getChildren();
if (!empty($children) && $this->isChildrenCalculated()) {
foreach ($children as $child) {
$totalDiscountAmount += $child->getDiscountAmount();
}
} else {
$totalDiscountAmount = $this->getDiscountAmount();
}
return $totalDiscountAmount;
}
}