diff --git a/app/code/Magento/Multishipping/Model/Checkout/Type/Multishipping.php b/app/code/Magento/Multishipping/Model/Checkout/Type/Multishipping.php index f9d6d0adaae93..767f58bb9e4ed 100644 --- a/app/code/Magento/Multishipping/Model/Checkout/Type/Multishipping.php +++ b/app/code/Magento/Multishipping/Model/Checkout/Type/Multishipping.php @@ -817,13 +817,21 @@ public function reset() */ public function validateMinimumAmount() { - return !($this->_scopeConfig->isSetFlag( + $minimumOrderActive = $this->_scopeConfig->isSetFlag( 'sales/minimum_order/active', \Magento\Store\Model\ScopeInterface::SCOPE_STORE - ) && $this->_scopeConfig->isSetFlag( + ); + + if ($this->_scopeConfig->isSetFlag( 'sales/minimum_order/multi_address', - \Magento\Store\Model\ScopeInterface::SCOPE_STORE - ) && !$this->getQuote()->validateMinimumAmount()); + \Magento\Store\Model\ScopeInterface::SCOPE_STORE) + ) { + $result = !($minimumOrderActive && !$this->getQuote()->validateMinimumAmount()); + } else { + $result = !($minimumOrderActive && !$this->validateMinimumAmountForAddressItems()); + } + + return $result; } /** @@ -1031,4 +1039,41 @@ private function getShippingAssignmentProcessor() } return $this->shippingAssignmentProcessor; } + + /** + * Validate minimum amount for "Checkout with Multiple Addresses" when + * "Validate Each Address Separately in Multi-address Checkout" is No. + * + * @return bool + */ + private function validateMinimumAmountForAddressItems() + { + $result = true; + $storeId = $this->getQuote()->getStoreId(); + + $minAmount = $this->_scopeConfig->getValue( + 'sales/minimum_order/amount', + \Magento\Store\Model\ScopeInterface::SCOPE_STORE, + $storeId + ); + $taxInclude = $this->_scopeConfig->getValue( + 'sales/minimum_order/tax_including', + \Magento\Store\Model\ScopeInterface::SCOPE_STORE, + $storeId + ); + + $addresses = $this->getQuote()->getAllAddresses(); + + $baseTotal = 0; + foreach ($addresses as $address) { + $taxes = $taxInclude ? $address->getBaseTaxAmount() : 0; + $baseTotal += $address->getBaseSubtotalWithDiscount() + $taxes; + } + + if ($baseTotal < $minAmount) { + $result = false; + } + + return $result; + } } diff --git a/app/code/Magento/Multishipping/Test/Unit/Model/Checkout/Type/MultishippingTest.php b/app/code/Magento/Multishipping/Test/Unit/Model/Checkout/Type/MultishippingTest.php index 1d779c11d5935..f90e85a904352 100644 --- a/app/code/Magento/Multishipping/Test/Unit/Model/Checkout/Type/MultishippingTest.php +++ b/app/code/Magento/Multishipping/Test/Unit/Model/Checkout/Type/MultishippingTest.php @@ -118,13 +118,18 @@ class MultishippingTest extends \PHPUnit\Framework\TestCase */ private $quoteRepositoryMock; + /** + * @var PHPUnit_Framework_MockObject_MockObject + */ + private $scopeConfigMock; + protected function setUp() { $this->checkoutSessionMock = $this->createSimpleMock(Session::class); $this->customerSessionMock = $this->createSimpleMock(CustomerSession::class); $orderFactoryMock = $this->createSimpleMock(OrderFactory::class); $eventManagerMock = $this->createSimpleMock(ManagerInterface::class); - $scopeConfigMock = $this->createSimpleMock(ScopeConfigInterface::class); + $this->scopeConfigMock = $this->createSimpleMock(ScopeConfigInterface::class); $sessionMock = $this->createSimpleMock(Generic::class); $addressFactoryMock = $this->createSimpleMock(AddressFactory::class); $toOrderMock = $this->createSimpleMock(ToOrder::class); @@ -166,7 +171,7 @@ protected function setUp() $orderFactoryMock, $this->addressRepositoryMock, $eventManagerMock, - $scopeConfigMock, + $this->scopeConfigMock, $sessionMock, $addressFactoryMock, $toOrderMock, @@ -497,4 +502,37 @@ private function createSimpleMock($className) ->disableOriginalConstructor() ->getMock(); } + + public function testValidateMinimumAmountMultiAddressTrue() + { + $this->scopeConfigMock->expects($this->exactly(2))->method('isSetFlag')->withConsecutive( + ['sales/minimum_order/active', \Magento\Store\Model\ScopeInterface::SCOPE_STORE], + ['sales/minimum_order/multi_address', \Magento\Store\Model\ScopeInterface::SCOPE_STORE] + )->willReturnOnConsecutiveCalls(true, true); + + $this->checkoutSessionMock->expects($this->atLeastOnce())->method('getQuote')->willReturn($this->quoteMock); + $this->quoteMock->expects($this->once())->method('validateMinimumAmount')->willReturn(false); + $this->assertFalse($this->model->validateMinimumAmount()); + } + + public function testValidateMinimumAmountMultiAddressFalse() + { + $addressMock = $this->createMock(\Magento\Quote\Model\Quote\Address::class); + $this->scopeConfigMock->expects($this->exactly(2))->method('isSetFlag')->withConsecutive( + ['sales/minimum_order/active', \Magento\Store\Model\ScopeInterface::SCOPE_STORE], + ['sales/minimum_order/multi_address', \Magento\Store\Model\ScopeInterface::SCOPE_STORE] + )->willReturnOnConsecutiveCalls(true, false); + + $this->scopeConfigMock->expects($this->exactly(2))->method('getValue')->withConsecutive( + ['sales/minimum_order/amount', \Magento\Store\Model\ScopeInterface::SCOPE_STORE], + ['sales/minimum_order/tax_including', \Magento\Store\Model\ScopeInterface::SCOPE_STORE] + )->willReturnOnConsecutiveCalls(100, false); + + $this->checkoutSessionMock->expects($this->atLeastOnce())->method('getQuote')->willReturn($this->quoteMock); + $this->quoteMock->expects($this->once())->method('getStoreId')->willReturn(1); + $this->quoteMock->expects($this->once())->method('getAllAddresses')->willReturn([$addressMock]); + $addressMock->expects($this->once())->method('getBaseSubtotalWithDiscount')->willReturn(101); + + $this->assertTrue($this->model->validateMinimumAmount()); + } }