diff --git a/app/code/Magento/Catalog/Model/ResourceModel/Product/Collection.php b/app/code/Magento/Catalog/Model/ResourceModel/Product/Collection.php index 925c9fe60855d247fef190d9b4bce3322eb0cafb..cb39273d3553ebf4b15748424aa3044922c6266f 100644 --- a/app/code/Magento/Catalog/Model/ResourceModel/Product/Collection.php +++ b/app/code/Magento/Catalog/Model/ResourceModel/Product/Collection.php @@ -1670,7 +1670,7 @@ class Collection extends \Magento\Catalog\Model\ResourceModel\Collection\Abstrac return $this; } elseif ($attribute == 'is_saleable') { - $this->getSelect()->order("is_saleable " . $dir); + $this->getSelect()->order("is_salable " . $dir); return $this; } diff --git a/app/code/Magento/Checkout/view/frontend/web/js/view/configure/product-customer-data.js b/app/code/Magento/Checkout/view/frontend/web/js/view/configure/product-customer-data.js index a612b5e2dc6b7d38fa365911b81d67e5a3ca2aaa..d7a81decbadefb5473027e4f69d64b910649e96e 100644 --- a/app/code/Magento/Checkout/view/frontend/web/js/view/configure/product-customer-data.js +++ b/app/code/Magento/Checkout/view/frontend/web/js/view/configure/product-customer-data.js @@ -1,6 +1,7 @@ require([ 'jquery', - 'Magento_Customer/js/customer-data' + 'Magento_Customer/js/customer-data', + 'domReady!' ], function ($, customerData) { 'use strict'; diff --git a/app/code/Magento/Customer/etc/webapi_rest/di.xml b/app/code/Magento/Customer/etc/webapi_rest/di.xml index f2457963a5f3dc5336d7afce5a973b3ae2600844..5f3ca2fdb745391ae72d81a4fdcd75e90ff49307 100644 --- a/app/code/Magento/Customer/etc/webapi_rest/di.xml +++ b/app/code/Magento/Customer/etc/webapi_rest/di.xml @@ -13,7 +13,7 @@ <arguments> <argument name="userContexts" xsi:type="array"> <item name="customerSessionUserContext" xsi:type="array"> - <item name="type" xsi:type="object">Magento\Customer\Model\Authorization\CustomerSessionUserContext</item> + <item name="type" xsi:type="object">Magento\Customer\Model\Authorization\CustomerSessionUserContext\Proxy</item> <item name="sortOrder" xsi:type="string">20</item> </item> </argument> diff --git a/app/code/Magento/SalesRule/view/adminhtml/layout/sales_rule_promo_quote_edit.xml b/app/code/Magento/SalesRule/view/adminhtml/layout/sales_rule_promo_quote_edit.xml index ad5bbbd262da79def247ca7f775f04ecf1153cb7..3366af650f8e9fddd683b47750e8f94bffb4a58b 100644 --- a/app/code/Magento/SalesRule/view/adminhtml/layout/sales_rule_promo_quote_edit.xml +++ b/app/code/Magento/SalesRule/view/adminhtml/layout/sales_rule_promo_quote_edit.xml @@ -6,6 +6,7 @@ */ --> <page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd"> + <update handle="styles" /> <body> <referenceContainer name="content"> <uiComponent name="sales_rule_form"/> diff --git a/app/code/Magento/Shipping/Controller/Adminhtml/Order/Shipment/Email.php b/app/code/Magento/Shipping/Controller/Adminhtml/Order/Shipment/Email.php index 1f5d6e2cb7a892083221788240d62ec9fe1ffcb5..f08204fdff0d7fb4f5a8b8fd1bbf592ba487be49 100644 --- a/app/code/Magento/Shipping/Controller/Adminhtml/Order/Shipment/Email.php +++ b/app/code/Magento/Shipping/Controller/Adminhtml/Order/Shipment/Email.php @@ -57,7 +57,9 @@ class Email extends \Magento\Backend\App\Action $this->_objectManager->create(\Magento\Shipping\Model\ShipmentNotifier::class) ->notify($shipment); $shipment->save(); - $this->messageManager->addSuccess(__('You sent the shipment.')); + $this->messageManager->addSuccess( + __('An email confirming the order is underway has been sent to the customer.') + ); } } catch (\Magento\Framework\Exception\LocalizedException $e) { $this->messageManager->addError($e->getMessage()); diff --git a/app/code/Magento/Shipping/Test/Unit/Controller/Adminhtml/Order/Shipment/EmailTest.php b/app/code/Magento/Shipping/Test/Unit/Controller/Adminhtml/Order/Shipment/EmailTest.php index 7e4e27efe5ba7683b5b960c1666a63f3bb400047..3507b7fe2e2744451b55fc76bc7c78ce665c45b9 100644 --- a/app/code/Magento/Shipping/Test/Unit/Controller/Adminhtml/Order/Shipment/EmailTest.php +++ b/app/code/Magento/Shipping/Test/Unit/Controller/Adminhtml/Order/Shipment/EmailTest.php @@ -207,7 +207,7 @@ class EmailTest extends \PHPUnit\Framework\TestCase ->will($this->returnValue(true)); $this->messageManager->expects($this->once()) ->method('addSuccess') - ->with('You sent the shipment.'); + ->with('An email confirming the order is underway has been sent to the customer.'); $path = '*/*/view'; $arguments = ['shipment_id' => $shipmentId]; $this->prepareRedirect($path, $arguments, 0); diff --git a/app/code/Magento/Shipping/i18n/en_US.csv b/app/code/Magento/Shipping/i18n/en_US.csv index f777e64ef98c9a54f6f8239d340b1d1a4cc82611..0bda9d2a71477d40f83d2971838fa80085be5833 100644 --- a/app/code/Magento/Shipping/i18n/en_US.csv +++ b/app/code/Magento/Shipping/i18n/en_US.csv @@ -28,7 +28,7 @@ Shipments,Shipments "Cannot add tracking number.","Cannot add tracking number." "You created the shipping label.","You created the shipping label." "An error occurred while creating shipping label.","An error occurred while creating shipping label." -"You sent the shipment.","You sent the shipment." +"An email confirming the order is underway has been sent to the customer.","An email confirming the order is underway has been sent to the customer." "Cannot send shipment information.","Cannot send shipment information." "There are no shipping labels related to selected orders.","There are no shipping labels related to selected orders." "New Shipment","New Shipment" diff --git a/app/code/Magento/User/etc/webapi_rest/di.xml b/app/code/Magento/User/etc/webapi_rest/di.xml index 7c6cccb454df75b1edef806d8b697a56d478e164..930e505648d9c9dbfc04e27a42381fdb2199cb61 100644 --- a/app/code/Magento/User/etc/webapi_rest/di.xml +++ b/app/code/Magento/User/etc/webapi_rest/di.xml @@ -10,7 +10,7 @@ <arguments> <argument name="userContexts" xsi:type="array"> <item name="adminSessionUserContext" xsi:type="array"> - <item name="type" xsi:type="object">Magento\User\Model\Authorization\AdminSessionUserContext</item> + <item name="type" xsi:type="object">Magento\User\Model\Authorization\AdminSessionUserContext\Proxy</item> <item name="sortOrder" xsi:type="string">30</item> </item> </argument> diff --git a/dev/tests/integration/testsuite/Magento/Catalog/Model/ResourceModel/Product/CollectionTest.php b/dev/tests/integration/testsuite/Magento/Catalog/Model/ResourceModel/Product/CollectionTest.php index da47201fe6e38c3218c5ac99f41794c2b959a41c..caa0b2734bb20c4fa156ff8bd2115073b13a8bde 100644 --- a/dev/tests/integration/testsuite/Magento/Catalog/Model/ResourceModel/Product/CollectionTest.php +++ b/dev/tests/integration/testsuite/Magento/Catalog/Model/ResourceModel/Product/CollectionTest.php @@ -124,4 +124,40 @@ class CollectionTest extends \PHPUnit\Framework\TestCase $this->assertEquals(50, $tierPrices[2]->getExtensionAttributes()->getPercentageValue()); $this->assertEquals(5, $tierPrices[2]->getValue()); } + + /** + * Test addAttributeToSort() with attribute 'is_saleable' works properly on frontend. + * + * @dataProvider addAttributeToSortDataProvider + * @magentoDataFixture Magento/Catalog/_files/multiple_products_with_non_saleable_product.php + * @magentoConfigFixture current_store cataloginventory/options/show_out_of_stock 1 + * @magentoAppIsolation enabled + * @magentoAppArea frontend + */ + public function testAddAttributeToSort(string $productSku, string $order) + { + /** @var Collection $productCollection */ + $this->collection->addAttributeToSort('is_saleable', $order); + self::assertEquals(2, $this->collection->count()); + self::assertSame($productSku, $this->collection->getFirstItem()->getSku()); + } + + /** + * Provide test data for testAddAttributeToSort(). + * + * @return array + */ + public function addAttributeToSortDataProvider() + { + return [ + [ + 'product_sku' => 'simple_saleable', + 'order' => Collection::SORT_ORDER_DESC, + ], + [ + 'product_sku' => 'simple_not_saleable', + 'order' => Collection::SORT_ORDER_ASC, + ] + ]; + } } diff --git a/dev/tests/integration/testsuite/Magento/Catalog/_files/multiple_products_with_non_saleable_product.php b/dev/tests/integration/testsuite/Magento/Catalog/_files/multiple_products_with_non_saleable_product.php new file mode 100644 index 0000000000000000000000000000000000000000..2286b2abffd0f6cbfb52af925bfd970f95e780c9 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Catalog/_files/multiple_products_with_non_saleable_product.php @@ -0,0 +1,52 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +/** @var $product \Magento\Catalog\Model\Product */ +$product = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create(\Magento\Catalog\Model\Product::class); +$product->isObjectNew(true); +$product->setTypeId(\Magento\Catalog\Model\Product\Type::TYPE_SIMPLE) + ->setAttributeSetId(4) + ->setName('Simple Product') + ->setSku('simple_saleable') + ->setTaxClassId('none') + ->setDescription('description') + ->setShortDescription('short description') + ->setOptionsContainer('container1') + ->setMsrpDisplayActualPriceType(\Magento\Msrp\Model\Product\Attribute\Source\Type::TYPE_IN_CART) + ->setPrice(10) + ->setWeight(1) + ->setMetaTitle('meta title') + ->setMetaKeyword('meta keyword') + ->setMetaDescription('meta description') + ->setVisibility(\Magento\Catalog\Model\Product\Visibility::VISIBILITY_BOTH) + ->setStatus(\Magento\Catalog\Model\Product\Attribute\Source\Status::STATUS_ENABLED) + ->setWebsiteIds([1]) + ->setCateroryIds([]) + ->setStockData(['use_config_manage_stock' => 1, 'qty' => 100, 'is_qty_decimal' => 0, 'is_in_stock' => 1]) + ->save(); + +$product = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create(\Magento\Catalog\Model\Product::class); +$product->isObjectNew(true); +$product->setTypeId(\Magento\Catalog\Model\Product\Type::TYPE_SIMPLE) + ->setAttributeSetId(4) + ->setName('Simple Product2') + ->setSku('simple_not_saleable') + ->setTaxClassId('none') + ->setDescription('description') + ->setShortDescription('short description') + ->setOptionsContainer('container1') + ->setMsrpDisplayActualPriceType(\Magento\Msrp\Model\Product\Attribute\Source\Type::TYPE_ON_GESTURE) + ->setPrice(20) + ->setWeight(1) + ->setMetaTitle('meta title') + ->setMetaKeyword('meta keyword') + ->setMetaDescription('meta description') + ->setVisibility(\Magento\Catalog\Model\Product\Visibility::VISIBILITY_IN_CATALOG) + ->setStatus(\Magento\Catalog\Model\Product\Attribute\Source\Status::STATUS_ENABLED) + ->setWebsiteIds([1]) + ->setCateroryIds([]) + ->setStockData(['use_config_manage_stock' => 1, 'qty' => 50, 'is_qty_decimal' => 0, 'is_in_stock' => 0]) + ->save(); diff --git a/dev/tests/integration/testsuite/Magento/Catalog/_files/multiple_products_with_non_saleable_product_rollback.php b/dev/tests/integration/testsuite/Magento/Catalog/_files/multiple_products_with_non_saleable_product_rollback.php new file mode 100644 index 0000000000000000000000000000000000000000..63fffd1894b0342e730bc949daef574ad7225929 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Catalog/_files/multiple_products_with_non_saleable_product_rollback.php @@ -0,0 +1,28 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +$objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager(); + +/** @var \Magento\Framework\Registry $registry */ +$registry = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get(\Magento\Framework\Registry::class); + +$registry->unregister('isSecureArea'); +$registry->register('isSecureArea', true); + +/** @var \Magento\Catalog\Api\ProductRepositoryInterface $productRepository */ +$productRepository = $objectManager->create(\Magento\Catalog\Api\ProductRepositoryInterface::class); + +foreach (['simple_saleable', 'simple_not_saleable'] as $sku) { + try { + $product = $productRepository->get($sku, false, null, true); + $productRepository->delete($product); + } catch (\Magento\Framework\Exception\NoSuchEntityException $exception) { + //Product already removed + } +} + +$registry->unregister('isSecureArea'); +$registry->register('isSecureArea', false);