456 lines
16 KiB
PHP
Executable File
456 lines
16 KiB
PHP
Executable File
<?php
|
|
/**
|
|
* Copyright © Magento, Inc. All rights reserved.
|
|
* See COPYING.txt for license details.
|
|
*/
|
|
|
|
namespace Magento\Tax\Model;
|
|
|
|
use Magento\Framework\Api\Filter;
|
|
use Magento\TestFramework\Helper\Bootstrap;
|
|
|
|
/**
|
|
* @SuppressWarnings(PHPMD.CouplingBetweenObjects)
|
|
*/
|
|
class TaxRuleRepositoryTest extends \PHPUnit\Framework\TestCase
|
|
{
|
|
/**
|
|
* @var \Magento\Framework\ObjectManagerInterface
|
|
*/
|
|
private $objectManager;
|
|
|
|
/**
|
|
* @var \Magento\Tax\Api\Data\TaxRuleInterfaceFactory
|
|
*/
|
|
private $taxRuleFactory;
|
|
|
|
/**
|
|
* @var \Magento\Tax\Api\TaxRuleRepositoryInterface
|
|
*/
|
|
private $taxRuleRepository;
|
|
|
|
/**
|
|
* @var TaxRuleFixtureFactory
|
|
*/
|
|
private $taxRuleFixtureFactory;
|
|
|
|
/**
|
|
* Array of default tax classes ids
|
|
*
|
|
* Key is class name
|
|
*
|
|
* @var int[]
|
|
*/
|
|
private $taxClasses;
|
|
|
|
/**
|
|
* Array of default tax rates ids.
|
|
*
|
|
* Key is rate percentage as string.
|
|
*
|
|
* @var int[]
|
|
*/
|
|
private $taxRates;
|
|
|
|
/**
|
|
* Array of default tax rules ids.
|
|
*
|
|
* Key is rule code.
|
|
*
|
|
* @var int[]
|
|
*/
|
|
private $taxRules;
|
|
|
|
/**
|
|
* @var \Magento\Tax\Api\TaxRateRepositoryInterface
|
|
*/
|
|
private $taxRateRepository;
|
|
|
|
/**
|
|
* @var \Magento\Framework\Api\DataObjectHelper
|
|
*/
|
|
private $dataObjectHelper;
|
|
|
|
protected function setUp(): void
|
|
{
|
|
$this->objectManager = Bootstrap::getObjectManager();
|
|
$this->taxRuleRepository = $this->objectManager->get(\Magento\Tax\Api\TaxRuleRepositoryInterface::class);
|
|
$this->taxRateRepository = $this->objectManager->get(\Magento\Tax\Api\TaxRateRepositoryInterface::class);
|
|
$this->taxRuleFactory = $this->objectManager->create(\Magento\Tax\Api\Data\TaxRuleInterfaceFactory::class);
|
|
$this->dataObjectHelper = $this->objectManager->create(\Magento\Framework\Api\DataObjectHelper::class);
|
|
$this->taxRuleFixtureFactory = new TaxRuleFixtureFactory();
|
|
}
|
|
|
|
/**
|
|
* @magentoDbIsolation enabled
|
|
*/
|
|
public function testSave()
|
|
{
|
|
// Tax rule data object created
|
|
$taxRuleDataObject = $this->createTaxRuleDataObject();
|
|
//Tax rule service call
|
|
$taxRule = $this->taxRuleRepository->save($taxRuleDataObject);
|
|
|
|
//Assertions
|
|
$this->assertInstanceOf(\Magento\Tax\Api\Data\TaxRuleInterface::class, $taxRule);
|
|
$this->assertEquals($taxRuleDataObject->getCode(), $taxRule->getCode());
|
|
$this->assertEquals(
|
|
$taxRuleDataObject->getCustomerTaxClassIds(),
|
|
$taxRule->getCustomerTaxClassIds()
|
|
);
|
|
$this->assertEquals($taxRuleDataObject->getProductTaxClassIds(), $taxRule->getProductTaxClassIds());
|
|
$this->assertEquals($taxRuleDataObject->getPriority(), $taxRule->getPriority());
|
|
$this->assertEquals($taxRuleDataObject->getPosition(), $taxRule->getPosition());
|
|
$this->assertNotNull($taxRule->getId());
|
|
}
|
|
|
|
/**
|
|
* @magentoDbIsolation enabled
|
|
*/
|
|
public function testSaveThrowsExceptionIdIfTargetTaxRuleDoesNotExist()
|
|
{
|
|
$this->expectException(\Magento\Framework\Exception\NoSuchEntityException::class);
|
|
$this->expectExceptionMessage('No such entity with taxRuleId = 9999');
|
|
|
|
$taxRuleDataObject = $this->taxRuleFactory->create();
|
|
$taxRuleDataObject->setId(9999)
|
|
->setCode('code')
|
|
->setCustomerTaxClassIds([3])
|
|
->setProductTaxClassIds([2])
|
|
->setTaxRateIds([2])
|
|
->setPriority(0)
|
|
->setPosition(1);
|
|
$this->taxRuleRepository->save($taxRuleDataObject);
|
|
}
|
|
|
|
/**
|
|
* @magentoDbIsolation enabled
|
|
*/
|
|
public function testSaveThrowsExceptionIfProvidedTaxClassIdsAreInvalid()
|
|
{
|
|
$this->expectException(\Magento\Framework\Exception\CouldNotSaveException::class);
|
|
$this->expectExceptionMessage('No such entity');
|
|
|
|
$taxRuleData = [
|
|
'code' => 'code',
|
|
// These TaxClassIds exist, but '2' is should be a productTaxClassId and
|
|
// '3' should be a customerTaxClassId. See MAGETWO-25683.
|
|
'customer_tax_class_ids' => [2],
|
|
'product_tax_class_ids' => [3],
|
|
'tax_rate_ids' => [1],
|
|
'priority' => 0,
|
|
'position' => 0,
|
|
];
|
|
// Tax rule data object created
|
|
$taxRule = $this->taxRuleFactory->create();
|
|
$this->dataObjectHelper->populateWithArray(
|
|
$taxRule,
|
|
$taxRuleData,
|
|
\Magento\Tax\Api\Data\TaxRuleInterface::class
|
|
);
|
|
|
|
$this->taxRuleRepository->save($taxRule);
|
|
}
|
|
|
|
/**
|
|
* @magentoDbIsolation enabled
|
|
*/
|
|
public function testSaveThrowsExceptionIfProvidedPositionIsInvalid()
|
|
{
|
|
$this->expectException(\Magento\Framework\Exception\CouldNotSaveException::class);
|
|
$this->expectExceptionMessage('The position value of "-1" must be greater than or equal to 0.');
|
|
|
|
$taxRuleData = [
|
|
'code' => 'code',
|
|
'customer_tax_class_ids' => [3],
|
|
'product_tax_class_ids' => [2],
|
|
'tax_rate_ids' => [1],
|
|
'priority' => 0,
|
|
'position' => -1,
|
|
];
|
|
// Tax rule data object created
|
|
$taxRule = $this->taxRuleFactory->create();
|
|
$this->dataObjectHelper->populateWithArray(
|
|
$taxRule,
|
|
$taxRuleData,
|
|
\Magento\Tax\Api\Data\TaxRuleInterface::class
|
|
);
|
|
|
|
//Tax rule service call
|
|
$this->taxRuleRepository->save($taxRule);
|
|
$this->fail('Did not throw expected InputException');
|
|
}
|
|
|
|
/**
|
|
* @magentoDbIsolation enabled
|
|
*/
|
|
public function testGetReturnsTaxRuleCreatedByRepository()
|
|
{
|
|
// Tax rule data object created
|
|
$taxRuleDataObject = $this->createTaxRuleDataObject();
|
|
//Tax rule service call to create rule
|
|
$ruleId = $this->taxRuleRepository->save($taxRuleDataObject)->getId();
|
|
|
|
// Call getTaxRule and verify
|
|
$taxRule = $this->taxRuleRepository->get($ruleId);
|
|
$this->assertEquals('code', $taxRule->getCode());
|
|
$this->assertEquals([3], $taxRule->getCustomerTaxClassIds());
|
|
$this->assertEquals([2], $taxRule->getProductTaxClassIds());
|
|
$this->assertEquals([2], $taxRule->getTaxRateIds());
|
|
$this->assertEquals(0, $taxRule->getPriority());
|
|
$this->assertEquals(1, $taxRule->getPosition());
|
|
}
|
|
|
|
/**
|
|
* @magentoDataFixture Magento/Tax/_files/tax_classes.php
|
|
*/
|
|
public function testGetReturnsTaxRuleCreatedFromModel()
|
|
{
|
|
/** @var $registry \Magento\Framework\Registry */
|
|
$registry = $this->objectManager->get(\Magento\Framework\Registry::class);
|
|
/** @var $taxRuleModel \Magento\Tax\Model\Calculation\Rule */
|
|
$taxRuleModel = $registry->registry('_fixture/Magento_Tax_Model_Calculation_Rule');
|
|
$this->assertNotNull($taxRuleModel);
|
|
$ruleId = $taxRuleModel->getId();
|
|
|
|
$taxRateId = $registry->registry('_fixture/Magento_Tax_Model_Calculation_Rate')->getId();
|
|
$customerTaxClassIds = array_values(array_unique($taxRuleModel->getCustomerTaxClasses()));
|
|
|
|
// Call getTaxRule and verify
|
|
$taxRule = $this->taxRuleRepository->get($ruleId);
|
|
$this->assertEquals($customerTaxClassIds, $taxRule->getCustomerTaxClassIds());
|
|
$this->assertEquals([$taxRateId], $taxRule->getTaxRateIds());
|
|
}
|
|
|
|
/**
|
|
* @magentoDataFixture Magento/Tax/_files/tax_classes.php
|
|
*/
|
|
public function testDeleteById()
|
|
{
|
|
$this->expectException(\Magento\Framework\Exception\NoSuchEntityException::class);
|
|
$this->expectExceptionMessage('No such entity with taxRuleId');
|
|
|
|
/** @var $registry \Magento\Framework\Registry */
|
|
$registry = $this->objectManager->get(\Magento\Framework\Registry::class);
|
|
/** @var $taxRule \Magento\Tax\Model\Calculation\Rule */
|
|
$taxRule = $registry->registry('_fixture/Magento_Tax_Model_Calculation_Rule');
|
|
$this->assertNotNull($taxRule);
|
|
$ruleId = $taxRule->getId();
|
|
|
|
// Delete the new tax rate
|
|
$this->assertTrue($this->taxRuleRepository->deleteById($ruleId));
|
|
|
|
// Get the new tax rule, this should fail
|
|
$this->taxRuleRepository->get($ruleId);
|
|
}
|
|
|
|
/**
|
|
* @magentoDataFixture Magento/Tax/_files/tax_classes.php
|
|
*/
|
|
public function testDeleteByIdThrowsExceptionIfTargetTaxRuleDoesNotExist()
|
|
{
|
|
$this->expectException(\Magento\Framework\Exception\NoSuchEntityException::class);
|
|
$this->expectExceptionMessage('No such entity with taxRuleId');
|
|
|
|
/** @var $registry \Magento\Framework\Registry */
|
|
$registry = $this->objectManager->get(\Magento\Framework\Registry::class);
|
|
/** @var $taxRule \Magento\Tax\Model\Calculation\Rule */
|
|
$taxRule = $registry->registry('_fixture/Magento_Tax_Model_Calculation_Rule');
|
|
$this->assertNotNull($taxRule);
|
|
$ruleId = $taxRule->getId();
|
|
|
|
// Delete the new tax rule
|
|
$this->assertTrue($this->taxRuleRepository->deleteById($ruleId));
|
|
// Delete the new tax rule again, this should fail
|
|
$this->taxRuleRepository->deleteById($ruleId);
|
|
}
|
|
|
|
/**
|
|
* @magentoDbIsolation enabled
|
|
*/
|
|
public function testSaveUpdatesExistingTaxRule()
|
|
{
|
|
$taxRule = $this->createTaxRuleDataObject();
|
|
//Tax rule service call
|
|
$taxRule = $this->taxRuleRepository->save($taxRule);
|
|
$taxRule->setCode('updated code');
|
|
$this->taxRuleRepository->save($taxRule);
|
|
$retrievedRule = $this->taxRuleRepository->get($taxRule->getId());
|
|
|
|
$this->assertEquals('updated code', $retrievedRule->getCode());
|
|
}
|
|
|
|
/**
|
|
* @magentoDbIsolation enabled
|
|
*/
|
|
public function testSaveThrowsExceptionIsRequiredFieldsAreMissing()
|
|
{
|
|
$this->expectException(\Magento\Framework\Exception\CouldNotSaveException::class);
|
|
$this->expectExceptionMessage('"code" is required. Enter and try again.');
|
|
|
|
$taxRule = $this->taxRuleRepository->save($this->createTaxRuleDataObject());
|
|
$taxRule->setCode(null);
|
|
|
|
$this->taxRuleRepository->save($taxRule);
|
|
}
|
|
|
|
/**
|
|
*
|
|
* @param Filter[] $filters
|
|
* @param Filter[] $filterGroup
|
|
* @param string[] $expectedRuleCodes The codes of the tax rules that are expected to be found
|
|
*
|
|
* @magentoDbIsolation enabled
|
|
* @dataProvider searchTaxRulesDataProvider
|
|
*/
|
|
public function testGetList($filters, $filterGroup, $expectedRuleCodes)
|
|
{
|
|
$this->setUpDefaultRules();
|
|
|
|
/** @var \Magento\Framework\Api\SearchCriteriaBuilder $searchBuilder */
|
|
$searchBuilder = Bootstrap::getObjectManager()
|
|
->create(\Magento\Framework\Api\SearchCriteriaBuilder::class);
|
|
foreach ($filters as $filter) {
|
|
$searchBuilder->addFilters([$filter]);
|
|
}
|
|
if ($filterGroup !== null) {
|
|
$searchBuilder->addFilters($filterGroup);
|
|
}
|
|
$searchCriteria = $searchBuilder->create();
|
|
|
|
$searchResults = $this->taxRuleRepository->getList($searchCriteria);
|
|
$items = [];
|
|
foreach ($expectedRuleCodes as $ruleCode) {
|
|
$ruleId = $this->taxRules[$ruleCode];
|
|
$items[] = $this->taxRuleRepository->get($ruleId);
|
|
}
|
|
|
|
$this->assertEquals($searchCriteria, $searchResults->getSearchCriteria());
|
|
$this->assertEquals(count($expectedRuleCodes), $searchResults->getTotalCount());
|
|
foreach ($searchResults->getItems() as $rule) {
|
|
$this->assertContains($rule->getCode(), $expectedRuleCodes);
|
|
}
|
|
|
|
$this->tearDownDefaultRules();
|
|
}
|
|
|
|
public function searchTaxRulesDataProvider()
|
|
{
|
|
$filterBuilder = Bootstrap::getObjectManager()->create(\Magento\Framework\Api\FilterBuilder::class);
|
|
|
|
return [
|
|
'code eq "Default Rule"' => [
|
|
[$filterBuilder->setField('code')->setValue('Default Rule')->create()],
|
|
null,
|
|
['Default Rule'],
|
|
],
|
|
'customer_tax_class_ids eq 3 AND priority eq 0' => [
|
|
[
|
|
$filterBuilder->setField('customer_tax_class_ids')->setValue(3)->create(),
|
|
$filterBuilder->setField('priority')->setValue('0')->create(),
|
|
],
|
|
[],
|
|
['Default Rule', 'Higher Rate Rule'],
|
|
],
|
|
'code eq "Default Rule" OR code eq "Higher Rate Rule"' => [
|
|
[],
|
|
[
|
|
$filterBuilder->setField('code')->setValue('Default Rule')->create(),
|
|
$filterBuilder->setField('code')->setValue('Higher Rate Rule')->create(),
|
|
],
|
|
['Default Rule', 'Higher Rate Rule'],
|
|
],
|
|
'code like "%Rule"' => [
|
|
[
|
|
$filterBuilder->setField('code')->setValue('%Rule')->setConditionType('like')
|
|
->create(),
|
|
],
|
|
[],
|
|
['Default Rule', 'Higher Rate Rule'],
|
|
],
|
|
];
|
|
}
|
|
|
|
/**
|
|
* Helper function that sets up some default rules
|
|
*/
|
|
private function setUpDefaultRules()
|
|
{
|
|
$this->taxClasses = $this->taxRuleFixtureFactory->createTaxClasses([
|
|
['name' => 'DefaultCustomerClass', 'type' => ClassModel::TAX_CLASS_TYPE_CUSTOMER],
|
|
['name' => 'DefaultProductClass', 'type' => ClassModel::TAX_CLASS_TYPE_PRODUCT],
|
|
['name' => 'HigherProductClass', 'type' => ClassModel::TAX_CLASS_TYPE_PRODUCT],
|
|
]);
|
|
|
|
$this->taxRates = $this->taxRuleFixtureFactory->createTaxRates([
|
|
['percentage' => 7.5, 'country' => 'US', 'region' => 42],
|
|
['percentage' => 7.5, 'country' => 'US', 'region' => 12], // Default store rate
|
|
]);
|
|
|
|
$higherRates = $this->taxRuleFixtureFactory->createTaxRates([
|
|
['percentage' => 22, 'country' => 'US', 'region' => 42],
|
|
['percentage' => 10, 'country' => 'US', 'region' => 12], // Default store rate
|
|
]);
|
|
|
|
$this->taxRules = $this->taxRuleFixtureFactory->createTaxRules([
|
|
[
|
|
'code' => 'Default Rule',
|
|
'customer_tax_class_ids' => [$this->taxClasses['DefaultCustomerClass'], 3],
|
|
'product_tax_class_ids' => [$this->taxClasses['DefaultProductClass']],
|
|
'tax_rate_ids' => array_values($this->taxRates),
|
|
'sort_order' => 0,
|
|
'priority' => 0,
|
|
'calculate_subtotal' => 1,
|
|
],
|
|
[
|
|
'code' => 'Higher Rate Rule',
|
|
'customer_tax_class_ids' => [$this->taxClasses['DefaultCustomerClass'], 3],
|
|
'product_tax_class_ids' => [$this->taxClasses['HigherProductClass']],
|
|
'tax_rate_ids' => array_values($higherRates),
|
|
'sort_order' => 0,
|
|
'priority' => 0,
|
|
'calculate_subtotal' => 1,
|
|
],
|
|
[
|
|
'code' => 'Highest Rate',
|
|
'customer_tax_class_ids' => [$this->taxClasses['DefaultCustomerClass'], 3],
|
|
'product_tax_class_ids' => [$this->taxClasses['HigherProductClass']],
|
|
'tax_rate_ids' => array_values($higherRates),
|
|
'sort_order' => 1,
|
|
'priority' => 1,
|
|
'calculate_subtotal' => 0,
|
|
],
|
|
]);
|
|
|
|
// For cleanup
|
|
$this->taxRates = array_merge($this->taxRates, $higherRates);
|
|
}
|
|
|
|
/**
|
|
* Helper function that tears down some default rules
|
|
*/
|
|
private function tearDownDefaultRules()
|
|
{
|
|
$this->taxRuleFixtureFactory->deleteTaxRules(array_values($this->taxRules));
|
|
$this->taxRuleFixtureFactory->deleteTaxRates(array_values($this->taxRates));
|
|
$this->taxRuleFixtureFactory->deleteTaxClasses(array_values($this->taxClasses));
|
|
}
|
|
|
|
/**
|
|
* Creates Tax Rule Data Object
|
|
*
|
|
* @return \Magento\Tax\Api\Data\TaxRuleInterface
|
|
*/
|
|
private function createTaxRuleDataObject()
|
|
{
|
|
$taxRule = $this->taxRuleFactory->create();
|
|
$taxRule->setCode('code')
|
|
->setCustomerTaxClassIds([3])
|
|
->setProductTaxClassIds([2])
|
|
->setTaxRateIds([2])
|
|
->setPriority(0)
|
|
->setPosition(1);
|
|
return $taxRule;
|
|
}
|
|
}
|