diff --git a/app/code/Magento/Braintree/Model/Observer.php b/app/code/Magento/Braintree/Model/Observer.php index e2d1b733dea9c..499df549b2964 100644 --- a/app/code/Magento/Braintree/Model/Observer.php +++ b/app/code/Magento/Braintree/Model/Observer.php @@ -41,7 +41,6 @@ class Observer * @var \Magento\Framework\DB\TransactionFactory */ protected $transactionFactory; - /** * @param Vault $vault * @param \Magento\Braintree\Model\Config\Cc $config @@ -80,21 +79,28 @@ public function processBraintreePayment(\Magento\Framework\DataObject $observer) && $order->canInvoice() && $this->shouldInvoice()) { $qtys = []; foreach ($shipment->getAllItems() as $shipmentItem) { - $qtys[$shipmentItem->getOrderItem()->getId()] = $shipmentItem->getQty(); + if ($shipmentItem->getOrderItem()->getQtyToInvoice() >= $shipmentItem->getQty()) { + $qtys[$shipmentItem->getOrderItem()->getId()] = $shipmentItem->getQty(); + } else { + $qtys[$shipmentItem->getOrderItem()->getId()] = $shipmentItem->getOrderItem()->getQtyToInvoice(); + } } foreach ($order->getAllItems() as $orderItem) { if (!array_key_exists($orderItem->getId(), $qtys)) { $qtys[$orderItem->getId()] = 0; } } - $invoice = $order->prepareInvoice($qtys); - $invoice->setRequestedCaptureCase(\Magento\Sales\Model\Order\Invoice::CAPTURE_ONLINE); - $invoice->register(); - /** @var \Magento\Framework\DB\Transaction $transaction */ - $transaction = $this->transactionFactory->create(); - $transaction->addObject($invoice) - ->addObject($invoice->getOrder()) - ->save(); + if (array_sum($qtys)>0) { + $invoice = $order->prepareInvoice($qtys); + $invoice->setOrder($order); + $invoice->setRequestedCaptureCase(\Magento\Sales\Model\Order\Invoice::CAPTURE_ONLINE); + $invoice->register(); + /** @var \Magento\Framework\DB\Transaction $transaction */ + $transaction = $this->transactionFactory->create(); + $transaction->addObject($invoice) + ->addObject($invoice->getOrder()) + ->save(); + } } return $this; } diff --git a/app/code/Magento/Braintree/Test/Unit/Model/ObserverTest.php b/app/code/Magento/Braintree/Test/Unit/Model/ObserverTest.php index fce7158772524..9b6a439a285ee 100644 --- a/app/code/Magento/Braintree/Test/Unit/Model/ObserverTest.php +++ b/app/code/Magento/Braintree/Test/Unit/Model/ObserverTest.php @@ -104,13 +104,22 @@ protected function setupOrderShipmentItems($orderMock, $shipmentMock) $shipment3Qty = 3; $orderItem1 = new \Magento\Framework\DataObject( - ['id' => $orderItem1Id] + [ + 'id' => $orderItem1Id, + 'qty_to_invoice' => $orderItem1Id + ] ); $orderItem2 = new \Magento\Framework\DataObject( - ['id' => $orderItem2Id] + [ + 'id' => $orderItem2Id, + 'qty_to_invoice' => $orderItem2Id + ] ); $orderItem3 = new \Magento\Framework\DataObject( - ['id' => $orderItem3Id] + [ + 'id' => $orderItem3Id, + 'qty_to_invoice' => $orderItem3Id + ] ); $orderItems = [$orderItem1, $orderItem2, $orderItem3]; $orderMock->expects($this->any()) diff --git a/app/code/Magento/Catalog/Block/Product/View/Options.php b/app/code/Magento/Catalog/Block/Product/View/Options.php index 7086edbd40c95..5e4efdb8e56cb 100644 --- a/app/code/Magento/Catalog/Block/Product/View/Options.php +++ b/app/code/Magento/Catalog/Block/Product/View/Options.php @@ -13,6 +13,9 @@ use Magento\Catalog\Model\Product; +/** + * @SuppressWarnings(PHPMD.CouplingBetweenObjects) + */ class Options extends \Magento\Framework\View\Element\Template { /** @@ -190,6 +193,7 @@ protected function _getPriceConfiguration($option) ], ], 'type' => $option->getPriceType(), + 'name' => $option->getTitle() ]; return $data; } diff --git a/app/code/Magento/Catalog/Block/Product/View/Options/Type/Select.php b/app/code/Magento/Catalog/Block/Product/View/Options/Type/Select.php index cedd7b1f84598..bfaba72156943 100644 --- a/app/code/Magento/Catalog/Block/Product/View/Options/Type/Select.php +++ b/app/code/Magento/Catalog/Block/Product/View/Options/Type/Select.php @@ -59,7 +59,7 @@ public function getValuesHtml() ); $select->addOption( $_value->getOptionTypeId(), - $_value->getTitle() . ' ' . $priceStr . '', + $_value->getTitle() . ' ' . strip_tags($priceStr) . '', ['price' => $this->pricingHelper->currencyByStore($_value->getPrice(true), $store, false)] ); } diff --git a/app/code/Magento/Catalog/Pricing/Price/CustomOptionPrice.php b/app/code/Magento/Catalog/Pricing/Price/CustomOptionPrice.php index b4475de139be0..380b3a7c61091 100644 --- a/app/code/Magento/Catalog/Pricing/Price/CustomOptionPrice.php +++ b/app/code/Magento/Catalog/Pricing/Price/CustomOptionPrice.php @@ -9,6 +9,9 @@ use Magento\Catalog\Model\Product\Option; use Magento\Catalog\Pricing\Price; use Magento\Framework\Pricing\Price\AbstractPrice; +use Magento\Framework\Pricing\Object\SaleableInterface; +use Magento\Framework\Pricing\Adjustment\CalculatorInterface; +use Magento\Framework\Pricing\Amount\AmountInterface; /** * Class OptionPrice @@ -26,6 +29,31 @@ class CustomOptionPrice extends AbstractPrice implements CustomOptionPriceInterf */ protected $priceOptions; + /** + * Code of parent adjustment to be skipped from calculation + * + * @var string + */ + protected $excludeAdjustment = null; + + /** + * @param SaleableInterface $saleableItem + * @param float $quantity + * @param CalculatorInterface $calculator + * @param \Magento\Framework\Pricing\PriceCurrencyInterface $priceCurrency + * @param string $excludeAdjustment + */ + public function __construct( + SaleableInterface $saleableItem, + $quantity, + CalculatorInterface $calculator, + \Magento\Framework\Pricing\PriceCurrencyInterface $priceCurrency, + $excludeAdjustment = null + ) { + parent::__construct($saleableItem, $quantity, $calculator, $priceCurrency); + $this->excludeAdjustment = $excludeAdjustment; + } + /** * Get minimal and maximal option values * @@ -83,6 +111,23 @@ public function getValue() return $optionValues; } + /** + * @param float $amount + * @param null|bool|string $exclude + * @param null|array $context + * @return AmountInterface|bool|float + */ + public function getCustomAmount($amount = null, $exclude = null, $context = []) + { + if (null !== $amount) { + $amount = $this->priceCurrency->convertAndRound($amount); + } else { + $amount = $this->getValue(); + } + $exclude = $this->excludeAdjustment; + return $this->calculator->getAmount($amount, $this->getProduct(), $exclude, $context); + } + /** * Return the minimal or maximal price for custom options * diff --git a/app/code/Magento/Catalog/view/base/layout/catalog_product_prices.xml b/app/code/Magento/Catalog/view/base/layout/catalog_product_prices.xml index ca7d042bde70e..8e700eac76263 100644 --- a/app/code/Magento/Catalog/view/base/layout/catalog_product_prices.xml +++ b/app/code/Magento/Catalog/view/base/layout/catalog_product_prices.xml @@ -28,7 +28,7 @@ Magento_Catalog::product/price/final_price.phtml - Magento_Catalog::product/price/amount/option.phtml + Magento_Catalog::product/price/amount/default.phtml Magento\Catalog\Pricing\Render\ConfiguredPriceBox diff --git a/app/code/Magento/Catalog/view/base/templates/product/price/amount/option.phtml b/app/code/Magento/Catalog/view/base/templates/product/price/amount/option.phtml deleted file mode 100644 index 990ae6f404fab..0000000000000 --- a/app/code/Magento/Catalog/view/base/templates/product/price/amount/option.phtml +++ /dev/null @@ -1,13 +0,0 @@ - - -formatCurrency($block->getDisplayValue(), (bool) $block->getIncludeContainer()) ?> diff --git a/app/code/Magento/Catalog/view/base/web/js/price-options.js b/app/code/Magento/Catalog/view/base/web/js/price-options.js index bf95c7f249743..aa008c0a982a5 100644 --- a/app/code/Magento/Catalog/view/base/web/js/price-options.js +++ b/app/code/Magento/Catalog/view/base/web/js/price-options.js @@ -5,9 +5,11 @@ define([ 'jquery', 'underscore', + 'mage/template', 'priceUtils', + 'priceBox', 'jquery/ui' -], function ($, _, utils) { +], function ($, _, mageTemplate, utils) { 'use strict'; var globalOptions = { @@ -16,6 +18,10 @@ define([ optionsSelector: '.product-custom-option', optionConfig: {}, optionHandlers: {}, + optionTemplate: '<%- data.label %>' + + '<% if (data.finalPrice.value) { %>' + + ' +<%- data.finalPrice.formatted %>' + + '<% } %>', controlContainer: 'dd' }; @@ -29,7 +35,17 @@ define([ */ _create: function createPriceOptions() { var form = this.element, - options = $(this.options.optionsSelector, form); + options = $(this.options.optionsSelector, form), + priceBox = $(this.options.priceHolderSelector, $(this.options.optionsSelector).element); + + if (priceBox.data('magePriceBox') && priceBox.priceBox('option') && priceBox.priceBox('option').priceConfig) { + if (priceBox.priceBox('option').priceConfig.optionTemplate) { + this._setOption('optionTemplate', priceBox.priceBox('option').priceConfig.optionTemplate); + } + this._setOption('priceFormat', priceBox.priceBox('option').priceConfig.priceFormat); + } + + this._applyOptionNodeFix(options); options.on('change', this._onOptionChanged.bind(this)); }, @@ -53,6 +69,64 @@ define([ $(this.options.priceHolderSelector).trigger('updatePrice', changes); }, + + /** + * Helper to fix issue with option nodes: + * - you can't place any html in option -> + * so you can't style it via CSS + * @param {jQuery} options + * @private + */ + _applyOptionNodeFix: function applyOptionNodeFix(options) { + var config = this.options, + format = config.priceFormat, + template = config.optionTemplate; + template = mageTemplate(template); + options.filter('select').each(function (index, element) { + var $element = $(element), + optionId = utils.findOptionId($element), + optionName = $element.prop('name'), + optionType = $element.prop('type'); + var optionConfig = config.optionConfig && config.optionConfig[optionId]; + + $element.find('option').each(function (idx, option) { + var $option, + optionValue, + toTemplate, + prices; + + $option = $(option); + optionValue = $option.val(); + + if (!optionValue && optionValue !== 0) { + return; + } + + toTemplate = { + data: { + label: optionConfig[optionValue] && optionConfig[optionValue].name + } + }; + prices = optionConfig[optionValue] ? optionConfig[optionValue].prices : null; + + if (prices) { + _.each(prices, function (price, type) { + var value = +(price.amount); + value += _.reduce(price.adjustments, function (sum, x) { + return sum + x; + }, 0); + toTemplate.data[type] = { + value: value, + formatted: utils.formatPrice(value, format) + }; + }); + + $option.text(template(toTemplate)); + } + }); + }); + }, + /** * Custom behavior on getting options: * now widget able to deep merge accepted configuration with instance options. diff --git a/app/code/Magento/Customer/Test/Unit/Model/Resource/Group/Grid/ServiceCollectionTest.php b/app/code/Magento/Customer/Test/Unit/Model/Resource/Group/Grid/ServiceCollectionTest.php index 88e6ff36f333b..b506acdf4ec3d 100644 --- a/app/code/Magento/Customer/Test/Unit/Model/Resource/Group/Grid/ServiceCollectionTest.php +++ b/app/code/Magento/Customer/Test/Unit/Model/Resource/Group/Grid/ServiceCollectionTest.php @@ -240,4 +240,14 @@ public function addFieldToFilterInconsistentArraysDataProvider() ], ]; } + + /** + * @expectedException \Magento\Framework\Exception\LocalizedException + * @expectedExceptionMessage When passing an array of fields there must be at least one field in the array. + * @dataProvider addFieldToFilterInconsistentArraysDataProvider + */ + public function testAddFieldToFilterEmptyArrays() + { + $this->serviceCollection->addFieldToFilter([], []); + } } diff --git a/app/code/Magento/Directory/Api/Data/CurrencyInformationInterface.php b/app/code/Magento/Directory/Api/Data/CurrencyInformationInterface.php index 07d5c093e2abf..ce9ae4a9ff164 100644 --- a/app/code/Magento/Directory/Api/Data/CurrencyInformationInterface.php +++ b/app/code/Magento/Directory/Api/Data/CurrencyInformationInterface.php @@ -10,7 +10,7 @@ * * @api */ -interface CurrencyInformationInterface +interface CurrencyInformationInterface extends \Magento\Framework\Api\ExtensibleDataInterface { /** * Get the base currency code for the store. @@ -105,17 +105,17 @@ public function setExchangeRates(array $exchangeRates = null); /** * Retrieve existing extension attributes object or create a new one. * - * @return \Magento\Directory\Api\Data\CurrencyInformationInterface|null + * @return \Magento\Directory\Api\Data\CurrencyInformationExtensionInterface|null */ public function getExtensionAttributes(); /** * Set an extension attributes object. * - * @param \Magento\Directory\Api\Data\CurrencyInformationInterface $extensionAttributes + * @param \Magento\Directory\Api\Data\CurrencyInformationExtensionInterface $extensionAttributes * @return $this */ public function setExtensionAttributes( - \Magento\Directory\Api\Data\CurrencyInformationInterface $extensionAttributes + \Magento\Directory\Api\Data\CurrencyInformationExtensionInterface $extensionAttributes ); } diff --git a/app/code/Magento/Directory/Api/Data/ExchangeRateInterface.php b/app/code/Magento/Directory/Api/Data/ExchangeRateInterface.php index ae360968b66c5..10917074ae3b5 100644 --- a/app/code/Magento/Directory/Api/Data/ExchangeRateInterface.php +++ b/app/code/Magento/Directory/Api/Data/ExchangeRateInterface.php @@ -10,7 +10,7 @@ * * @api */ -interface ExchangeRateInterface +interface ExchangeRateInterface extends \Magento\Framework\Api\ExtensibleDataInterface { /** * Get the currency code associated with the exchange rate. @@ -45,17 +45,17 @@ public function setRate($rate); /** * Retrieve existing extension attributes object or create a new one. * - * @return \Magento\Directory\Api\Data\ExchangeRateInterface|null + * @return \Magento\Directory\Api\Data\ExchangeRateExtensionInterface|null */ public function getExtensionAttributes(); /** * Set an extension attributes object. * - * @param \Magento\Directory\Api\Data\ExchangeRateInterface $extensionAttributes + * @param \Magento\Directory\Api\Data\ExchangeRateExtensionInterface $extensionAttributes * @return $this */ public function setExtensionAttributes( - \Magento\Directory\Api\Data\ExchangeRateInterface $extensionAttributes + \Magento\Directory\Api\Data\ExchangeRateExtensionInterface $extensionAttributes ); } diff --git a/app/code/Magento/Directory/Helper/Data.php b/app/code/Magento/Directory/Helper/Data.php index 5def90f736f71..00e8ca5fb2a54 100644 --- a/app/code/Magento/Directory/Helper/Data.php +++ b/app/code/Magento/Directory/Helper/Data.php @@ -138,7 +138,7 @@ public function getRegionCollection() /** * Retrieve country collection * - * @param mixed $store + * @param null|int|string|\Magento\Store\Model\Store $store * @return \Magento\Directory\Model\Resource\Country\Collection */ public function getCountryCollection($store = null) diff --git a/app/code/Magento/Directory/Model/Data/CurrencyInformation.php b/app/code/Magento/Directory/Model/Data/CurrencyInformation.php index c20eb61b60470..091e7a006e434 100644 --- a/app/code/Magento/Directory/Model/Data/CurrencyInformation.php +++ b/app/code/Magento/Directory/Model/Data/CurrencyInformation.php @@ -131,7 +131,7 @@ public function getExtensionAttributes() * @inheritDoc */ public function setExtensionAttributes( - \Magento\Directory\Api\Data\CurrencyInformationInterface $extensionAttributes + \Magento\Directory\Api\Data\CurrencyInformationExtensionInterface $extensionAttributes ) { return $this->_setExtensionAttributes($extensionAttributes); } diff --git a/app/code/Magento/Directory/Model/Data/ExchangeRate.php b/app/code/Magento/Directory/Model/Data/ExchangeRate.php index 16d65828a938e..db728789456c3 100644 --- a/app/code/Magento/Directory/Model/Data/ExchangeRate.php +++ b/app/code/Magento/Directory/Model/Data/ExchangeRate.php @@ -78,7 +78,7 @@ public function getExtensionAttributes() * @inheritDoc */ public function setExtensionAttributes( - \Magento\Directory\Api\Data\ExchangeRateInterface $extensionAttributes + \Magento\Directory\Api\Data\ExchangeRateExtensionInterface $extensionAttributes ) { return $this->_setExtensionAttributes($extensionAttributes); } diff --git a/app/code/Magento/Directory/Model/Resource/Country/Collection.php b/app/code/Magento/Directory/Model/Resource/Country/Collection.php index 686926d4a469b..a5209e1a809cd 100644 --- a/app/code/Magento/Directory/Model/Resource/Country/Collection.php +++ b/app/code/Magento/Directory/Model/Resource/Country/Collection.php @@ -111,12 +111,18 @@ protected function _construct() /** * Load allowed countries for current store * - * @param mixed $store + * @param null|int|string|\Magento\Store\Model\Store $store * @return \Magento\Directory\Model\Resource\Country\Collection */ public function loadByStore($store = null) { - $allowCountries = explode(',', (string)$this->_scopeConfig->getValue('general/country/allow', \Magento\Store\Model\ScopeInterface::SCOPE_STORE, $store)); + $allowCountries = explode(',', + (string)$this->_scopeConfig->getValue( + 'general/country/allow', + \Magento\Store\Model\ScopeInterface::SCOPE_STORE, + $store + ) + ); if (!empty($allowCountries)) { $this->addFieldToFilter("country_id", ['in' => $allowCountries]); } diff --git a/app/code/Magento/Sales/Model/Order/Shipment.php b/app/code/Magento/Sales/Model/Order/Shipment.php index b43efb1490d06..44adc392212d1 100644 --- a/app/code/Magento/Sales/Model/Order/Shipment.php +++ b/app/code/Magento/Sales/Model/Order/Shipment.php @@ -68,11 +68,6 @@ class Shipment extends AbstractModel implements EntityInterface, ShipmentInterfa */ protected $_eventObject = 'shipment'; - /** - * @var \Magento\Sales\Model\OrderFactory - */ - protected $_orderFactory; - /** * @var \Magento\Sales\Model\Resource\Order\Shipment\Item\CollectionFactory */ @@ -93,16 +88,21 @@ class Shipment extends AbstractModel implements EntityInterface, ShipmentInterfa */ protected $_commentCollectionFactory; + /** + * @var \Magento\Sales\Api\OrderRepositoryInterface + */ + protected $orderRepository; + /** * @param \Magento\Framework\Model\Context $context * @param \Magento\Framework\Registry $registry * @param \Magento\Framework\Api\ExtensionAttributesFactory $extensionFactory * @param AttributeValueFactory $customAttributeFactory - * @param \Magento\Sales\Model\OrderFactory $orderFactory * @param \Magento\Sales\Model\Resource\Order\Shipment\Item\CollectionFactory $shipmentItemCollectionFactory * @param \Magento\Sales\Model\Resource\Order\Shipment\Track\CollectionFactory $trackCollectionFactory * @param Shipment\CommentFactory $commentFactory * @param \Magento\Sales\Model\Resource\Order\Shipment\Comment\CollectionFactory $commentCollectionFactory + * @param \Magento\Sales\Api\OrderRepositoryInterface $orderRepository * @param \Magento\Framework\Model\Resource\AbstractResource $resource * @param \Magento\Framework\Data\Collection\AbstractDb $resourceCollection * @param array $data @@ -113,20 +113,20 @@ public function __construct( \Magento\Framework\Registry $registry, \Magento\Framework\Api\ExtensionAttributesFactory $extensionFactory, AttributeValueFactory $customAttributeFactory, - \Magento\Sales\Model\OrderFactory $orderFactory, \Magento\Sales\Model\Resource\Order\Shipment\Item\CollectionFactory $shipmentItemCollectionFactory, \Magento\Sales\Model\Resource\Order\Shipment\Track\CollectionFactory $trackCollectionFactory, \Magento\Sales\Model\Order\Shipment\CommentFactory $commentFactory, \Magento\Sales\Model\Resource\Order\Shipment\Comment\CollectionFactory $commentCollectionFactory, + \Magento\Sales\Api\OrderRepositoryInterface $orderRepository, \Magento\Framework\Model\Resource\AbstractResource $resource = null, \Magento\Framework\Data\Collection\AbstractDb $resourceCollection = null, array $data = [] ) { - $this->_orderFactory = $orderFactory; $this->_shipmentItemCollectionFactory = $shipmentItemCollectionFactory; $this->_trackCollectionFactory = $trackCollectionFactory; $this->_commentFactory = $commentFactory; $this->_commentCollectionFactory = $commentCollectionFactory; + $this->orderRepository = $orderRepository; parent::__construct( $context, $registry, @@ -196,7 +196,7 @@ public function getProtectCode() public function getOrder() { if (!$this->_order instanceof \Magento\Sales\Model\Order) { - $this->_order = $this->_orderFactory->create()->load($this->getOrderId()); + $this->_order = $this->orderRepository->get($this->getOrderId()); } return $this->_order->setHistoryEntityName($this->entityType); } diff --git a/app/code/Magento/Shipping/Controller/Adminhtml/Order/ShipmentLoader.php b/app/code/Magento/Shipping/Controller/Adminhtml/Order/ShipmentLoader.php index e2b3e9fe1fedf..6bbaac5a04d4a 100644 --- a/app/code/Magento/Shipping/Controller/Adminhtml/Order/ShipmentLoader.php +++ b/app/code/Magento/Shipping/Controller/Adminhtml/Order/ShipmentLoader.php @@ -38,11 +38,6 @@ class ShipmentLoader extends DataObject */ protected $shipmentRepository; - /** - * @var \Magento\Sales\Model\OrderFactory - */ - protected $orderFactory; - /** * @var \Magento\Sales\Model\Order\ShipmentFactory */ @@ -53,30 +48,35 @@ class ShipmentLoader extends DataObject */ protected $trackFactory; + /** + * @var \Magento\Sales\Api\OrderRepositoryInterface + */ + protected $orderRepository; + /** * @param \Magento\Framework\Message\ManagerInterface $messageManager * @param \Magento\Framework\Registry $registry * @param \Magento\Sales\Model\Order\ShipmentRepository $shipmentRepository - * @param \Magento\Sales\Model\OrderFactory $orderFactory * @param \Magento\Sales\Model\Order\ShipmentFactory $shipmentFactory * @param \Magento\Sales\Model\Order\Shipment\TrackFactory $trackFactory + * @param \Magento\Sales\Api\OrderRepositoryInterface $orderRepository * @param array $data */ public function __construct( \Magento\Framework\Message\ManagerInterface $messageManager, \Magento\Framework\Registry $registry, \Magento\Sales\Model\Order\ShipmentRepository $shipmentRepository, - \Magento\Sales\Model\OrderFactory $orderFactory, \Magento\Sales\Model\Order\ShipmentFactory $shipmentFactory, \Magento\Sales\Model\Order\Shipment\TrackFactory $trackFactory, + \Magento\Sales\Api\OrderRepositoryInterface $orderRepository, array $data = [] ) { $this->messageManager = $messageManager; $this->registry = $registry; $this->shipmentRepository = $shipmentRepository; - $this->orderFactory = $orderFactory; $this->shipmentFactory = $shipmentFactory; $this->trackFactory = $trackFactory; + $this->orderRepository = $orderRepository; parent::__construct($data); } @@ -106,7 +106,7 @@ public function load() if ($shipmentId) { $shipment = $this->shipmentRepository->get($shipmentId); } elseif ($orderId) { - $order = $this->orderFactory->create()->load($orderId); + $order = $this->orderRepository->get($orderId); /** * Check order existing diff --git a/app/code/Magento/Shipping/Test/Unit/Controller/Adminhtml/Order/ShipmentLoaderTest.php b/app/code/Magento/Shipping/Test/Unit/Controller/Adminhtml/Order/ShipmentLoaderTest.php index 8b38639a2a824..62b798716ba8e 100644 --- a/app/code/Magento/Shipping/Test/Unit/Controller/Adminhtml/Order/ShipmentLoaderTest.php +++ b/app/code/Magento/Shipping/Test/Unit/Controller/Adminhtml/Order/ShipmentLoaderTest.php @@ -32,11 +32,6 @@ class ShipmentLoaderTest extends \PHPUnit_Framework_TestCase */ protected $shipmentRepositoryMock; - /** - * @var \PHPUnit_Framework_MockObject_MockObject - */ - protected $orderFactoryMock; - /** * @var \Magento\Sales\Model\Order\ShipmentFactory|\PHPUnit_Framework_MockObject_MockObject */ @@ -47,6 +42,11 @@ class ShipmentLoaderTest extends \PHPUnit_Framework_TestCase */ protected $trackFactoryMock; + /** + * @var \PHPUnit_Framework_MockObject_MockObject + */ + protected $orderRepository; + /** * @var \Magento\Shipping\Controller\Adminhtml\Order\ShipmentLoader */ @@ -62,10 +62,6 @@ public function setUp() ->disableOriginalConstructor() ->setMethods([]) ->getMock(); - $this->orderFactoryMock = $this->getMockBuilder('Magento\Sales\Model\OrderFactory') - ->disableOriginalConstructor() - ->setMethods(['create']) - ->getMock(); $this->shipmentFactory = $this->getMockBuilder('Magento\Sales\Model\Order\ShipmentFactory') ->disableOriginalConstructor() ->setMethods(['create']) @@ -78,6 +74,10 @@ public function setUp() ->disableOriginalConstructor() ->setMethods([]) ->getMock(); + $this->orderRepository = $this->getMockBuilder('Magento\Sales\Api\OrderRepositoryInterface') + ->disableOriginalConstructor() + ->setMethods([]) + ->getMock(); $data = [ 'order_id' => 100032, @@ -93,9 +93,9 @@ public function setUp() $this->messageManagerMock, $this->registryMock, $this->shipmentRepositoryMock, - $this->orderFactoryMock, $this->shipmentFactory, $this->trackFactoryMock, + $this->orderRepository, $data ); } @@ -121,15 +121,11 @@ public function testLoadOrderId() $this->loader->unsetData('shipment_id'); $orderMock = $this->getMockBuilder('Magento\Sales\Model\Order') ->disableOriginalConstructor() - ->setMethods(['getForcedShipmentWithInvoice', 'getId', 'load', 'canShip']) + ->setMethods(['getForcedShipmentWithInvoice', 'getId', 'canShip']) ->getMock(); - $this->orderFactoryMock->expects($this->once()) - ->method('create') + $this->orderRepository->expects($this->once()) + ->method('get') ->will($this->returnValue($orderMock)); - $orderMock->expects($this->once()) - ->method('load') - ->with($this->loader->getOrderId()) - ->will($this->returnSelf()); $orderMock->expects($this->once()) ->method('getId') ->will($this->returnValue($this->loader->getOrderId())); diff --git a/app/code/Magento/Shipping/Test/Unit/Model/ShipmentTest.php b/app/code/Magento/Shipping/Test/Unit/Model/ShipmentTest.php index 6ec6c6912a917..7842964852aa9 100644 --- a/app/code/Magento/Shipping/Test/Unit/Model/ShipmentTest.php +++ b/app/code/Magento/Shipping/Test/Unit/Model/ShipmentTest.php @@ -8,7 +8,7 @@ namespace Magento\Shipping\Test\Unit\Model; -use Magento\Sales\Model\Resource\OrderFactory; +use \Magento\Sales\Api\OrderRepositoryInterface; use Magento\Framework\TestFramework\Unit\Helper\ObjectManager as ObjectManagerHelper; /** @@ -17,9 +17,9 @@ class ShipmentTest extends \PHPUnit_Framework_TestCase { /** - * @var OrderFactory |\PHPUnit_Framework_MockObject_MockObject + * @var \Magento\Sales\Api\OrderRepositoryInterface |\PHPUnit_Framework_MockObject_MockObject */ - protected $orderFactory; + protected $orderRepository; /** * @var \Magento\Sales\Model\Order\Shipment @@ -28,9 +28,9 @@ class ShipmentTest extends \PHPUnit_Framework_TestCase public function setUp() { - $this->orderFactory = $this->getMock( - '\Magento\Sales\Model\OrderFactory', - ['create'], + $this->orderRepository = $this->getMock( + '\Magento\Sales\Api\OrderRepositoryInterface', + [], [], '', false @@ -42,7 +42,7 @@ public function setUp() 'registry' => $this->getMock('Magento\Framework\Registry', [], [], '', false), 'localeDate' => $this->getMock('Magento\Framework\Stdlib\DateTime\TimezoneInterface', [], [], '', false), 'dateTime' => $this->getMock('Magento\Framework\Stdlib\DateTime', [], [], '', false), - 'orderFactory' => $this->orderFactory, + 'orderRepository' => $this->orderRepository, 'shipmentItemCollectionFactory' => $this->getMock( 'Magento\Sales\Model\Resource\Order\Shipment\Item\CollectionFactory', [], @@ -95,13 +95,9 @@ public function testGetOrder() ->method('setHistoryEntityName') ->with($entityName) ->will($this->returnSelf()); - $order->expects($this->atLeastOnce()) - ->method('load') - ->with($orderId) - ->will($this->returnValue($order)); - $this->orderFactory->expects($this->atLeastOnce()) - ->method('create') + $this->orderRepository->expects($this->atLeastOnce()) + ->method('get') ->will($this->returnValue($order)); $this->assertEquals($order, $this->shipment->getOrder()); diff --git a/app/code/Magento/Tax/view/frontend/web/js/view/checkout/cart/totals/tax.js b/app/code/Magento/Tax/view/frontend/web/js/view/checkout/cart/totals/tax.js index 0a6b04fda7b88..067385cc1f76b 100644 --- a/app/code/Magento/Tax/view/frontend/web/js/view/checkout/cart/totals/tax.js +++ b/app/code/Magento/Tax/view/frontend/web/js/view/checkout/cart/totals/tax.js @@ -10,8 +10,7 @@ define( function (Component, totals) { 'use strict'; - var isTaxDisplayedInGrandTotal = window.checkoutConfig.includeTaxInGrandTotal, - isFullTaxSummaryDisplayed = window.checkoutConfig.isFullTaxSummaryDisplayed, + var isFullTaxSummaryDisplayed = window.checkoutConfig.isFullTaxSummaryDisplayed, isZeroTaxDisplayed = window.checkoutConfig.isZeroTaxDisplayed; return Component.extend({ @@ -31,7 +30,7 @@ define( * @override */ ifShowDetails: function () { - return isTaxDisplayedInGrandTotal && this.getPureValue() > 0 && isFullTaxSummaryDisplayed; + return this.getPureValue() > 0 && isFullTaxSummaryDisplayed; }, /** diff --git a/app/code/Magento/Tax/view/frontend/web/js/view/checkout/summary/tax.js b/app/code/Magento/Tax/view/frontend/web/js/view/checkout/summary/tax.js index ae9c482f43c98..3418d3236b0ea 100644 --- a/app/code/Magento/Tax/view/frontend/web/js/view/checkout/summary/tax.js +++ b/app/code/Magento/Tax/view/frontend/web/js/view/checkout/summary/tax.js @@ -34,7 +34,7 @@ define( if (!this.isFullMode()) { return false; } - return isTaxDisplayedInGrandTotal && this.getPureValue() > 0 && isFullTaxSummaryDisplayed; + return this.getPureValue() > 0 && isFullTaxSummaryDisplayed; }, getPureValue: function() { var amount = 0; diff --git a/app/code/Magento/Weee/Helper/Data.php b/app/code/Magento/Weee/Helper/Data.php index c986021093717..cac43a92c6031 100644 --- a/app/code/Magento/Weee/Helper/Data.php +++ b/app/code/Magento/Weee/Helper/Data.php @@ -738,7 +738,7 @@ public function geDisplayExcl($storeId = null) * @param \Magento\Catalog\Model\Product $product * @return array */ - public function getWeeAttributesForBundle($product) + public function getWeeeAttributesForBundle($product) { if ($product->getTypeId() == \Magento\Catalog\Model\Product\Type::TYPE_BUNDLE) { $typeInstance = $product->getTypeInstance(); @@ -757,7 +757,7 @@ public function getWeeAttributesForBundle($product) $product->getStore()->getWebsiteId() ); foreach ($weeAttributes as $weeAttribute) { - $insertedWeeCodesArray[$weeAttribute->getCode()]=$weeAttribute; + $insertedWeeCodesArray[$selectionItem->getId()][$weeAttribute->getCode()]=$weeAttribute; } } return $insertedWeeCodesArray; diff --git a/app/code/Magento/Weee/Model/Observer.php b/app/code/Magento/Weee/Model/Observer.php index b87dad005a063..ba5a8130cc83d 100644 --- a/app/code/Magento/Weee/Model/Observer.php +++ b/app/code/Magento/Weee/Model/Observer.php @@ -219,7 +219,7 @@ public function getPriceConfiguration(\Magento\Framework\Event\Observer $observe try { $product = $this->_registry->registry('current_product'); - $weeeAttributes = $this->_weeeData->getWeeAttributesForBundle($product); + $weeeAttributes = $this->_weeeData->getWeeeAttributesForBundle($product); $calcPrice = 'finalPrice'; if ($this->_taxData->priceIncludesTax() && @@ -242,7 +242,7 @@ public function getPriceConfiguration(\Magento\Framework\Event\Observer $observe } /** - * Recur through the config array and insert the wee price + * Recur through the config array and insert the weee price * * @param array $input * @param string $searchKey @@ -265,7 +265,7 @@ private function recurConfigAndInsertWeeePrice($input, $searchKey, $calcPrice, $ $holder[$key]['weeePrice'] = $holder[$key][$calcPrice]; // only do processing on product options if (array_key_exists('optionId', $input) && $weeeAttributes) { - $holder = $this->insertWeePrice($holder, $key, $weeeAttributes); + $holder = $this->insertWeeePrice($holder, $key, $weeeAttributes); } } } @@ -278,24 +278,26 @@ private function recurConfigAndInsertWeeePrice($input, $searchKey, $calcPrice, $ } /** - * Insert the wee price for bundle product + * Insert the weee price for bundle product * * @param array $holder * @param int|string $key * @param array $weeeAttributes * @return array */ - private function insertWeePrice($holder, $key, $weeeAttributes) + private function insertWeeePrice($holder, $key, $weeeAttributes) { - if (count($weeeAttributes)>0) { - $weeSum = 0; - foreach ($weeeAttributes as $weeAttribute) { - $holder[$key]['weeePrice' . $weeAttribute->getCode()] = - ['amount' => (float)$weeAttribute->getAmount()]; - $weeSum += (float)$weeAttribute->getAmount(); - } + if (array_key_exists($holder['optionId'], $weeeAttributes)) { + if (count($weeeAttributes[$holder['optionId']]) > 0 && is_array($weeeAttributes[$holder['optionId']])) { + $weeeSum = 0; + foreach ($weeeAttributes[$holder['optionId']] as $weeeAttribute) { + $holder[$key]['weeePrice' . $weeeAttribute->getCode()] = + ['amount' => (float)$weeeAttribute->getAmount()]; + $weeeSum += (float)$weeeAttribute->getAmount(); + } - $holder[$key]['weeePrice']['amount'] += (float)$weeSum; + $holder[$key]['weeePrice']['amount'] += (float)$weeeSum; + } } return $holder; } @@ -305,6 +307,7 @@ private function insertWeePrice($holder, $key, $weeeAttributes) * * @param \Magento\Framework\Event\Observer $observer * @return $this + * @SuppressWarnings(PHPMD.CyclomaticComplexity) */ public function updateProductOptions(\Magento\Framework\Event\Observer $observer) { @@ -330,14 +333,18 @@ public function updateProductOptions(\Magento\Framework\Event\Observer $observer . '<% } %>'; } - foreach ($this->_weeeData->getWeeAttributesForBundle($product) as $weeAttribute) { - $options['optionTemplate'] .= sprintf( - ' <%% if (data.weeePrice' . $weeAttribute->getCode() . ') { %%>' - . ' (' . $weeAttribute->getName() - . ':<%%= data.weeePrice' . $weeAttribute->getCode() - . '.formatted %%>)' - . '<%% } %%>' - ); + foreach ($this->_weeeData->getWeeeAttributesForBundle($product) as $weeeAttributes) { + foreach ($weeeAttributes as $weeeAttribute) { + if (!preg_match('/'.$weeeAttribute->getCode().'/', $options['optionTemplate'])) { + $options['optionTemplate'] .= sprintf( + ' <%% if (data.weeePrice' . $weeeAttribute->getCode() . ') { %%>' + . ' (' . $weeeAttribute->getName() + . ':<%%= data.weeePrice' . $weeeAttribute->getCode() + . '.formatted %%>)' + . '<%% } %%>' + ); + } + } } if ($this->_weeeData->geDisplayExlDescIncl($product->getStoreId())) { diff --git a/app/code/Magento/Weee/Test/Unit/Helper/DataTest.php b/app/code/Magento/Weee/Test/Unit/Helper/DataTest.php index 8a054153e857d..7bf6303507a8e 100644 --- a/app/code/Magento/Weee/Test/Unit/Helper/DataTest.php +++ b/app/code/Magento/Weee/Test/Unit/Helper/DataTest.php @@ -21,7 +21,7 @@ class DataTest extends \PHPUnit_Framework_TestCase /** * @var \Magento\Catalog\Model\Product */ - protected $_product; + protected $product; /** * @var \Magento\Weee\Model\Tax @@ -35,7 +35,7 @@ class DataTest extends \PHPUnit_Framework_TestCase protected function setUp() { - $this->_product = $this->getMock('Magento\Catalog\Model\Product', [], [], '', false); + $this->product = $this->getMock('Magento\Catalog\Model\Product', [], [], '', false); $weeeConfig = $this->getMock('Magento\Weee\Model\Config', [], [], '', false); $weeeConfig->expects($this->any())->method('isEnabled')->will($this->returnValue(true)); $this->weeeTax = $this->getMock('Magento\Weee\Model\Tax', [], [], '', false); @@ -50,10 +50,10 @@ protected function setUp() public function testGetAmount() { - $this->_product->expects($this->any())->method('hasData')->will($this->returnValue(false)); - $this->_product->expects($this->any())->method('getData')->will($this->returnValue(11.26)); + $this->product->expects($this->any())->method('hasData')->will($this->returnValue(false)); + $this->product->expects($this->any())->method('getData')->will($this->returnValue(11.26)); - $this->assertEquals('11.26', $this->_helperData->getAmount($this->_product)); + $this->assertEquals('11.26', $this->_helperData->getAmount($this->product)); } /** @@ -152,31 +152,52 @@ public function testGetBaseWeeeTaxAmountRefunded() $this->assertEquals(self::BASE_TAX_AMOUNT_REFUNDED, $value); } - public function testGetWeeAttributesForBundle() + public function testGetWeeeAttributesForBundle() { - $weeObject = new \Magento\Framework\DataObject( + $prodId1 = 1; + $prodId2 = 2; + $fptCode1 = 'fpt' . $prodId1; + $fptCode2 = 'fpt' . $prodId2; + + $weeeObject1 = new \Magento\Framework\DataObject( + [ + 'code' => $fptCode1, + 'amount' => '15.0000', + ] + ); + + $weeeObject2 = new \Magento\Framework\DataObject( [ - 'code' => 'fpt', + 'code' => $fptCode2, 'amount' => '15.0000', ] ); - $testArray = ['fpt' => $weeObject]; + + + $testArray = [$prodId1 => [$fptCode1 => $weeeObject1], $prodId2 => [$fptCode2 => $weeeObject2]]; $this->weeeTax->expects($this->any()) ->method('getProductWeeeAttributes') - ->will($this->returnValue([$weeObject])); + ->will($this->returnValue([$weeeObject1, $weeeObject2])); - $productSimple=$this->getMock('\Magento\Catalog\Model\Product\Type\Simple', [], [], '', false); + $productSimple = $this->getMock('\Magento\Catalog\Model\Product\Type\Simple', ['getId'], [], '', false); - $productInstance=$this->getMock('\Magento\Bundle\Model\Product\Type', [], [], '', false); + $productSimple->expects($this->at(0)) + ->method('getId') + ->will($this->returnValue($prodId1)); + $productSimple->expects($this->at(1)) + ->method('getId') + ->will($this->returnValue($prodId2)); + + $productInstance = $this->getMock('\Magento\Bundle\Model\Product\Type', [], [], '', false); $productInstance->expects($this->any()) ->method('getSelectionsCollection') ->will($this->returnValue([$productSimple])); $store=$this->getMock('\Magento\Store\Model\Store', [], [], '', false); - - $product=$this->getMock( + /** @var \Magento\Catalog\Model\Product $product */ + $product = $this->getMock( '\Magento\Bundle\Model\Product', ['getTypeInstance', 'getStoreId', 'getStore', 'getTypeId'], [], @@ -202,9 +223,9 @@ public function testGetWeeAttributesForBundle() $registry=$this->getMock('Magento\Framework\Registry', [], [], '', false); $registry->expects($this->any()) ->method('registry') - ->with('current_product') + ->with('currentproduct') ->will($this->returnValue($product)); - $this->assertEquals($testArray, $this->_helperData->getWeeAttributesForBundle($product)); + $this->assertEquals($testArray, $this->_helperData->getWeeeAttributesForBundle($product)); } } diff --git a/app/code/Magento/Weee/Test/Unit/Model/ObserverTest.php b/app/code/Magento/Weee/Test/Unit/Model/ObserverTest.php index 376674c146e4b..6b01e16f2997e 100644 --- a/app/code/Magento/Weee/Test/Unit/Model/ObserverTest.php +++ b/app/code/Magento/Weee/Test/Unit/Model/ObserverTest.php @@ -26,8 +26,23 @@ public function testGetPriceConfiguration($testArray, $expectedArray) 'config' => $testArray, ] ); - $weeHelper=$this->getMock('Magento\Weee\Helper\Data', [], [], '', false); - $weeHelper->expects($this->any()) + + $weeeObject1 = new \Magento\Framework\DataObject( + [ + 'code' => 'fpt1', + 'amount' => '15.0000', + ] + ); + + $weeeObject2 = new \Magento\Framework\DataObject( + [ + 'code' => 'fpt2', + 'amount' => '16.0000', + ] + ); + + $weeeHelper=$this->getMock('Magento\Weee\Helper\Data', [], [], '', false); + $weeeHelper->expects($this->any()) ->method('isEnabled') ->will($this->returnValue(true)); @@ -54,18 +69,27 @@ public function testGetPriceConfiguration($testArray, $expectedArray) ->with('current_product') ->will($this->returnValue($product)); + $weeeHelper->expects($this->any()) + ->method('getWeeeAttributesForBundle') + ->will($this->returnValue([ + 1=> ['fpt1' => $weeeObject1], + 2 =>[ + 'fpt1'=>$weeeObject1, + 'fpt2'=> $weeeObject2 + ] + ])); $objectManager = new ObjectManager($this); - $weeeObserverObject = $objectManager->getObject( - 'Magento\Weee\Model\Observer', - [ - 'weeeData' => $weeHelper, - 'registry' => $registry, - ] - ); - $weeeObserverObject->getPriceConfiguration($observerObject); + $weeeObserverObject = $objectManager->getObject( + 'Magento\Weee\Model\Observer', + [ + 'weeeData' => $weeeHelper, + 'registry' => $registry, + ] + ); + $weeeObserverObject->getPriceConfiguration($observerObject); - $this->assertEquals($expectedArray, $configObj->getData('config')); + $this->assertEquals($expectedArray, $configObj->getData('config')); } /** @@ -117,7 +141,10 @@ public function getPriceConfigurationProvider() 'amount' => 33.50, ], 'weeePrice' => [ - 'amount' => 31.50, + 'amount' => 46.5, + ], + 'weeePricefpt1' => [ + 'amount' => 15, ], ], ], @@ -132,7 +159,13 @@ public function getPriceConfigurationProvider() 'amount' => 333.50, ], 'weeePrice' => [ - 'amount' => 331.50, + 'amount' => 362.5, + ], + 'weeePricefpt1' => [ + 'amount' => 15, + ], + 'weeePricefpt2' => [ + 'amount' => 16, ], ], ], @@ -206,11 +239,11 @@ public function getPriceConfigurationProvider() * Tests the methods that rely on the ScopeConfigInterface object to provide their return values * @dataProvider updateProductOptionsProvider * @param array $testArray - * @param bool $weeDisplay - * @param bool $weeEnabled + * @param bool $weeeDisplay + * @param bool $weeeEnabled * @param array $expectedArray */ - public function testUpdateProductOptions($testArray, $weeDisplay, $weeEnabled, $expectedArray) + public function testUpdateProductOptions($testArray, $weeeDisplay, $weeeEnabled, $expectedArray) { $configObj = new \Magento\Framework\DataObject( [ @@ -218,25 +251,32 @@ public function testUpdateProductOptions($testArray, $weeDisplay, $weeEnabled, $ ] ); - $weeObject = new \Magento\Framework\DataObject( + $weeeObject1 = new \Magento\Framework\DataObject( [ - 'code' => 'fpt', + 'code' => 'fpt1', 'amount' => '15.0000', ] ); - $weeHelper=$this->getMock('Magento\Weee\Helper\Data', [], [], '', false); - $weeHelper->expects($this->any()) + $weeeObject2 = new \Magento\Framework\DataObject( + [ + 'code' => 'fpt2', + 'amount' => '15.0000', + ] + ); + + $weeeHelper=$this->getMock('Magento\Weee\Helper\Data', [], [], '', false); + $weeeHelper->expects($this->any()) ->method('isEnabled') - ->will($this->returnValue($weeEnabled)); + ->will($this->returnValue($weeeEnabled)); - $weeHelper->expects($this->any()) + $weeeHelper->expects($this->any()) ->method('geDisplayExlDescIncl') - ->will($this->returnValue($weeDisplay)); + ->will($this->returnValue($weeeDisplay)); - $weeHelper->expects($this->any()) - ->method('getWeeAttributesForBundle') - ->will($this->returnValue([$weeObject])); + $weeeHelper->expects($this->any()) + ->method('getWeeeAttributesForBundle') + ->will($this->returnValue([['fpt1' => $weeeObject1], ['fpt1'=>$weeeObject1, 'fpt2'=>$weeeObject2]])); $responseObject=$this->getMock('Magento\Framework\Event\Observer', ['getResponseObject'], [], '', false); $responseObject->expects($this->any()) @@ -248,7 +288,7 @@ public function testUpdateProductOptions($testArray, $weeDisplay, $weeEnabled, $ ->method('getEvent') ->will($this->returnValue($responseObject)); - $product=$this->getMock( + $product = $this->getMock( '\Magento\Bundle\Model\Product\Type', ['getTypeId', 'getStoreId'], [], @@ -274,7 +314,7 @@ public function testUpdateProductOptions($testArray, $weeDisplay, $weeEnabled, $ $weeeObserverObject = $objectManager->getObject( 'Magento\Weee\Model\Observer', [ - 'weeeData' => $weeHelper, + 'weeeData' => $weeeHelper, 'registry' => $registry, ] ); @@ -296,8 +336,8 @@ public function updateProductOptionsProvider() 'optionTemplate' => '<%= data.label %><% if (data.basePrice.value) ' . '{ %> +<%= data.basePrice.formatted %><% } %>', ], - 'weeDisplay' => true, - 'weeEnabled' => false, + 'weeeDisplay' => true, + 'weeeEnabled' => false, 'expectedArray' => [ 'TOTAL_BASE_CALCULATION' => 'TOTAL_BASE_CALCULATION', 'optionTemplate' => '<%= data.label %><% if (data.basePrice.value) ' @@ -306,17 +346,18 @@ public function updateProductOptionsProvider() ], [ 'testArray' => [ - 'TOTAL_BASE_CALCULATION' => 'TOTAL_BASE_CALCULATION', - 'optionTemplate' => '<%= data.label %><% if (data.basePrice.value) ' - . '{ %> +<%= data.basePrice.formatted %><% } %>', + 'TOTAL_BASE_CALCULATION' => 'TOTAL_BASE_CALCULATION', + 'optionTemplate' => '<%= data.label %><% if (data.basePrice.value) ' + . '{ %> +<%= data.basePrice.formatted %><% } %>', ], - 'weeDisplay' => false, - 'weeEnabled' => true, + 'weeeDisplay' => false, + 'weeeEnabled' => true, 'expectedArray' => [ - 'TOTAL_BASE_CALCULATION' => 'TOTAL_BASE_CALCULATION', - 'optionTemplate' => '<%= data.label %><% if (data.basePrice.value) ' - . '{ %> +<%= data.basePrice.formatted %><% } %> <% if (data.weeePricefpt) ' - . '{ %> (:<%= data.weeePricefpt.formatted %>)<% } %>', + 'TOTAL_BASE_CALCULATION' => 'TOTAL_BASE_CALCULATION', + 'optionTemplate' => '<%= data.label %><% if (data.basePrice.value) ' + . '{ %> +<%= data.basePrice.formatted %><% } %> <% if (data.weeePricefpt1) ' + . '{ %> (:<%= data.weeePricefpt1.formatted %>)<% } %>' + . ' <% if (data.weeePricefpt2) { %> (:<%= data.weeePricefpt2.formatted %>)<% } %>', ], ], [ @@ -325,13 +366,14 @@ public function updateProductOptionsProvider() 'optionTemplate' => '<%= data.label %><% if (data.basePrice.value) ' . '{ %> +<%= data.basePrice.formatted %><% } %>', ], - 'weeDisplay' => true, - 'weeEnabled' => true, + 'weeeDisplay' => true, + 'weeeEnabled' => true, 'expectedArray' => [ 'TOTAL_BASE_CALCULATION' => 'TOTAL_BASE_CALCULATION', 'optionTemplate' => '<%= data.label %><% if (data.basePrice.value) ' - . '{ %> +<%= data.basePrice.formatted %><% } %> <% if (data.weeePricefpt) ' - . '{ %> (:<%= data.weeePricefpt.formatted %>)<% } %> ' + . '{ %> +<%= data.basePrice.formatted %><% } %> <% if (data.weeePricefpt1) ' + . '{ %> (:<%= data.weeePricefpt1.formatted %>)<% } %> ' + . '<% if (data.weeePricefpt2) { %> (:<%= data.weeePricefpt2.formatted %>)<% } %> ' . '<% if (data.weeePrice) { %><%= data.weeePrice.formatted %><% } %>', ], ], diff --git a/app/code/Magento/Weee/etc/di.xml b/app/code/Magento/Weee/etc/di.xml index 92feb75d2877c..95748f0a0577d 100644 --- a/app/code/Magento/Weee/etc/di.xml +++ b/app/code/Magento/Weee/etc/di.xml @@ -42,4 +42,9 @@ Magento\Weee\Pricing\Adjustment::ADJUSTMENT_CODE + + + Magento\Weee\Pricing\Adjustment::ADJUSTMENT_CODE + + diff --git a/app/code/Magento/Weee/view/frontend/web/js/view/checkout/summary/item/price/row_excl_tax.js b/app/code/Magento/Weee/view/frontend/web/js/view/checkout/summary/item/price/row_excl_tax.js index 07c7f94305e99..fd9b454c49c33 100644 --- a/app/code/Magento/Weee/view/frontend/web/js/view/checkout/summary/item/price/row_excl_tax.js +++ b/app/code/Magento/Weee/view/frontend/web/js/view/checkout/summary/item/price/row_excl_tax.js @@ -20,7 +20,23 @@ define( if(!window.checkoutConfig.getIncludeWeeeFlag) { return rowTotalExclTax + parseFloat(item.weee_tax_applied_amount); } - return rowTotalExclTax + return rowTotalExclTax; + }, + + getRowDisplayPriceExclTax: function(item) { + var rowTotalExclTax = parseFloat(item.row_total); + return rowTotalExclTax + this.getRowWeeeTaxExclTax(item); + }, + + getRowWeeeTaxExclTax: function(item) { + var totalWeeeTaxExclTaxApplied = 0; + if (item.weee_tax_applied) { + var weeeTaxAppliedAmounts = JSON.parse(item.weee_tax_applied); + weeeTaxAppliedAmounts.forEach(function (weeeTaxAppliedAmount) { + totalWeeeTaxExclTaxApplied += parseFloat(Math.max(weeeTaxAppliedAmount.row_amount, 0)); + }); + } + return totalWeeeTaxExclTaxApplied; } }); diff --git a/app/code/Magento/Weee/view/frontend/web/js/view/checkout/summary/item/price/row_incl_tax.js b/app/code/Magento/Weee/view/frontend/web/js/view/checkout/summary/item/price/row_incl_tax.js index 15aec47fd0f36..1ddc245645fc4 100644 --- a/app/code/Magento/Weee/view/frontend/web/js/view/checkout/summary/item/price/row_incl_tax.js +++ b/app/code/Magento/Weee/view/frontend/web/js/view/checkout/summary/item/price/row_incl_tax.js @@ -24,12 +24,19 @@ define( return rowTotalInclTax; }, + getRowDisplayPriceInclTax: function(item) { + var rowTotalInclTax = parseFloat(item.row_total_incl_tax); + return rowTotalInclTax + this.getRowWeeeTaxInclTax(item); + }, + getRowWeeeTaxInclTax: function(item) { - var weeeTaxAppliedAmounts = JSON.parse(item.weee_tax_applied); var totalWeeeTaxIncTaxApplied = 0; - weeeTaxAppliedAmounts.forEach(function (weeeTaxAppliedAmount) { - totalWeeeTaxIncTaxApplied+=parseFloat(Math.max(weeeTaxAppliedAmount.row_amount_incl_tax, 0)); - }); + if (item.weee_tax_applied) { + var weeeTaxAppliedAmounts = JSON.parse(item.weee_tax_applied); + weeeTaxAppliedAmounts.forEach(function (weeeTaxAppliedAmount) { + totalWeeeTaxIncTaxApplied += parseFloat(Math.max(weeeTaxAppliedAmount.row_amount_incl_tax, 0)); + }); + } return totalWeeeTaxIncTaxApplied; } diff --git a/app/code/Magento/Weee/view/frontend/web/template/checkout/summary/item/price/row_excl_tax.html b/app/code/Magento/Weee/view/frontend/web/template/checkout/summary/item/price/row_excl_tax.html index 39e2bfa7815e8..f52551194e6bb 100644 --- a/app/code/Magento/Weee/view/frontend/web/template/checkout/summary/item/price/row_excl_tax.html +++ b/app/code/Magento/Weee/view/frontend/web/template/checkout/summary/item/price/row_excl_tax.html @@ -6,28 +6,28 @@ --> - + - + - - + + - - + + - + - + diff --git a/app/code/Magento/Weee/view/frontend/web/template/checkout/summary/item/price/row_incl_tax.html b/app/code/Magento/Weee/view/frontend/web/template/checkout/summary/item/price/row_incl_tax.html index 562bd3293cf96..c66a2061bf611 100644 --- a/app/code/Magento/Weee/view/frontend/web/template/checkout/summary/item/price/row_incl_tax.html +++ b/app/code/Magento/Weee/view/frontend/web/template/checkout/summary/item/price/row_incl_tax.html @@ -6,28 +6,28 @@ --> - + - + - - + + - - + + - + - + diff --git a/app/code/Magento/Weee/view/frontend/web/template/checkout/summary/weee.html b/app/code/Magento/Weee/view/frontend/web/template/checkout/summary/weee.html index 7a3696a829ef8..886e2443918e6 100644 --- a/app/code/Magento/Weee/view/frontend/web/template/checkout/summary/weee.html +++ b/app/code/Magento/Weee/view/frontend/web/template/checkout/summary/weee.html @@ -8,7 +8,7 @@ - + \ No newline at end of file diff --git a/app/design/frontend/Magento/blank/Magento_Catalog/web/css/source/_module.less b/app/design/frontend/Magento/blank/Magento_Catalog/web/css/source/_module.less index 41727f629e33c..d65fc3090a9fa 100644 --- a/app/design/frontend/Magento/blank/Magento_Catalog/web/css/source/_module.less +++ b/app/design/frontend/Magento/blank/Magento_Catalog/web/css/source/_module.less @@ -241,6 +241,9 @@ .note { display: block; } + .price-notice { + &:extend(.abs-adjustment-incl-excl-tax all); + } } } diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Repository/CatalogProductSimple.xml b/dev/tests/functional/tests/app/Magento/Catalog/Test/Repository/CatalogProductSimple.xml index 328c932717e73..36e2655c40562 100644 --- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Repository/CatalogProductSimple.xml +++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Repository/CatalogProductSimple.xml @@ -917,6 +917,9 @@ default_subcategory + + taxable_goods + Main Website @@ -946,6 +949,9 @@ default_subcategory + + taxable_goods + Main Website diff --git a/dev/tests/functional/tests/app/Magento/Weee/Test/Constraint/AssertFptApplied.php b/dev/tests/functional/tests/app/Magento/Weee/Test/Constraint/AssertFptApplied.php index 6e58923b821a2..2814c8597df1c 100644 --- a/dev/tests/functional/tests/app/Magento/Weee/Test/Constraint/AssertFptApplied.php +++ b/dev/tests/functional/tests/app/Magento/Weee/Test/Constraint/AssertFptApplied.php @@ -120,7 +120,7 @@ protected function getPrices(CatalogProductSimple $product) // Get prices with fpt on cart page $actualPrices = $this->getCartPrice($product, $actualPrices); - return $actualPrices; + return array_filter($actualPrices); } /** @@ -181,6 +181,8 @@ protected function getCartPrice(CatalogProductSimple $product, array $actualPric $actualPrices['cart_item_subtotal_fpt'] = $productWeeeItem->getSubtotalFptBlock()->getFpt(); $actualPrices['cart_item_subtotal_fpt_total'] = $productWeeeItem->getSubtotalFptBlock()->getFptTotal(); $actualPrices['grand_total'] = $this->checkoutCart->getTotalsBlock()->getGrandTotal(); + $actualPrices['grand_total_excl_tax'] = $this->checkoutCart->getTotalsBlock()->getGrandTotalExcludingTax(); + $actualPrices['grand_total_incl_tax'] = $this->checkoutCart->getTotalsBlock()->getGrandTotalIncludingTax(); $actualPrices['total_fpt'] = $this->checkoutCart->getWeeeTotalsBlock()->getFptBlock()->getTotalFpt(); return $actualPrices; diff --git a/dev/tests/functional/tests/app/Magento/Weee/Test/Page/CheckoutCart.xml b/dev/tests/functional/tests/app/Magento/Weee/Test/Page/CheckoutCart.xml index be49a88ca0d71..4cfab8b70af86 100644 --- a/dev/tests/functional/tests/app/Magento/Weee/Test/Page/CheckoutCart.xml +++ b/dev/tests/functional/tests/app/Magento/Weee/Test/Page/CheckoutCart.xml @@ -8,6 +8,6 @@ - + diff --git a/dev/tests/functional/tests/app/Magento/Weee/Test/TestCase/CreateTaxWithFptTest.xml b/dev/tests/functional/tests/app/Magento/Weee/Test/TestCase/CreateTaxWithFptTest.xml index 5e3c1447ed7df..c6700d12186a8 100644 --- a/dev/tests/functional/tests/app/Magento/Weee/Test/TestCase/CreateTaxWithFptTest.xml +++ b/dev/tests/functional/tests/app/Magento/Weee/Test/TestCase/CreateTaxWithFptTest.xml @@ -23,7 +23,7 @@ 100.00 10.00 110.00 - 118.25 + 123.66 10.00 @@ -31,15 +31,21 @@ Check not taxed FPT display set to Including FPT and Description on product with custom option catalog price Excluding Tax shipping_tax_class_taxable_goods,tax_with_fpt_cat_excl_disc_on_incl, display_including_tax with_custom_option_and_fpt - 80.00 + 75.78 10.00 - 100.00 + 85.78 + 108.25 10.00 - 110.00 + 118.25 + 108.25 10.00 - 110.00 + 118.25 + 108.25 10.00 - 118.25 + 118.25 + 123.66 + 115.00 + 123.66 10.00 @@ -47,21 +53,27 @@ Check not taxed FPT display set to Excluding, Description and Including FPT on product with special price catalog price Excluding Tax shipping_tax_class_taxable_goods,tax_with_fpt_cat_excl_disc_on_incl, display_including_tax with_special_price_and_fpt - 110.00 + 108.25 10.00 - 110.00 + 118.25 + 108.25 10.00 - 110.00 + 118.25 + 108.25 10.00 - 110.00 + 118.25 + 108.25 10.00 - 118.25 + 118.25 + 123.66 + 115.00 + 123.66 10.00 Check not taxed FPT display set to Including FPT and Description on product with special price catalog price Excluding Tax - shipping_tax_class_taxable_goods,tax_with_fpt_cat_excl_disc_on_excl, + shipping_tax_class_taxable_goods,tax_with_fpt_cat_excl_disc_on_excl with_special_price_and_fpt 100.00 10.00 @@ -75,7 +87,7 @@ 100.00 10.00 110.00 - 118.25 + 123.66 10.00 @@ -95,7 +107,7 @@ 100.00 10.00 110.00 - 119.08 + 124.49 10.00 @@ -103,15 +115,17 @@ Check taxed FPT display set to Including FPT and Description on product with with custom option catalog price Excluding Tax shipping_tax_class_taxable_goods,tax_with_fpt_taxed_cat_excl_disc_on_incl, display_including_tax with_custom_option_and_fpt - 80.00 + 86.60 10.00 - 100.00 + 119.08 10.00 - 110.00 - 10.00 - 110.00 - 10.00 - 119.08 + 119.08 + 10.83 + 119.08 + 10.83 + 124.49 + 115.00 + 124.49 10.00 @@ -119,15 +133,17 @@ Check taxed FPT display set to Excluding, Description and Including FPT on product with special price catalog price Excluding Tax shipping_tax_class_taxable_goods,tax_with_fpt_taxed_cat_excl_disc_on_incl, display_including_tax with_special_price_and_fpt - 110.00 + 119.08 10.00 - 110.00 + 119.08 10.00 - 110.00 - 10.00 - 110.00 - 10.00 - 119.08 + 119.08 + 10.83 + 119.08 + 10.83 + 124.49 + 115.00 + 124.49 10.00 @@ -147,7 +163,7 @@ 100.00 10.00 110.00 - 119.08 + 124.49 10.00 @@ -167,13 +183,13 @@ 92.38 9.24 101.62 - 110.00 + 115.00 10.00 Check taxed FPT display set to Including FPT and Description on product with with special price and catalog price Including Tax - shipping_tax_class_taxable_goods,tax_with_fpt_taxed_cat_incl_disc_on_incl, display_including_tax + shipping_tax_class_taxable_goods,tax_with_fpt_taxed_cat_incl_disc_on_incl with_special_price_and_fpt 92.38 10.00 @@ -183,7 +199,7 @@ 9.24 101.62 9.24 - 110.00 + 115.00 10.00 @@ -203,7 +219,7 @@ 92.38 9.24 101.62 - 110.00 + 115.00 10.00 diff --git a/dev/tests/integration/testsuite/Magento/Customer/Model/Resource/Group/Grid/ServiceCollectionTest.php b/dev/tests/integration/testsuite/Magento/Customer/Model/Resource/Group/Grid/ServiceCollectionTest.php index cef578e0114a3..354a4c4533d65 100644 --- a/dev/tests/integration/testsuite/Magento/Customer/Model/Resource/Group/Grid/ServiceCollectionTest.php +++ b/dev/tests/integration/testsuite/Magento/Customer/Model/Resource/Group/Grid/ServiceCollectionTest.php @@ -97,10 +97,19 @@ public function testSingleLikeFilter() /** * @expectedException \Magento\Framework\Exception\LocalizedException - * @expectedExceptionMessage When passing in a field array there must be a matching condition array. + * @expectedExceptionMessage When passing an array of fields there must be at least one field in the array. */ public function testAddToFilterException() { $this->collection->addFieldToFilter([], 'not_array'); } + + /** + * @expectedException \Magento\Framework\Exception\LocalizedException + * @expectedExceptionMessage When passing in a field array there must be a matching condition array. + */ + public function testAddToFilterExceptionArrayNotSymmetric() + { + $this->collection->addFieldToFilter(['field2', 'field2'], ['condition1']); + } } diff --git a/dev/tests/integration/testsuite/Magento/Shipping/Helper/DataTest.php b/dev/tests/integration/testsuite/Magento/Shipping/Helper/DataTest.php index b242bb0ef8464..b94bcc54d13db 100644 --- a/dev/tests/integration/testsuite/Magento/Shipping/Helper/DataTest.php +++ b/dev/tests/integration/testsuite/Magento/Shipping/Helper/DataTest.php @@ -32,8 +32,8 @@ public function testGetTrackingPopupUrlBySalesModel($modelName, $getIdMethod, $e $objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager(); $constructArgs = []; if ('Magento\Sales\Model\Order\Shipment' == $modelName) { - $orderFactory = $this->_getMockOrderFactory($code); - $constructArgs['orderFactory'] = $orderFactory; + $orderRepository = $this->_getMockOrderRepository($code); + $constructArgs['orderRepository'] = $orderRepository; } elseif ('Magento\Sales\Model\Order\Shipment\Track' == $modelName) { $shipmentRepository = $this->_getMockShipmentRepository($code); $constructArgs['shipmentRepository'] = $shipmentRepository; @@ -52,16 +52,16 @@ public function testGetTrackingPopupUrlBySalesModel($modelName, $getIdMethod, $e /** * @param $code - * @return \Magento\Sales\Model\OrderFactory + * @return \Magento\Sales\Api\OrderRepositoryInterface */ - protected function _getMockOrderFactory($code) + protected function _getMockOrderRepository($code) { $objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager(); $order = $objectManager->create('Magento\Sales\Model\Order'); $order->setProtectCode($code); - $orderFactory = $this->getMock('Magento\Sales\Model\OrderFactory', ['create'], [], '', false); - $orderFactory->expects($this->atLeastOnce())->method('create')->will($this->returnValue($order)); - return $orderFactory; + $orderRepository = $this->getMock('Magento\Sales\Api\OrderRepositoryInterface', [], [], '', false); + $orderRepository->expects($this->atLeastOnce())->method('get')->will($this->returnValue($order)); + return $orderRepository; } /** @@ -71,8 +71,8 @@ protected function _getMockOrderFactory($code) protected function _getMockShipmentRepository($code) { $objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager(); - $orderFactory = $this->_getMockOrderFactory($code); - $shipmentArgs = ['orderFactory' => $orderFactory]; + $orderRepository = $this->_getMockOrderRepository($code); + $shipmentArgs = ['orderRepository' => $orderRepository]; $shipment = $objectManager->create('Magento\Sales\Model\Order\Shipment', $shipmentArgs); $shipmentRepository = $this->getMock( diff --git a/lib/internal/Magento/Framework/Api/AbstractServiceCollection.php b/lib/internal/Magento/Framework/Api/AbstractServiceCollection.php index a834a2151282e..c7c910a4c07be 100644 --- a/lib/internal/Magento/Framework/Api/AbstractServiceCollection.php +++ b/lib/internal/Magento/Framework/Api/AbstractServiceCollection.php @@ -96,6 +96,9 @@ public function __construct( *
      * $field = ['age', 'name'];
      * $condition = [42, ['like' => 'Mage']];
+     * or
+     * ['rate', 'tax_postcode']
+     * [['from'=>"3",'to'=>'8.25'], ['like' =>'%91000%']];
      * 
* The above would find where age equal to 42 OR name like %Mage%. * @@ -106,15 +109,94 @@ public function __construct( */ public function addFieldToFilter($field, $condition) { - if (is_array($field) && count($field) != count($condition)) { + if (is_array($field) && is_array($condition) && count($field) != count($condition)) { throw new LocalizedException( new \Magento\Framework\Phrase('When passing in a field array there must be a matching condition array.') ); + } elseif (is_array($field) && !count($field) > 0) { + throw new LocalizedException( + new \Magento\Framework\Phrase( + 'When passing an array of fields there must be at least one field in the array.' + ) + ); + } + $this->processFilters($field, $condition); + return $this; + } + + /** + * Pre-process filters to create multiple groups in case of multiple conditions eg: from & to + * @param string|array $field + * @param string|int|array $condition + * @return $this + */ + private function processFilters($field, $condition) + { + //test if we have multiple conditions per field + $requiresMultipleFilterGroups = false; + if (is_array($field) && is_array($condition)) { + foreach ($condition as $cond) { + if (is_array($cond) && count($cond) > 1) { + $requiresMultipleFilterGroups = true; + break; + } + } + } elseif (is_array($condition)) { + $requiresMultipleFilterGroups = true; + } + + if ($requiresMultipleFilterGroups) { + $this->addFilterGroupsForMultipleConditions($field, $condition); + } else { + $this->addFilterGroupsForSingleConditions($field, $condition); } + return $this; + } + + /** + * Return a single filter group in case of single conditions + * @param string|array $field + * @param string|int|array $condition + * @return $this + */ + private function addFilterGroupsForSingleConditions($field, $condition) + { $this->fieldFilters[] = ['field' => $field, 'condition' => $condition]; return $this; } + /** + * Return multiple filters groups in case of multiple conditions eg: from & to + * @param string|array $field + * @param array $condition + * @return $this + */ + private function addFilterGroupsForMultipleConditions($field, $condition) + { + if (!is_array($field) && is_array($condition)) { + foreach ($condition as $key => $value) { + $this->fieldFilters[] = ['field' => $field, 'condition' => [$key => $value]]; + } + } else { + $cnt = 0; + foreach ($condition as $cond) { + if (is_array($cond)) { + //we Do want multiple groups in this case + foreach ($cond as $condKey => $condValue) { + $this->fieldFilters[] = [ + 'field' => array_slice($field, $cnt, 1, true), + 'condition' => [$condKey => $condValue] + ]; + } + } else { + $this->fieldFilters[] = ['field' => array_slice($field, $cnt, 1, true), 'condition' => $cond]; + } + $cnt++; + } + } + return $this; + } + /** * Creates a search criteria DTO based on the array of field filters. * diff --git a/lib/internal/Magento/Framework/Pricing/Render/Amount.php b/lib/internal/Magento/Framework/Pricing/Render/Amount.php index a17c6d08af4c5..0f91eedf9850b 100644 --- a/lib/internal/Magento/Framework/Pricing/Render/Amount.php +++ b/lib/internal/Magento/Framework/Pricing/Render/Amount.php @@ -207,9 +207,11 @@ protected function getAdjustments($adjustmentRenders) $data = $this->getData(); $adjustments = []; foreach ($adjustmentRenders as $adjustmentRender) { - $html = $adjustmentRender->render($this, $data); - if (trim($html)) { - $adjustments[$adjustmentRender->getAdjustmentCode()] = $html; + if ($this->getAmount()->getAdjustmentAmount($adjustmentRender->getAdjustmentCode()) !== false) { + $html = $adjustmentRender->render($this, $data); + if (trim($html)) { + $adjustments[$adjustmentRender->getAdjustmentCode()] = $html; + } } } return $adjustments; diff --git a/lib/internal/Magento/Framework/Pricing/Test/Unit/Render/AmountTest.php b/lib/internal/Magento/Framework/Pricing/Test/Unit/Render/AmountTest.php index fbf8d4f834f2f..75d87e1f96ca4 100644 --- a/lib/internal/Magento/Framework/Pricing/Test/Unit/Render/AmountTest.php +++ b/lib/internal/Magento/Framework/Pricing/Test/Unit/Render/AmountTest.php @@ -169,6 +169,9 @@ public function testToHtmlGetAdjustmentRenders() $this->rendererPool->expects($this->once()) ->method('getAdjustmentRenders') ->will($this->returnValue($adjustmentRenders)); + $this->amount->expects($this->atLeastOnce()) + ->method('getAdjustmentAmount') + ->willReturn(true); $this->model->toHtml(); } @@ -226,6 +229,9 @@ public function testAdjustmentsHtml() $this->rendererPool->expects($this->once()) ->method('getAdjustmentRenders') ->will($this->returnValue($adjustmentRenders)); + $this->amount->expects($this->atLeastOnce()) + ->method('getAdjustmentAmount') + ->willReturn(true); $this->model->toHtml();