diff --git a/Block/Adminhtml/Form/Field/TransportColumn.php b/Block/Adminhtml/Form/Field/TransportColumn.php
index c87c310e..c1f68570 100644
--- a/Block/Adminhtml/Form/Field/TransportColumn.php
+++ b/Block/Adminhtml/Form/Field/TransportColumn.php
@@ -25,6 +25,10 @@ class TransportColumn extends Select
* @var DataObjectFactory
*/
protected $dataObjectFactory;
+ /**
+ * @var \Magento\Framework\Message\ManagerInterface
+ */
+ protected $messageManager;
/**
* @var RestDefinitionsInterface
*/
@@ -34,6 +38,7 @@ class TransportColumn extends Select
* @param StoreManagerInterface $storeManager
* @param DataObjectFactory $dataObjectFactory
* @param RestDefinitionsInterface $definitionsService
+ * @param \Magento\Framework\Message\ManagerInterface $messageManager
* @param Config $config
*/
public function __construct(
@@ -41,6 +46,7 @@ public function __construct(
StoreManagerInterface $storeManager,
DataObjectFactory $dataObjectFactory,
RestDefinitionsInterface $definitionsService,
+ \Magento\Framework\Message\ManagerInterface $messageManager,
Config $config,
array $data = []
)
@@ -49,6 +55,7 @@ public function __construct(
$this->storeManager = $storeManager;
$this->dataObjectFactory = $dataObjectFactory;
$this->definitionsService = $definitionsService;
+ $this->messageManager = $messageManager;
$this->config = $config;
}
@@ -101,7 +108,12 @@ private function getSourceOptions(): array
$licenseKey = $this->config->getLicenseKey($storeId, $scopeType, $isProduction);
if(!empty($accountNumber) && !empty($licenseKey))
{
- $validateResult = $this->definitionsService->parameters($isProduction, $storeId);
+ try {
+ $validateResult = $this->definitionsService->parameters($isProduction, $storeId);
+ } catch (\Exception $e) {
+ $this->messageManager->addError($e->getMessage());
+ return [];
+ }
}
$transport = [];
if(!empty($validateResult) && $validateResult->hasValue())
diff --git a/Block/Adminhtml/System/Config/AvaTax.php b/Block/Adminhtml/System/Config/AvaTax.php
new file mode 100644
index 00000000..0e169360
--- /dev/null
+++ b/Block/Adminhtml/System/Config/AvaTax.php
@@ -0,0 +1,111 @@
+getRequest()->getParam('section')) {
+ $params['section'] = $this->getRequest()->getParam('section');
+ }
+ if ($this->getRequest()->getParam('expanded')) {
+ $params['group'] = $this->getRequest()->getParam('expanded');
+ }
+ if ($this->getRequest()->getParam('field')) {
+ $params['field'] = $this->getRequest()->getParam('field');
+ }
+ return json_encode($params);
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public function render(AbstractElement $element)
+ {
+ $params = $this->getConfigSearchParamsJson();
+ $html = parent::render($element);
+ $html .= "";
+
+ return $html;
+ }
+}
diff --git a/Block/Adminhtml/System/Config/ExpandedFieldSet.php b/Block/Adminhtml/System/Config/ExpandedFieldSet.php
new file mode 100644
index 00000000..c8b345bb
--- /dev/null
+++ b/Block/Adminhtml/System/Config/ExpandedFieldSet.php
@@ -0,0 +1,61 @@
+getRequest()->getParam('expanded')) {
+ $expanded = $this->getRequest()->getParam('expanded');
+ }
+ return $expanded;
+ }
+
+ /**
+ * Collapsed or expanded fieldset when page loaded?
+ *
+ * @param AbstractElement $element
+ * @return bool
+ */
+ protected function _isCollapseState($element)
+ {
+ $expanded = $this->getConfigSearchParams();
+ /** To Open Requested Group */
+ if ($element->getId() == $expanded) {
+ return true;
+ }
+ /** To Open Parent of Requested Group */
+ if ($element->getId() == self::PARENT_AVATAX_CONFIGURATION_ID && $expanded != self::PARENT_AVATAX_CONFIGURATION_ID) {
+ return true;
+ }
+ return parent::_isCollapseState($element);
+ }
+}
diff --git a/Block/Adminhtml/System/Config/TaxIncluded.php b/Block/Adminhtml/System/Config/TaxIncluded.php
index 81ab7b30..f9809346 100644
--- a/Block/Adminhtml/System/Config/TaxIncluded.php
+++ b/Block/Adminhtml/System/Config/TaxIncluded.php
@@ -26,36 +26,36 @@ class TaxIncluded extends \Magento\Config\Block\System\Config\Form\Field
*/
protected function _getElementHtml(\Magento\Framework\Data\Form\Element\AbstractElement $element)
{
- if ($element->getValue() != -1) {
- $element->setReadonly(true);
- }
+ $allowedOptions = \ClassyLlama\AvaTax\Model\Config\Source\TaxIncluded::allowedOptions();
+ $jsHtml = '';
+ if (in_array($element->getValue(), $allowedOptions)) {
+ foreach ($allowedOptions as $key => $value) {
+ $jsHtml .= "jQuery('#tax_avatax_configuration_sales_tax_tax_included".$key."').prop('disabled',true); ";
+ }
+ }
$html = $element->getElementHtml();
- $html .= '
';
- $html .= '
'.__('Warning! For tax compliance reasons, once you save the settings for the first time, you won\'t be able to change the Taxation Policy again.').'
';
+
$html .= "";
return $html;
}
diff --git a/Block/Cart/CartTotalsProcessor.php b/Block/Cart/CartTotalsProcessor.php
index 0eb3d53e..0ee34304 100644
--- a/Block/Cart/CartTotalsProcessor.php
+++ b/Block/Cart/CartTotalsProcessor.php
@@ -19,15 +19,33 @@
use Magento\Checkout\Block\Checkout\LayoutProcessorInterface;
use Magento\Store\Model\ScopeInterface;
use ClassyLlama\AvaTax\Helper\Config;
+use Magento\Framework\App\Config\ScopeConfigInterface;
class CartTotalsProcessor extends AbstractTotalsProcessor implements LayoutProcessorInterface
{
+ /**
+ * @var Config
+ */
+ protected $config = null;
+
+ /**
+ * @param ScopeConfigInterface $scopeConfig
+ * @param Config $config
+ */
+ public function __construct(
+ ScopeConfigInterface $scopeConfig,
+ Config $config
+ ) {
+ $this->config = $config;
+ parent::__construct($scopeConfig);
+ }
+
/**
* {@inheritdoc}
*/
public function process($jsLayout)
{
- $taxIncluded = (boolean)$this->scopeConfig->getValue(Config::XML_PATH_AVATAX_TAX_INCLUDED, ScopeInterface::SCOPE_STORES);
+ $taxIncluded = $this->config->getTaxationPolicy(null, ScopeInterface::SCOPE_STORES);
if ($taxIncluded)
$jsLayout['components']['block-totals']['children']['tax']['config']['title'] .= " (".__(Config::XML_SUFFIX_AVATAX_TAX_INCLUDED).")";
return $jsLayout;
diff --git a/Framework/AppInterface.php b/Framework/AppInterface.php
index 7bc437c0..6697962f 100644
--- a/Framework/AppInterface.php
+++ b/Framework/AppInterface.php
@@ -20,7 +20,7 @@ interface AppInterface
/**
* Connector version
*/
- const APP_VERSION = '2.4.1';
+ const APP_VERSION = '2.4.2';
/**
* Avalara APP String
*/
diff --git a/Framework/Interaction/Line.php b/Framework/Interaction/Line.php
index cbc8866c..d1feaa36 100644
--- a/Framework/Interaction/Line.php
+++ b/Framework/Interaction/Line.php
@@ -53,6 +53,13 @@ class Line
*/
protected $metaDataObject = null;
+ /**
+ * Tax calculation model
+ *
+ * @var \Magento\Tax\Model\Calculation
+ */
+ protected $calculationTool;
+
/**
* Description for shipping line
*/
@@ -130,6 +137,7 @@ class Line
* @param MetaDataObjectFactory $metaDataObjectFactory
* @param DataObjectFactory $dataObjectFactory
* @param CustomsConfig $customsConfigHelper
+ * @param \Magento\Tax\Model\Calculation $calculationTool
*/
public function __construct(
Config $config,
@@ -137,7 +145,8 @@ public function __construct(
\ClassyLlama\AvaTax\Model\Logger\AvaTaxLogger $avaTaxLogger,
MetaDataObjectFactory $metaDataObjectFactory,
DataObjectFactory $dataObjectFactory,
- CustomsConfig $customsConfigHelper
+ CustomsConfig $customsConfigHelper,
+ \Magento\Tax\Model\Calculation $calculationTool
) {
$this->config = $config;
$this->taxClassHelper = $taxClassHelper;
@@ -145,6 +154,7 @@ public function __construct(
$this->metaDataObject = $metaDataObjectFactory->create(['metaDataProperties' => $this::$validFields]);
$this->dataObjectFactory = $dataObjectFactory;
$this->customsConfigHelper = $customsConfigHelper;
+ $this->calculationTool = $calculationTool;
}
/**
@@ -310,21 +320,20 @@ protected function convertTaxQuoteDetailsItemToData(\Magento\Tax\Api\Data\QuoteD
$taxCode = $extensionAttributes ? $extensionAttributes->getAvataxTaxCode() : null;
// Calculate tax with or without discount based on config setting
+ $unitPrice = $this->calculationTool->round($item->getUnitPrice());
if ($this->config->getCalculateTaxBeforeDiscount($item->getStoreId())) {
- $amount = $item->getUnitPrice() * $quantity;
+ $amount = $unitPrice * $quantity;
} else {
- $amount = ($item->getUnitPrice() * $quantity) - $item->getDiscountAmount();
+ $discountAmount = $this->calculationTool->round($item->getDiscountAmount());
+ $amount = ($unitPrice * $quantity) - $discountAmount;
}
$ref1 = $extensionAttributes ? $extensionAttributes->getAvataxRef1() : null;
$ref2 = $extensionAttributes ? $extensionAttributes->getAvataxRef2() : null;
$taxIncluded = false;
- if ($taxCode != $this->config->getShippingTaxCode($item->getStoreId()))
- {
- $taxIncluded = $this->config->getTaxationPolicy($item->getStoreId());
- }
-
+ $taxIncluded = $this->config->getTaxationPolicy($item->getStoreId());
+
$data = [
'mage_sequence_no' => $item->getCode(),
'item_code' => $itemCode,
@@ -436,14 +445,17 @@ public function getShippingLine($data, $credit)
$storeId = $data->getStoreId();
$itemCode = $this->config->getSkuShipping($storeId);
+ $taxIncluded = $this->config->getTaxationPolicy($storeId);
$data = [
'mage_sequence_no' => $this->getLineNumber(),
'item_code' => $itemCode,
'tax_code' => $this->taxClassHelper->getAvataxTaxCodeForShipping(),
'description' => self::SHIPPING_LINE_DESCRIPTION,
'quantity' => 1,
+ 'tax_included' => $taxIncluded,
'amount' => $shippingAmount,
];
+
$line = $this->dataObjectFactory->create(['data' => $data]);
try {
@@ -611,9 +623,10 @@ public function getPositiveAdjustmentLine($data) {
// Credit memo amounts need to be sent to AvaTax as negative numbers
$amount *= -1;
-
+
$storeId = $data->getStoreId();
$itemCode = $this->config->getSkuAdjustmentPositive($storeId);
+ $taxIncluded = $this->config->getTaxationPolicy($storeId);
$data = [
'mage_sequence_no' => $this->getLineNumber(),
'item_code' => $itemCode,
@@ -621,8 +634,7 @@ public function getPositiveAdjustmentLine($data) {
'description' => self::ADJUSTMENT_POSITIVE_LINE_DESCRIPTION,
'quantity' => 1,
'amount' => $amount,
- // Since taxes will already be included in this amount, set this flag to true
- 'tax_included' => true
+ 'tax_included' => $taxIncluded
];
$line = $this->dataObjectFactory->create(['data' => $data]);
@@ -655,6 +667,7 @@ public function getNegativeAdjustmentLine($data) {
$storeId = $data->getStoreId();
$itemCode = $this->config->getSkuAdjustmentNegative($storeId);
+ $taxIncluded = $this->config->getTaxationPolicy($storeId);
$data = [
'mage_sequence_no' => $this->getLineNumber(),
'item_code' => $itemCode,
@@ -662,8 +675,7 @@ public function getNegativeAdjustmentLine($data) {
'description' => self::ADJUSTMENT_NEGATIVE_LINE_DESCRIPTION,
'quantity' => 1,
'amount' => $amount,
- // Since taxes will already be included in this amount, set this flag to true
- 'tax_included' => true
+ 'tax_included' => $taxIncluded
];
$line = $this->dataObjectFactory->create(['data' => $data]);
diff --git a/Framework/Interaction/Request/CreditmemoRequestBuilder.php b/Framework/Interaction/Request/CreditmemoRequestBuilder.php
index ae078b5b..59e2a809 100755
--- a/Framework/Interaction/Request/CreditmemoRequestBuilder.php
+++ b/Framework/Interaction/Request/CreditmemoRequestBuilder.php
@@ -237,7 +237,7 @@ public function __construct(
* Creditmemo request builder
*
* @param CreditmemoInterface $creditmemo
- * @return RequestInterface
+ * @return RequestInterface|null
* @throws \Throwable
*/
public function build(CreditmemoInterface $creditmemo): RequestInterface
@@ -348,7 +348,7 @@ private function isProductCalculated(OrderItem $item): bool
*/
private function getDocTypeCreditmemoEstimation(): string
{
- return DocumentType::C_RETURNORDER;
+ return (string) DocumentType::C_RETURNORDER;
}
/**
diff --git a/Framework/Interaction/Rest.php b/Framework/Interaction/Rest.php
index 542a08a9..2fd92997 100644
--- a/Framework/Interaction/Rest.php
+++ b/Framework/Interaction/Rest.php
@@ -195,6 +195,7 @@ protected function handleException($exception, $request = null, $logLevel = LOG_
*
* @param array $response
* @return \Magento\Framework\Phrase
+ * @codeCoverageIgnore
*/
protected function prepareErrorForHandleException(array $response)
{
diff --git a/Framework/Interaction/Rest/Tax.php b/Framework/Interaction/Rest/Tax.php
index 25625213..29a361b9 100644
--- a/Framework/Interaction/Rest/Tax.php
+++ b/Framework/Interaction/Rest/Tax.php
@@ -141,8 +141,8 @@ public function getTax( $request, $isProduction = null, $scopeId = null, $scopeT
'customerCode' => $request->getCustomerCode(),
'dateTime' => $request->getDate(),
]);
- $this->customsConfigHelper->initNextIncrementForWithParameter();
-
+ $this->customsConfigHelper->initNextIncrementForWithParameter();
+
$this->setTransactionDetails($transactionBuilder, $request);
$this->setLineDetails($transactionBuilder, $request);
$logContext['extra']['LineCount'] = $transactionBuilder->getCurrentLineNumber() - 1;
@@ -389,7 +389,7 @@ public function getTaxBatch(
'customerCode' => $request->getCustomerCode(),
'dateTime' => $request->getDate(),
]);
- $this->customsConfigHelper->initNextIncrementForWithParameter();
+ $this->customsConfigHelper->initNextIncrementForWithParameter();
$this->setTransactionDetails($transactionBuilder, $request);
try {
$this->setLineDetails($transactionBuilder, $request);
diff --git a/Framework/Interaction/TaxCalculation.php b/Framework/Interaction/TaxCalculation.php
index 87d0abda..0a63c19a 100644
--- a/Framework/Interaction/TaxCalculation.php
+++ b/Framework/Interaction/TaxCalculation.php
@@ -214,7 +214,7 @@ protected function getTaxDetailsItem(
$scope
)
{
- $price = $item->getUnitPrice();
+ $price = $this->calculationTool->round($item->getUnitPrice());
/* @var $taxLine \Magento\Framework\DataObject */
$taxLine = $getTaxResult->getTaxLine($item->getCode());
@@ -269,8 +269,8 @@ protected function getTaxDetailsItem(
$taxableAmountPercentage = $taxLine->getTaxableAmount() / $totalAmount;
}
}
-
- $effectiveDiscountAmount = $taxableAmountPercentage * $item->getDiscountAmount();
+ $discountAmount = $this->calculationTool->round($item->getDiscountAmount());
+ $effectiveDiscountAmount = $taxableAmountPercentage * $discountAmount;
$taxOnDiscountAmount = $effectiveDiscountAmount * $rate;
$taxOnDiscountAmount = $this->calculationTool->round($taxOnDiscountAmount);
$rowTaxBeforeDiscount = $rowTax + $taxOnDiscountAmount;
@@ -296,7 +296,7 @@ protected function getTaxDetailsItem(
* @see \Magento\Tax\Model\Calculation\AbstractAggregateCalculator::calculateWithTaxInPrice
*/
$discountTaxCompensationAmount = 0;
- $taxIncluded = $this->avaTaxHelper->getTaxationPolicy($scope);
+ $taxIncluded = (boolean) $taxLine->getTaxIncluded();
if ($taxIncluded && $rowTax > 0) {
$discountTaxCompensationAmount = -$rowTax;
}
diff --git a/Helper/Config.php b/Helper/Config.php
index a05c1898..9ead5db1 100644
--- a/Helper/Config.php
+++ b/Helper/Config.php
@@ -1318,16 +1318,23 @@ public function getConfigData($configPath, $store = null)
* Get Taxation Policy
*
* @param null $store
+ * @param string $scope
* @return boolean
*/
- public function getTaxationPolicy($store = null)
+ public function getTaxationPolicy($store = null, $scope = ScopeInterface::SCOPE_STORE)
{
- return (boolean)$this->scopeConfig->getValue(
+ $configuredValue = $this->scopeConfig->getValue(
self::XML_PATH_AVATAX_TAX_INCLUDED,
- ScopeInterface::SCOPE_STORE,
+ $scope,
$store
);
+ $allowedOptions = \ClassyLlama\AvaTax\Model\Config\Source\TaxIncluded::allowedOptions();
+ if (!in_array($configuredValue, $allowedOptions)) {
+ $configuredValue = \ClassyLlama\AvaTax\Model\Config\Source\TaxIncluded::DEFAULT_POLICY;
+ }
+ return (boolean)$configuredValue;
}
+
/**
* Get VAT Transport
*
diff --git a/Helper/CustomsConfig.php b/Helper/CustomsConfig.php
index 0d70e927..3b55318c 100644
--- a/Helper/CustomsConfig.php
+++ b/Helper/CustomsConfig.php
@@ -262,7 +262,7 @@ public function getShippingTypeForMethod($method, $scopeId = null, $scopeType =
// Return default method
return $this->getDefaultShippingType($scopeId, $scopeType);
}
-
+
/**
* Init parameters next increment for each new transaction
*
diff --git a/Model/Config/Source/TaxIncluded.php b/Model/Config/Source/TaxIncluded.php
index bc019fdd..36e4295b 100644
--- a/Model/Config/Source/TaxIncluded.php
+++ b/Model/Config/Source/TaxIncluded.php
@@ -19,7 +19,20 @@ class TaxIncluded implements \Magento\Framework\Data\OptionSourceInterface
{
const NET = 0;
const GROSS = 1;
+
+ const DEFAULT_POLICY = self::NET;
+ /**
+ * @return array
+ */
+ public static function allowedOptions()
+ {
+ return [
+ self::NET,
+ self::GROSS
+ ];
+ }
+
/**
* @return array
*/
diff --git a/Plugin/Model/ResourceModel/ExtensionAttributesPersistencePlugin.php b/Plugin/Model/ResourceModel/ExtensionAttributesPersistencePlugin.php
index a8bc7524..3d2a13c2 100644
--- a/Plugin/Model/ResourceModel/ExtensionAttributesPersistencePlugin.php
+++ b/Plugin/Model/ResourceModel/ExtensionAttributesPersistencePlugin.php
@@ -97,7 +97,7 @@ function ($extensionAttributeCode) use ($extensibleEntityName) {
return in_array(
$extensionAttributeCode,
$this->config->getConfigDataArray(
- "tax/avatax_advanced/attribute_codes/$extensibleEntityName")
+ "tax/avatax_advanced_attribute_codes/$extensibleEntityName")
);
},
ARRAY_FILTER_USE_KEY
diff --git a/Setup/Patch/Data/MoveAllowedAttributesConfigToNewConfigPath.php b/Setup/Patch/Data/MoveAllowedAttributesConfigToNewConfigPath.php
new file mode 100644
index 00000000..dbc21d9e
--- /dev/null
+++ b/Setup/Patch/Data/MoveAllowedAttributesConfigToNewConfigPath.php
@@ -0,0 +1,79 @@
+moduleDataSetup = $moduleDataSetup;
+ }
+
+ /**
+ * @inheritdoc
+ */
+ public function apply()
+ {
+ $this->moduleDataSetup->getConnection()->startSetup();
+ $connection = $this->moduleDataSetup->getConnection();
+ $table = $this->moduleDataSetup->getTable('core_config_data');
+ $pathField = $connection->quoteIdentifier('path');
+ $oldConfigPath = $connection->quote("tax/avatax_advanced/attribute_codes/");
+ $newConfigPath = $connection->quote("tax/avatax_advanced_attribute_codes/");
+ $connection->update(
+ $table,
+ [
+ 'path' => new \Zend_Db_Expr(
+ 'REPLACE(' . $pathField . ',' . $oldConfigPath . ', ' . $newConfigPath . ')'
+ )
+ ],
+ [$pathField . ' LIKE ?' => 'tax/avatax_advanced/attribute_codes/%']
+ );
+ $this->moduleDataSetup->getConnection()->endSetup();
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public static function getDependencies()
+ {
+ return [];
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public static function getVersion()
+ {
+ return '2.2.4.2';
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getAliases()
+ {
+ return [];
+ }
+}
diff --git a/System_Integration_Document.pdf b/System_Integration_Document.pdf
index 37f4f4c0..5616d4bc 100644
Binary files a/System_Integration_Document.pdf and b/System_Integration_Document.pdf differ
diff --git a/Test/Integration/Framework/Interaction/Request/AddressBuilderTest.php b/Test/Integration/Framework/Interaction/Request/AddressBuilderTest.php
deleted file mode 100644
index 0cd629e7..00000000
--- a/Test/Integration/Framework/Interaction/Request/AddressBuilderTest.php
+++ /dev/null
@@ -1,78 +0,0 @@
-objectManager = Bootstrap::getObjectManager();
- $this->avaTaxHelperRestConfig = $this->objectManager->create(AvaTaxHelperRestConfig::class);
- }
-
- /**
- * - order rollback
- * - create simple product
- * - create order item
- * - create order
- */
- public static function loadFixture()
- {
- include __DIR__ . '/../../../_files/order.php';
- }
-
- /**
- * @test
- * @covers \ClassyLlama\AvaTax\Framework\Interaction\Request\AddressBuilder::build
- * @magentoAppIsolation enabled
- * @magentoDbIsolation enabled
- * @magentoDataFixture loadFixture
- */
- public function checkAddressBuilderReturnsCorrectData()
- {
- /** @var Order $order */
- $order = $this->objectManager->create(Order::class);
- $order->loadByIncrementId('123456789');
-
- /** @var AddressBuilder $addressBuilder */
- $addressBuilder = $this->objectManager->create(AddressBuilder::class);
- $storeId = (int)$this->objectManager->get(StoreManagerInterface::class)->getStore()->getId();
-
- /** @var array $result */
- $result = $addressBuilder->build($order, $storeId);
-
- /** @var string $shipTo */
- $shipTo = $this->avaTaxHelperRestConfig->getAddrTypeTo();
-
- self::assertEquals('street', $result[$shipTo]->getData('line_1'));
- self::assertEquals('Los Angeles', $result[$shipTo]->getData('city'));
- self::assertEquals('123-456', $result[$shipTo]->getData('postal_code'));
- }
-}
diff --git a/Test/Integration/Framework/Interaction/Request/LineBuilderTest.php b/Test/Integration/Framework/Interaction/Request/LineBuilderTest.php
deleted file mode 100644
index 39e5d866..00000000
--- a/Test/Integration/Framework/Interaction/Request/LineBuilderTest.php
+++ /dev/null
@@ -1,97 +0,0 @@
-objectManager = Bootstrap::getObjectManager();
- $this->creditmemoRepository = $this->objectManager->get(CreditmemoRepositoryInterface::class);
- }
-
- /**
- * - order rollback
- * - create simple product
- * - create order item
- * - create order
- * - create creditmemo
- */
- public static function loadFixture()
- {
- include __DIR__ . '/../../../_files/creditmemo.php';
- }
-
- /**
- * @test
- * @covers \ClassyLlama\AvaTax\Framework\Interaction\Request\LineBuilder::build
- * @magentoAppIsolation enabled
- * @magentoDbIsolation enabled
- * @magentoDataFixture loadFixture
- */
- public function checkLineBuilderReturnsCorrectData()
- {
- /** @var Order $order */
- $order = $this->objectManager->create(Order::class);
- $order->loadByIncrementId('123456789');
-
- $orderItems = [];
- foreach ($order->getItems() as $orderItem) {
- $orderItems[$orderItem->getProductId()] = $orderItem;
- }
-
- /** @var SearchCriteriaBuilder $searchCriteriaBuilder */
- $searchCriteriaBuilder = $this->objectManager->create(SearchCriteriaBuilder::class);
- /** @var FilterBuilder $filterBuilder */
- $filterBuilder = $this->objectManager->create(FilterBuilder::class);
- $searchCriteriaBuilder->addFilters([
- $filterBuilder->setField('increment_id')
- ->setValue('100000001')
- ->create()
- ]);
- /** @var Creditmemo $creditmemo */
- $creditmemo = current($this->creditmemoRepository->getList($searchCriteriaBuilder->create())->getItems());
- /** @var LineBuilder $lineBuilder */
- $lineBuilder = $this->objectManager->get(LineBuilder::class);
-
- /** @var array $result */
- $lines = $lineBuilder->build($creditmemo, $orderItems);
-
- self::assertCount(3, $lines);
- self::assertSame('Simple Product', current($lines)->getData('description'));
- self::assertSame(100.0, current($lines)->getData('quantity'));
- self::assertSame('Adjustment refund', next($lines)->getData('description'));
- self::assertSame(-5.0, current($lines)->getData('amount'));
- self::assertSame('Adjustment fee', next($lines)->getData('description'));
- self::assertSame(10.0, current($lines)->getData('amount'));
- }
-}
diff --git a/Test/Integration/Helper/CustomsConfigTest.php b/Test/Integration/Helper/CustomsConfigTest.php
deleted file mode 100755
index f397f6d6..00000000
--- a/Test/Integration/Helper/CustomsConfigTest.php
+++ /dev/null
@@ -1,82 +0,0 @@
-objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager();
- $this->customsHelper = $this->objectManager->get(CustomsConfigHelper::class);
- }
-
- /**
- * @magentoConfigFixture current_store tax/avatax_customs/enabled 1
- * @magentoConfigFixture current_store tax/avatax/enabled 1
- */
- public function testEnabled_enabledReturnsTrue()
- {
- $result = $this->customsHelper->enabled();
- $this->assertTrue($result);
- }
-
- /**
- * @magentoConfigFixture current_store tax/avatax_customs/enabled 0
- * @magentoConfigFixture current_store tax/avatax/enabled 1
- */
- public function testEnabled_disabledReturnsFalse()
- {
- $result = $this->customsHelper->enabled();
- $this->assertFalse($result);
- }
-
- /**
- * @magentoConfigFixture current_store tax/avatax_customs/enabled 1
- * @magentoConfigFixture current_store tax/avatax/enabled 0
- */
- public function testEnabled_avaTaxDisabledReturnsFalse()
- {
- $result = $this->customsHelper->enabled();
- $this->assertFalse($result);
- }
-
- /**
- * @magentoConfigFixture default_store tax/avatax_customs/enabled 1
- * @magentoConfigFixture current_store tax/avatax/enabled 1
- * @magentoConfigFixture current_store tax/avatax_customs/enabled 0
- */
- public function testEnabled_storeOverridesDefault()
- {
- $result = $this->customsHelper->enabled();
- $this->assertFalse($result);
- }
-}
diff --git a/Test/Integration/Model/Tax/Sales/Total/Quote/SetupUtil.php b/Test/Integration/Model/Tax/Sales/Total/Quote/SetupUtil.php
deleted file mode 100755
index 5a8541ca..00000000
--- a/Test/Integration/Model/Tax/Sales/Total/Quote/SetupUtil.php
+++ /dev/null
@@ -1,1183 +0,0 @@
- '0',
- Config::CONFIG_XML_PATH_PRICE_INCLUDES_TAX => 0, //Excluding tax
- Config::CONFIG_XML_PATH_SHIPPING_INCLUDES_TAX => 0, //Excluding tax
- Config::CONFIG_XML_PATH_BASED_ON => 'shipping', // or 'billing'
- Config::CONFIG_XML_PATH_APPLY_ON => '0',
- Config::CONFIG_XML_PATH_APPLY_AFTER_DISCOUNT => '0',
- Config::CONFIG_XML_PATH_DISCOUNT_TAX => '0',
- Config::XML_PATH_ALGORITHM => Calculation::CALC_TOTAL_BASE,
- ];
-
- const TAX_RATE_MI = 'tax_rate_mi';
- const TAX_RATE_SHIPPING = 'tax_rate_shipping';
- const TAX_STORE_RATE = 'tax_store_rate';
- const COUNTRY_US = 'US';
-
- /**#@+
- * Values for default address and taxing jurisdiction (6% flat state tax)
- */
- const REGION_MI = '33';
- const MI_POST_CODE = '48933';
- const MI_CITY = 'Lansing';
- const MI_STREET_1 = '100 N Capitol Ave'; // Michigan state capitol
- const AVATAX_MI_RATE_DESCRIPTION = 'MI STATE TAX';
- const AVATAX_MI_RATE_JURISCODE = 26;
- /**#@-*/
-
- /**#@+
- * Values for optional address and taxing jurisdiction (8% combined tax)
- */
- const REGION_CA = '12';
- const SAN_DIEGO_POST_CODE = '92101';
- const SAN_DIEGO_CITY = 'San Diego';
- const SAN_DIEGO_STREET_1 = '2920 Zoo Dr'; // San Diego Zoo
- const AVATAX_CA_RATE_DESCRIPTION = 'CA STATE TAX';
- const AVATAX_CA_RATE_JURISCODE = '06';
- const AVATAX_CA_COUNTY_RATE_DESCRIPTION = 'CA COUNTY TAX';
- const AVATAX_CA_COUNTY_RATE_JURISCODE = '037';
- const AVATAX_CA_SAN_DIEGO_SPECIAL_RATE_DESCRIPTION = 'CA SPECIAL TAX';
- const AVATAX_CA_SAN_DIEGO_SPECIAL_RATE_JURISCODE = 'EMBD0';
- /**#@-*/
-
- /**
- * Tax rates
- *
- * @var array
- */
- protected $taxRates = [
- self::TAX_RATE_SHIPPING => [
- 'data' => [
- 'tax_country_id' => self::COUNTRY_US,
- 'tax_region_id' => '*',
- 'tax_postcode' => '*',
- 'code' => self::TAX_RATE_SHIPPING,
- 'rate' => '7.5',
- ],
- 'id' => null,
- ],
- self::TAX_STORE_RATE => [
- 'data' => [
- 'tax_country_id' => self::COUNTRY_US,
- 'tax_region_id' => self::REGION_CA,
- 'tax_postcode' => '*',
- 'code' => self::TAX_STORE_RATE,
- 'rate' => '8',
- ],
- 'id' => null,
- ],
- self::TAX_RATE_MI => [
- 'data' => [
- 'tax_country_id' => self::COUNTRY_US,
- 'tax_region_id' => self::REGION_MI,
- 'tax_postcode' => '*',
- 'code' => self::TAX_RATE_MI,
- 'rate' => '6',
- ],
- 'id' => null,
- ],
- ];
-
- const PRODUCT_TAX_CLASS_1 = 'product_tax_class_1';
- const PRODUCT_TAX_CLASS_2 = 'product_tax_class_2';
- const PRODUCT_TAX_CLASS_3_DIGITAL_GOODS = 'product_tax_class_3_digital_goods';
- const SHIPPING_TAX_CLASS = 'shipping_tax_class';
-
- /**
- * List of product tax class that will be created.
- *
- * The ID of the created tax classes will be stored as the values for each of the keys
- *
- * @var array
- */
- protected $productTaxClasses = [
- self::PRODUCT_TAX_CLASS_1 => null,
- self::PRODUCT_TAX_CLASS_2 => null,
- // This tax class is for digital goods
- self::PRODUCT_TAX_CLASS_3_DIGITAL_GOODS => null,
- self::SHIPPING_TAX_CLASS => null,
- ];
-
- /**
- * Information to use when creating tax classes listed above
- *
- * @var array
- */
- protected $productTaxClassesCreationData = [
- self::PRODUCT_TAX_CLASS_1 => ['avatax_code' => ''],
- self::PRODUCT_TAX_CLASS_2 => ['avatax_code' => ''],
- self::PRODUCT_TAX_CLASS_3_DIGITAL_GOODS => ['avatax_code' => 'D0000000'],
- self::SHIPPING_TAX_CLASS => null,
- ];
-
- const CUSTOMER_TAX_CLASS_1 = 'customer_tax_class_1';
- const CUSTOMER_TAX_CLASS_2_NON_PROFIT = 'customer_tax_class_2_non_profit';
- const CUSTOMER_PASSWORD = 'password';
-
- /**
- * List of customer tax class to be created
- *
- * The ID of the created tax classes will be stored as the values for each of the keys
- *
- * @var array
- */
- protected $customerTaxClasses = [
- self::CUSTOMER_TAX_CLASS_1 => null,
- self::CUSTOMER_TAX_CLASS_2_NON_PROFIT => null,
- ];
-
- /**
- * Information to use when creating tax classes listed above
- *
- * @var array
- */
- protected $customerTaxClassesCreationData = [
- self::CUSTOMER_TAX_CLASS_1 => ['avatax_code' => ''],
- /**
- * "E" is the code for a Charitable Organization.
- * @see \ClassyLlama\AvaTax\Model\Config\Source\AvaTaxCustomerUsageType::toOptionArray
- */
- self::CUSTOMER_TAX_CLASS_2_NON_PROFIT => ['avatax_code' => 'E'],
- ];
-
- /**
- * List of tax rules
- *
- * @var array
- */
- protected $taxRules = [];
-
- const CONFIG_OVERRIDES = 'config_overrides';
- const TAX_RATE_OVERRIDES = 'tax_rate_overrides';
- const TAX_RULE_OVERRIDES = 'tax_rule_overrides';
-
- /**
- * Default data for shopping cart rule
- *
- * @var array
- */
- protected $defaultShoppingCartPriceRule = [
- 'name' => 'Shopping Cart Rule',
- 'is_active' => 1,
- 'customer_group_ids' => [\Magento\Customer\Model\GroupManagement::CUST_GROUP_ALL],
- 'coupon_type' => \Magento\SalesRule\Model\Rule::COUPON_TYPE_NO_COUPON,
- 'simple_action' => 'by_percent',
- 'discount_amount' => 40,
- 'stop_rules_processing' => 1,
- 'website_ids' => [1],
- ];
-
- /**
- * Name to be used for configurable attribute
- */
- const CONFIGURABLE_ATTRIBUTE_NAME = 'config_attribute';
-
- /**
- * Storage for customer so that it can be reused by this test
- * @see \ClassyLlama\AvaTax\Tests\Integration\Model\Tax\Sales\Total\Quote\TaxTest::testNativeVsMagentoTaxCalculation
- *
- * @var null
- */
- protected $customer = null;
-
- /**
- * Storage for configurable attributes so they can be retrieved after being created
- *
- * @var array
- */
- protected $configurableAttributes = [];
-
- /**
- * Object manager
- *
- * @var \Magento\Framework\ObjectManagerInterface
- */
- public $objectManager;
-
- /**
- * @var \Magento\Customer\Api\CustomerRepositoryInterface
- */
- protected $customerRepository;
-
- /**
- * @var \Magento\Catalog\Api\ProductRepositoryInterface $productRepository
- */
- protected $productRepository;
-
- /**
- * @var \Magento\Customer\Api\AccountManagementInterface
- */
- protected $accountManagement;
-
- /**
- * @param \Magento\Framework\ObjectManagerInterface $objectManager
- */
- public function __construct($objectManager)
- {
- $this->objectManager = $objectManager;
- $this->customerRepository = $this->objectManager->create('Magento\Customer\Api\CustomerRepositoryInterface');
- $this->productRepository = $this->objectManager->create('Magento\Catalog\Api\ProductRepositoryInterface');
- $this->accountManagement = $this->objectManager->create('Magento\Customer\Api\AccountManagementInterface');
- }
-
- /**
- * Create customer tax classes
- *
- * @return $this
- */
- protected function createCustomerTaxClass()
- {
- foreach (array_keys($this->customerTaxClasses) as $className) {
- $extraData = [];
- if (isset($this->customerTaxClassesCreationData[$className])) {
- $extraData = $this->customerTaxClassesCreationData[$className];
- }
- $this->customerTaxClasses[$className] = $this->objectManager->create('Magento\Tax\Model\ClassModel')
- ->setData($extraData)
- ->setClassName($className)
- ->setClassType(\Magento\Tax\Model\ClassModel::TAX_CLASS_TYPE_CUSTOMER)
- ->save()
- ->getId();
- }
-
- return $this;
- }
-
- /**
- * Create product tax classes
- *
- * @return $this
- */
- protected function createProductTaxClass()
- {
- foreach (array_keys($this->productTaxClasses) as $className) {
- $extraData = [];
- if (isset($this->productTaxClassesCreationData[$className])) {
- $extraData = $this->productTaxClassesCreationData[$className];
- }
- $this->productTaxClasses[$className] = $this->objectManager->create('Magento\Tax\Model\ClassModel')
- ->setData($extraData)
- ->setClassName($className)
- ->setClassType(\Magento\Tax\Model\ClassModel::TAX_CLASS_TYPE_PRODUCT)
- ->save()
- ->getId();
- }
-
- return $this;
- }
-
- /**
- * Set the configuration.
- *
- * @param array $configData
- * @return $this
- */
- public function setConfig($configData)
- {
- /** @var \Magento\Config\Model\ResourceModel\Config $config */
- $config = $this->objectManager->get('Magento\Config\Model\ResourceModel\Config');
- foreach ($configData as $path => $value) {
- if ($path == Config::CONFIG_XML_PATH_SHIPPING_TAX_CLASS) {
- $value = $this->productTaxClasses[$value];
- }
- $config->saveConfig(
- $path,
- $value,
- ScopeConfigInterface::SCOPE_TYPE_DEFAULT,
- 0
- );
- }
-
- /** @var \Magento\Framework\App\Config\ReinitableConfigInterface $config */
- $config = $this->objectManager->get('Magento\Framework\App\Config\ReinitableConfigInterface');
- $config->reinit();
-
- return $this;
- }
-
- /**
- * Create tax rates
- *
- * @param array $overrides
- * @return $this
- */
- protected function createTaxRates($overrides)
- {
- $taxRateOverrides = empty($overrides[self::TAX_RATE_OVERRIDES]) ? [] : $overrides[self::TAX_RATE_OVERRIDES];
- foreach (array_keys($this->taxRates) as $taxRateCode) {
- if (isset($taxRateOverrides[$taxRateCode])) {
- $this->taxRates[$taxRateCode]['data']['rate'] = $taxRateOverrides[$taxRateCode];
- }
- $this->taxRates[$taxRateCode]['id'] = $this->objectManager->create('Magento\Tax\Model\Calculation\Rate')
- ->setData($this->taxRates[$taxRateCode]['data'])
- ->save()
- ->getId();
- }
- return $this;
- }
-
- /**
- * Convert the code to id for productTaxClass, customerTaxClass and taxRate in taxRuleOverrideData
- *
- * @param array $taxRuleOverrideData
- * @param array $taxRateIds
- * @return array
- */
- protected function processTaxRuleOverrides($taxRuleOverrideData, $taxRateIds)
- {
- if (!empty($taxRuleOverrideData['customer_tax_class_ids'])) {
- $customerTaxClassIds = [];
- foreach ($taxRuleOverrideData['customer_tax_class_ids'] as $customerClassCode) {
- $customerTaxClassIds[] = $this->customerTaxClasses[$customerClassCode];
- }
- $taxRuleOverrideData['customer_tax_class_ids'] = $customerTaxClassIds;
- }
- if (!empty($taxRuleOverrideData['product_tax_class_ids'])) {
- $productTaxClassIds = [];
- foreach ($taxRuleOverrideData['product_tax_class_ids'] as $productClassCode) {
- $productTaxClassIds[] = $this->productTaxClasses[$productClassCode];
- }
- $taxRuleOverrideData['product_tax_class_ids'] = $productTaxClassIds;
- }
- if (!empty($taxRuleOverrideData['tax_rate_ids'])) {
- $taxRateIdsForRule = [];
- foreach ($taxRuleOverrideData['tax_rate_ids'] as $taxRateCode) {
- $taxRateIdsForRule[] = $taxRateIds[$taxRateCode];
- }
- $taxRuleOverrideData['tax_rate_ids'] = $taxRateIdsForRule;
- }
-
- return $taxRuleOverrideData;
- }
-
- /**
- * Return a list of product tax class ids NOT including shipping product tax class
- *
- * @return array
- */
- protected function getProductTaxClassIds()
- {
- $productTaxClassIds = [];
- foreach ($this->productTaxClasses as $productTaxClassName => $productTaxClassId) {
- if ($productTaxClassName != self::SHIPPING_TAX_CLASS) {
- $productTaxClassIds[] = $productTaxClassId;
- }
- }
-
- return $productTaxClassIds;
- }
-
- /**
- * Return a list of tax rate ids NOT including shipping tax rate
- *
- * @return array
- */
- protected function getDefaultTaxRateIds()
- {
- $taxRateIds = [
- $this->taxRates[self::TAX_RATE_MI]['id'],
- $this->taxRates[self::TAX_STORE_RATE]['id'],
- ];
-
- return $taxRateIds;
- }
-
- /**
- * Return the default customer group tax class id
- *
- * @return int
- */
- public function getDefaultCustomerTaxClassId()
- {
- /** @var \Magento\Customer\Api\GroupManagementInterface $groupManagement */
- $groupManagement = $this->objectManager->get('Magento\Customer\Api\GroupManagementInterface');
- $defaultGroup = $groupManagement->getDefaultGroup();
- return $defaultGroup->getTaxClassId();
- }
-
- /**
- * Create tax rules
- *
- * @param array $overrides
- * @return $this
- */
- protected function createTaxRules($overrides)
- {
- $taxRateIds = [];
- foreach ($this->taxRates as $taxRateCode => $taxRate) {
- $taxRateIds[$taxRateCode] = $taxRate['id'];
- }
-
- //The default customer tax class id is used to calculate store tax rate
- $customerClassIds = [
- $this->customerTaxClasses[self::CUSTOMER_TAX_CLASS_1],
- $this->getDefaultCustomerTaxClassId()
- ];
-
- //By default create tax rule that covers all product tax classes except SHIPPING_TAX_CLASS
- //The tax rule will cover all tax rates except TAX_RATE_SHIPPING
- $taxRuleDefaultData = [
- 'code' => 'Test Rule',
- 'priority' => '0',
- 'position' => '0',
- 'customer_tax_class_ids' => $customerClassIds,
- 'product_tax_class_ids' => $this->getProductTaxClassIds(),
- 'tax_rate_ids' => $this->getDefaultTaxRateIds(),
- ];
-
- //Create tax rules
- if (empty($overrides[self::TAX_RULE_OVERRIDES])) {
- //Create separate shipping tax rule
- $shippingTaxRuleData = [
- 'code' => 'Shipping Tax Rule',
- 'priority' => '0',
- 'position' => '0',
- 'customer_tax_class_ids' => $customerClassIds,
- 'product_tax_class_ids' => [$this->productTaxClasses[self::SHIPPING_TAX_CLASS]],
- 'tax_rate_ids' => [$this->taxRates[self::TAX_RATE_SHIPPING]['id']],
- ];
- $this->taxRules[$shippingTaxRuleData['code']] = $this->objectManager
- ->create('Magento\Tax\Model\Calculation\Rule')
- ->setData($shippingTaxRuleData)
- ->save()
- ->getId();
-
- //Create a default tax rule
- $this->taxRules[$taxRuleDefaultData['code']] = $this->objectManager
- ->create('Magento\Tax\Model\Calculation\Rule')
- ->setData($taxRuleDefaultData)
- ->save()
- ->getId();
- } else {
- foreach ($overrides[self::TAX_RULE_OVERRIDES] as $taxRuleOverrideData ) {
- //convert code to id for productTaxClass, customerTaxClass and taxRate
- $taxRuleOverrideData = $this->processTaxRuleOverrides($taxRuleOverrideData, $taxRateIds);
- $mergedTaxRuleData = array_merge($taxRuleDefaultData, $taxRuleOverrideData);
- $this->taxRules[$mergedTaxRuleData['code']] = $this->objectManager
- ->create('Magento\Tax\Model\Calculation\Rule')
- ->setData($mergedTaxRuleData)
- ->save()
- ->getId();
- }
- }
-
- return $this;
- }
-
- /**
- * Set up tax classes, tax rates and tax rules
- * The override structure:
- * override['self::CONFIG_OVERRIDES']
- * [
- * [config_path => config_value]
- * ]
- * override['self::TAX_RATE_OVERRIDES']
- * [
- * ['tax_rate_code' => tax_rate]
- * ]
- * override['self::TAX_RULE_OVERRIDES']
- * [
- * [
- * 'code' => code //Required, has to be unique
- * 'priority' => 0
- * 'position' => 0
- * 'tax_customer_class' => array of customer tax class names as defined in this class
- * 'tax_product_class' => array of product tax class names as defined in this class
- * 'tax_rate' => array of tax rate codes as defined in this class
- * ]
- * ]
- *
- * @param array $overrides
- * @return void
- */
- public function setupTax($overrides)
- {
- //Create product tax classes
- $this->createProductTaxClass();
-
- //Create customer tax classes
- $this->createCustomerTaxClass();
-
- //Create tax rates
- $this->createTaxRates($overrides);
-
- //Create tax rules
- $this->createTaxRules($overrides);
-
- //Tax calculation configuration
- if (!empty($overrides[self::CONFIG_OVERRIDES])) {
- $this->setConfig($overrides[self::CONFIG_OVERRIDES]);
- }
- }
-
- /**
- * Create a simple product with given sku, price and tax class
- *
- * @param string $sku
- * @param float $price
- * @param int $taxClassId
- * @param array|null $additionalAttributes
- * @return \Magento\Catalog\Model\Product
- */
- public function createSimpleProduct($sku, $price, $taxClassId, $additionalAttributes = [])
- {
- /** @var \Magento\Catalog\Model\Product $product */
- if ($this->loadProductBySku($sku)) {
- $product = $this->loadProductBySku($sku);
- } else {
- /** @var $product \Magento\Catalog\Model\Product */
- $product = $this->objectManager->create('Magento\Catalog\Model\Product');
- $product->isObjectNew(true);
- }
-
- $product->setTypeId('simple')
- ->setAttributeSetId(4)
- ->setWebsiteIds([1])
- ->setName('Simple Product' . $sku)
- ->setSku($sku)
- ->setPrice($price)
- ->setTaxClassId($taxClassId)
- ->setStockData(
- [
- 'use_config_manage_stock' => 1,
- 'qty' => 100,
- 'is_qty_decimal' => 0,
- 'is_in_stock' => 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);
-
- foreach ($additionalAttributes as $key => $value) {
- $product->setData($key, $value);
- }
-
- $product->save();
-
- $product = $product->load($product->getId());
- $this->products[$sku] = $product;
- return $product;
- }
-
- /**
- * Create configurable product and children
- *
- * This file was inspired by
- * @see dev/tests/integration/testsuite/Magento/ConfigurableProduct/_files/product_configurable.php
- *
- * @param $sku
- * @param $price
- * @param $taxClassId
- * @param $itemData
- * @return \Magento\Catalog\Model\Product
- */
- protected function createConfigurableProduct($sku, $price, $taxClassId, $itemData)
- {
- $options = $itemData['options'];
-
- $attribute = $this->createConfigurableAttribute(self::CONFIGURABLE_ATTRIBUTE_NAME, $options);
-
- /* Create simple products per each option value*/
- /** @var \Magento\Eav\Api\Data\AttributeOptionInterface[] $options */
- $options = $attribute->getOptions();
- array_shift($options); //remove the first option which is empty
-
- $associatedProductIds = [];
- $attributeValues = [];
- $i = 1;
- foreach ($options as $option) {
- $taxClassName = self::PRODUCT_TAX_CLASS_1;
- $taxClassId = $this->productTaxClasses[$taxClassName];
- $childSku = $sku . '_child' . $i++;
- $additionalAttributes = [
- self::CONFIGURABLE_ATTRIBUTE_NAME => $option->getValue(),
- ];
-
- $attributeValues[] = [
- 'label' => 'test',
- 'attribute_id' => $attribute->getId(),
- 'value_index' => $option->getValue(),
- ];
-
- $associatedProductIds[] = $this->createSimpleProduct($childSku, $price, $taxClassId, $additionalAttributes)->getId();
- }
-
- if ($this->loadProductBySku($sku)) {
- $product = $this->loadProductBySku($sku);
- } else {
- /** @var $product \Magento\Catalog\Model\Product */
- $product = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create('Magento\Catalog\Model\Product');
- }
-
- $product->setTypeId(\Magento\ConfigurableProduct\Model\Product\Type\Configurable::TYPE_CODE)
- ->setAttributeSetId(4)
- ->setWebsiteIds([1])
- ->setName('Configurable Product')
- ->setSku($sku)
- ->setTaxClassId($taxClassId)
- ->setVisibility(\Magento\Catalog\Model\Product\Visibility::VISIBILITY_BOTH)
- ->setStatus(\Magento\Catalog\Model\Product\Attribute\Source\Status::STATUS_ENABLED)
- ->setStockData(['use_config_manage_stock' => 1, 'is_in_stock' => 1])
- ->setAssociatedProductIds($associatedProductIds)
- ->setConfigurableAttributesData(
- [
- [
- 'attribute_id' => $attribute->getId(),
- 'attribute_code' => $attribute->getAttributeCode(),
- 'frontend_label' => 'test',
- 'values' => $attributeValues,
- ],
- ]
- )
- ->save();
-
- $this->products[$sku] = $product;
-
- return $product;
- }
-
- /**
- * Get configurable attribute created earlier
- *
- * @param $attributeName
- * @return bool|\Magento\Catalog\Model\ResourceModel\Eav\Attribute
- */
- protected function getConfigurableAttribute($attributeName)
- {
- if (isset($this->configurableAttributes[$attributeName])) {
- return $this->configurableAttributes[$attributeName];
- }
- return false;
- }
-
- /**
- * Create configurable attribute
- *
- * @see dev/tests/integration/testsuite/Magento/ConfigurableProduct/_files/configurable_attribute.php
- *
- * @param $attributeName
- * @param array $options
- * @return \Magento\Catalog\Model\ResourceModel\Eav\Attribute
- * @throws \Magento\Framework\Exception\LocalizedException
- */
- protected function createConfigurableAttribute($attributeName, $options)
- {
- if (isset($this->configurableAttributes[$attributeName])) {
- return $this->configurableAttributes[$attributeName];
- }
-
- $eavConfig = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get('Magento\Eav\Model\Config');
- $attribute = $eavConfig->getAttribute('catalog_product', $attributeName);
- if ($attribute instanceof \Magento\Eav\Model\Entity\Attribute\AbstractAttribute
- && $attribute->getId()
- ) {
- $attribute->delete();
- }
- $eavConfig->clear();
- /* Create attribute */
- /** @var $installer \Magento\Catalog\Setup\CategorySetup */
- $installer = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create('Magento\Catalog\Setup\CategorySetup');
-
- /** @var $attribute \Magento\Catalog\Model\ResourceModel\Eav\Attribute */
- $attribute = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create(
- 'Magento\Catalog\Model\ResourceModel\Eav\Attribute'
- );
- $attribute->setData(
- [
- 'attribute_code' => $attributeName,
- 'entity_type_id' => $installer->getEntityTypeId('catalog_product'),
- 'is_global' => 1,
- 'is_user_defined' => 1,
- 'frontend_input' => 'select',
- 'is_unique' => 0,
- 'is_required' => 1,
- 'is_searchable' => 0,
- 'is_visible_in_advanced_search' => 0,
- 'is_comparable' => 0,
- 'is_filterable' => 0,
- 'is_filterable_in_search' => 0,
- 'is_used_for_promo_rules' => 0,
- 'is_html_allowed_on_front' => 1,
- 'is_visible_on_front' => 0,
- 'used_in_product_listing' => 0,
- 'used_for_sort_by' => 0,
- 'frontend_label' => ['Test Configurable'],
- 'backend_type' => 'int',
- 'option' => $options,
- ]
- );
- $attribute->save();
-
- /* Assign attribute to attribute set */
- $installer->addAttributeToGroup('catalog_product', 'Default', 'General', $attribute->getId());
-
- /** @var \Magento\Eav\Model\Config $eavConfig */
- $eavConfig = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get('Magento\Eav\Model\Config');
- $eavConfig->clear();
-
- $this->configurableAttributes[$attributeName] = $attribute;
-
- return $attribute;
- }
-
- /**
- * Create bundled product and children
- *
- * This file was inspired by
- * @see dev/tests/integration/testsuite/Magento/Bundle/_files/product_with_multiple_options.php
- *
- * @param $sku
- * @param $price
- * @param $taxClassId
- * @param $itemData
- * @return \Magento\Catalog\Model\Product
- */
- protected function createBundledProduct($sku, $price, $taxClassId, $itemData)
- {
- $objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager();
-
- $children = [];
- foreach ($itemData['children'] as $child) {
- $taxClassName =
- isset($child['tax_class_name']) ? $child['tax_class_name'] : self::PRODUCT_TAX_CLASS_1;
- $taxClassId = $this->productTaxClasses[$taxClassName];
- $children[$child['sku']] = $this->createSimpleProduct($child['sku'], $child['price'], $taxClassId);
- }
-
-
- $bundleOptionsData = $itemData['bundled_options'];
-
- // Add each child to a group
- $bundleSelectionsData = [];
- foreach ($bundleOptionsData as $optionsKey => $optionsData) {
- $optionGroup = [];
- $optionsKey++;
-
- $selectedSkus = $optionsData['selected_skus'];
- foreach ($selectedSkus as $selectedSku) {
- $product = $children[$selectedSku];
- $optionGroup[] = [
- 'product_id' => $product->getId(),
- 'selection_qty' => 1, // The qty of this option is set by the ['bundled_options']['qty'] value
- 'selection_can_change_qty' => 1,
- 'delete' => '',
- 'option_id' => $optionsKey
- ];
- }
- if (count($optionGroup)) {
- $bundleSelectionsData[] = $optionGroup;
- }
- }
-
- $priceType = $itemData['price_type'];
-
- if ($this->loadProductBySku($sku)) {
- $product = $this->loadProductBySku($sku);
- } else {
- /** @var $product \Magento\Catalog\Model\Product */
- $product = $objectManager->create('Magento\Catalog\Model\Product');
- }
-
- $product->setTypeId(\Magento\Catalog\Model\Product\Type::TYPE_BUNDLE)
- ->setAttributeSetId(4)
- ->setWebsiteIds([1])
- ->setName('Bundle Product ' . $sku)
- ->setSku($sku)
- ->setVisibility(\Magento\Catalog\Model\Product\Visibility::VISIBILITY_BOTH)
- ->setStatus(\Magento\Catalog\Model\Product\Attribute\Source\Status::STATUS_ENABLED)
- ->setStockData([
- 'use_config_manage_stock' => 1,
- 'qty' => 100,
- 'is_qty_decimal' => 0,
- 'is_in_stock' => 1
- ])
- ->setPriceView(1)
- ->setPriceType($priceType)
- ->setPrice($price)
- ->setTaxClassId($taxClassId)
- ->setBundleOptionsData($bundleOptionsData)
- ->setBundleSelectionsData($bundleSelectionsData)
- ->save();
-
- $this->products[$sku] = $product;
-
- return $product;
- }
-
- /**
- * Attempt to load product by SKU
- *
- * @param string $sku
- * @return \Magento\Catalog\Api\Data\ProductInterface
- */
- protected function loadProductBySku($sku)
- {
- try {
- return $this->productRepository->get($sku);
- } catch (\Magento\Framework\Exception\NoSuchEntityException $e) {
- return false;
- }
- }
-
- /**
- * Create a customer group and associated it with given customer tax class
- *
- * @param int $customerTaxClassId
- * @return int
- */
- protected function createCustomerGroup($customerTaxClassId)
- {
- /** @var \Magento\Customer\Api\GroupRepositoryInterface $groupRepository */
- $groupRepository = $this->objectManager->create('Magento\Customer\Api\GroupRepositoryInterface');
- $customerGroupFactory = $this->objectManager->create('Magento\Customer\Api\Data\GroupInterfaceFactory');
- $customerGroup = $customerGroupFactory->create()
- ->setCode('custom_group')
- ->setTaxClassId($customerTaxClassId);
- $customerGroupId = $groupRepository->save($customerGroup)->getId();
- return $customerGroupId;
- }
-
- /**
- * Create a customer
- *
- * @param array $customerData
- * @return \Magento\Customer\Api\Data\CustomerInterface
- */
- protected function createCustomer(array $customerData)
- {
- if ($this->customer) {
- return $this->customer;
- }
-
- $taxClassName = isset($customerData['tax_class_name'])
- ? $customerData['tax_class_name']
- : self::CUSTOMER_TAX_CLASS_1;
- $customerGroupId = $this->createCustomerGroup($this->customerTaxClasses[$taxClassName]);
- /** @var \Magento\Customer\Model\Customer $customer */
- $customer = $this->objectManager->create('Magento\Customer\Model\Customer');
- $customer->isObjectNew(true);
- $customer->setWebsiteId(1)
- ->setEntityTypeId(1)
- ->setAttributeSetId(1)
- ->setEmail('customer@example.com')
- ->setPassword('password')
- ->setGroupId($customerGroupId)
- ->setStoreId(1)
- ->setIsActive(1)
- ->setFirstname('Firstname')
- ->setLastname('Lastname')
- ->save();
-
- $this->customer = $this->customerRepository->getById($customer->getId());
-
- return $this->customer;
- }
-
- /**
- * Create customer address
- *
- * @param array $addressOverride
- * @param int $customerId
- * @return \Magento\Customer\Model\Address
- */
- protected function createCustomerAddress($addressOverride, $customerId)
- {
- $defaultAddressData = [
- 'attribute_set_id' => 2,
- 'telephone' => 123456789,
- 'postcode' => self::MI_POST_CODE,
- 'country_id' => self::COUNTRY_US,
- 'city' => self::MI_CITY,
- 'company' => 'CompanyName',
- 'street' => [self::MI_STREET_1],
- 'lastname' => 'Smith',
- 'firstname' => 'John',
- 'parent_id' => 1,
- 'region_id' => self::REGION_MI,
- ];
- $addressData = array_merge($defaultAddressData, $addressOverride);
-
- /** @var \Magento\Customer\Model\Address $customerAddress */
- $customerAddress = $this->objectManager->create('Magento\Customer\Model\Address');
- $customerAddress->setData($addressData)
- ->setCustomerId($customerId)
- ->save();
-
- return $customerAddress;
- }
-
- /**
- * Create shopping cart rule
- *
- * @param array $ruleDataOverride
- * @return $this
- */
- protected function createCartRule($ruleDataOverride)
- {
- /** @var \Magento\SalesRule\Model\Rule $salesRule */
- $salesRule = $this->objectManager->create('Magento\SalesRule\Model\Rule');
- $ruleData = array_merge($this->defaultShoppingCartPriceRule, $ruleDataOverride);
- $salesRule->setData($ruleData);
- $salesRule->save();
-
- return $this;
- }
-
- /**
- * Create a quote object with customer
- *
- * @param array $quoteData
- * @param \Magento\Customer\Api\Data\CustomerInterface $customer
- * @return \Magento\Quote\Model\Quote
- */
- protected function createQuote($quoteData, $customer)
- {
- /** @var \Magento\Customer\Api\AddressRepositoryInterface $addressService */
- $addressService = $this->objectManager->create('Magento\Customer\Api\AddressRepositoryInterface');
-
- /** @var array $shippingAddressOverride */
- $shippingAddressOverride = empty($quoteData['shipping_address']) ? [] : $quoteData['shipping_address'];
- /** @var \Magento\Customer\Model\Address $shippingAddress */
- $shippingAddress = $this->createCustomerAddress($shippingAddressOverride, $customer->getId());
-
- /** @var \Magento\Quote\Model\Quote\Address $quoteShippingAddress */
- $quoteShippingAddress = $this->objectManager->create('Magento\Quote\Model\Quote\Address');
- $quoteShippingAddress->importCustomerAddressData($addressService->getById($shippingAddress->getId()));
-
- /** @var array $billingAddressOverride */
- $billingAddressOverride = empty($quoteData['billing_address']) ? [] : $quoteData['billing_address'];
- /** @var \Magento\Customer\Model\Address $billingAddress */
- $billingAddress = $this->createCustomerAddress($billingAddressOverride, $customer->getId());
-
- /** @var \Magento\Quote\Model\Quote\Address $quoteBillingAddress */
- $quoteBillingAddress = $this->objectManager->create('Magento\Quote\Model\Quote\Address');
- $quoteBillingAddress->importCustomerAddressData($addressService->getById($billingAddress->getId()));
-
- /** @var \Magento\Quote\Model\Quote $quote */
- $quote = $this->objectManager->create('Magento\Quote\Model\Quote');
- $quote->setStoreId(1)
- ->setIsActive(true)
- ->setIsMultiShipping(false)
- ->assignCustomerWithAddressChange($customer, $quoteBillingAddress, $quoteShippingAddress)
- ->setCheckoutMethod('register')
- ->setPasswordHash($this->accountManagement->getPasswordHash(static::CUSTOMER_PASSWORD));
-
- if (isset($quoteData['currency_rates'])) {
- $this->createCurrencyRate($quoteData['currency_rates'], $quote);
- }
-
- return $quote;
- }
-
- /**
- * Add products to quote
- *
- * @param \Magento\Quote\Model\Quote $quote
- * @param array $itemsData
- * @return $this
- */
- protected function addProductsToQuote(\Magento\Quote\Model\Quote $quote, $itemsData)
- {
- foreach ($itemsData as $itemData) {
- $sku = $itemData['sku'];
- $price = $itemData['price'];
- $qty = isset($itemData['qty']) ? $itemData['qty'] : 1;
- $taxClassName =
- isset($itemData['tax_class_name']) ? $itemData['tax_class_name'] : self::PRODUCT_TAX_CLASS_1;
- $taxClassId = $this->productTaxClasses[$taxClassName];
-
- if ($itemData['type'] == \Magento\Catalog\Model\Product\Type::TYPE_BUNDLE) {
- $product = $this->createBundledProduct($sku, $price, $taxClassId, $itemData);
- } elseif ($itemData['type'] == \Magento\ConfigurableProduct\Model\Product\Type\Configurable::TYPE_CODE) {
- $product = $this->createConfigurableProduct($sku, $price, $taxClassId, $itemData);
- } else {
- $product = $this->createSimpleProduct($sku, $price, $taxClassId);
- }
- $this->addProductToQuote($quote, $product, $qty, $itemData);
- }
- return $this;
- }
-
- /**
- * Add product to quote
- *
- * This file was inspired by
- * @see dev/tests/integration/testsuite/Magento/Checkout/_files/quote_with_bundle_and_options.php
- *
- * @param \Magento\Quote\Model\Quote $quote
- * @param \Magento\Catalog\Model\Product $product
- * @param int $qty
- * @param $itemData
- * @throws \Exception
- * @throws \Magento\Framework\Exception\LocalizedException
- */
- protected function addProductToQuote(
- \Magento\Quote\Model\Quote $quote,
- \Magento\Catalog\Model\Product $product,
- $qty,
- $itemData
- ) {
- if ($product->getTypeId() == \Magento\Catalog\Model\Product\Type::TYPE_SIMPLE) {
- $quote->addProduct($product, $qty);
- } elseif ($product->getTypeId() == \Magento\ConfigurableProduct\Model\Product\Type\Configurable::TYPE_CODE) {
-
- $attribute = $this->getConfigurableAttribute(self::CONFIGURABLE_ATTRIBUTE_NAME);
-
- /** @var \Magento\Eav\Api\Data\AttributeOptionInterface[] $options */
- $options = $attribute->getOptions();
- array_shift($options); //remove the first option which is empty
-
- $requestInfo = new \Magento\Framework\DataObject;
-
- if (!empty($options)) {
- $option = $options[0];
- $requestData = [
- 'qty' => $qty
- ];
- /** @var \Magento\ConfigurableProduct\Api\Data\ConfigurableItemOptionValueInterface $option */
- $requestData['super_attribute'][$attribute->getId()] = $option->getValue();
- $requestInfo->addData($requestData);
- }
-
- $quote->addProduct($product, $requestInfo);
-
- } elseif ($product->getTypeId() == \Magento\Catalog\Model\Product\Type::TYPE_BUNDLE) {
- /** @var $typeInstance \Magento\Bundle\Model\Product\Type */
- //Load options
- $typeInstance = $product->getTypeInstance();
- $typeInstance->setStoreFilter($product->getStoreId(), $product);
- $optionCollection = $typeInstance->getOptionsCollection($product);
-
- $bundleOptions = [];
- $bundleOptionsQty = [];
- /** @var $option \Magento\Bundle\Model\Option */
- foreach ($optionCollection as $option) {
- $selectionsCollection = $typeInstance->getSelectionsCollection([$option->getId()], $product);
- if ($option->isMultiSelection()) {
- $selectionsCollection->load();
- $bundleOptions[$option->getId()] = array_column($selectionsCollection->toArray(), 'selection_id');
- } else {
- $bundleOptions[$option->getId()] = $selectionsCollection->getFirstItem()->getSelectionId();
- }
- $optionQty = 1;
- foreach ($itemData['bundled_options'] as $bundledOptionData) {
- if ($option->getTitle() == $bundledOptionData['title']) {
- $optionQty = $bundledOptionData['qty'];
- break;
- }
- }
-
- $bundleOptionsQty[$option->getId()] = $optionQty;
- }
-
- $requestInfo = new \Magento\Framework\DataObject(
- [
- 'qty' => $qty,
- 'bundle_option' => $bundleOptions,
- 'bundle_option_qty' => $bundleOptionsQty
- ]
- );
-
- $quote->addProduct($product, $requestInfo);
- } else {
- throw new \Exception('Unrecognized type: ' . $product->getTypeId());
- }
- }
-
- /**
- * Create currency rates and set rate on quote
- *
- * @param $ratesData
- * @param \Magento\Quote\Model\Quote $quote
- */
- protected function createCurrencyRate($ratesData, \Magento\Quote\Model\Quote $quote)
- {
- $baseCurrencyCode = $ratesData['base_currency_code'];
- $quoteCurrencyCode = $ratesData['quote_currency_code'];
- $currencyConversionRate = $ratesData['currency_conversion_rate'];
-
- $newRate = [
- $baseCurrencyCode => [$quoteCurrencyCode => $currencyConversionRate]
- ];
- /** @var \Magento\Directory\Model\Currency $currency */
- $currency = $this->objectManager->get('Magento\Directory\Model\Currency');
- $currency->saveRates($newRate);
-
- // Set the currency code on the store so that the \Magento\Quote\Model\Quote::beforeSave() method sets the
- // quote_currency_code to the appropriate value
- $quote->getStore()->getCurrentCurrency()->setData('currency_code', $quoteCurrencyCode);
-
- // Save the quote to register the quote_currency_code
- $quote->save();
- }
-
- /**
- * Create a quote based on given data
- *
- * @param array $quoteData
- * @return \Magento\Quote\Model\Quote
- */
- public function setupQuote($quoteData)
- {
- $customerData = isset($quoteData['customer_data']) ? $quoteData['customer_data'] : [];
- $customer = $this->createCustomer($customerData);
-
- $quote = $this->createQuote($quoteData, $customer);
-
- $this->addProductsToQuote($quote, $quoteData['items']);
-
- //Set shipping amount
- if (isset($quoteData['shipping'])) {
- $shippingMethod = $quoteData['shipping']['method'];
- $shippingAmount = $quoteData['shipping']['amount'];
- $shippingBaseAmount = $quoteData['shipping']['base_amount'];
- $quote->getShippingAddress()->setShippingMethod($shippingMethod)
- ->setShippingDescription('Flat Rate - Fixed')
- ->setShippingAmount($shippingAmount)
- ->setBaseShippingAmount($shippingBaseAmount)
- ->save();
-
- $quote->getShippingAddress()->setCollectShippingRates(true);
- }
-
- //create shopping cart rules if necessary
- if (!empty($quoteData['shopping_cart_rules'])) {
- foreach ($quoteData['shopping_cart_rules'] as $ruleData) {
- $ruleData['customer_group_ids'] = [$customer->getGroupId()];
- $this->createCartRule($ruleData);
- }
- }
-
- return $quote;
- }
-}
diff --git a/Test/Integration/Model/Tax/Sales/Total/Quote/TaxTest.php b/Test/Integration/Model/Tax/Sales/Total/Quote/TaxTest.php
deleted file mode 100755
index c2d8e33e..00000000
--- a/Test/Integration/Model/Tax/Sales/Total/Quote/TaxTest.php
+++ /dev/null
@@ -1,482 +0,0 @@
- $value) {
- $this->assertEquals($value, $item->getData($key), 'item ' . $key . ' is incorrect');
- }
-
- return $this;
- }
-
- /**
- * Verify one tax rate in a tax row
- *
- * @param array $appliedTaxRate
- * @param array $expectedAppliedTaxRate
- * @return $this
- */
- protected function verifyAppliedTaxRate($appliedTaxRate, $expectedAppliedTaxRate)
- {
- foreach ($expectedAppliedTaxRate as $key => $value) {
- $this->assertEquals($value, $appliedTaxRate[$key], 'Applied tax rate ' . $key . ' is incorrect');
- }
- return $this;
- }
-
- /**
- * Verify one row in the applied taxes
- *
- * @param array $appliedTax
- * @param array $expectedAppliedTax
- * @return $this
- */
- protected function verifyAppliedTax($appliedTax, $expectedAppliedTax)
- {
- foreach ($expectedAppliedTax as $key => $value) {
- if ($key == 'rates') {
- foreach ($value as $index => $taxRate) {
- $this->verifyAppliedTaxRate($appliedTax['rates'][$index], $taxRate);
- }
- } else {
- $this->assertEquals($value, $appliedTax[$key], 'Applied tax ' . $key . ' is incorrect');
- }
- }
- return $this;
- }
-
- /**
- * Verify that applied taxes are correct
- *
- * @param array $appliedTaxes
- * @param array $expectedAppliedTaxes
- * @return $this
- */
- protected function verifyAppliedTaxes($appliedTaxes, $expectedAppliedTaxes)
- {
- foreach ($expectedAppliedTaxes as $taxRateKey => $expectedTaxRate) {
- $this->assertTrue(isset($appliedTaxes[$taxRateKey]), 'Missing tax rate ' . $taxRateKey);
- $this->verifyAppliedTax($appliedTaxes[$taxRateKey], $expectedTaxRate);
- }
- return $this;
- }
-
- /**
- * Verify fields in quote address
- *
- * @param \Magento\Quote\Model\Quote\Address $quoteAddress
- * @param array $expectedAddressData
- * @return $this
- */
- protected function verifyQuoteAddress($quoteAddress, $expectedAddressData)
- {
- foreach ($expectedAddressData as $key => $value) {
- if ($key == 'applied_taxes') {
- $this->verifyAppliedTaxes($quoteAddress->getAppliedTaxes(), $value);
- } else {
- $this->assertEquals($value, $quoteAddress->getData($key), 'Quote address ' . $key . ' is incorrect');
- }
- }
-
- return $this;
- }
-
- /**
- * Verify fields in quote address and quote item are correct
- *
- * @param \Magento\Quote\Model\Quote\Address $quoteAddress
- * @param array $expectedResults
- * @return $this
- */
- protected function verifyResult($quoteAddress, $expectedResults)
- {
- $addressData = $expectedResults['address_data'];
-
- $this->verifyQuoteAddress($quoteAddress, $addressData);
-
- $quoteItems = $quoteAddress->getAllItems();
- foreach ($quoteItems as $item) {
- /** @var \Magento\Quote\Model\Quote\Address\Item $item */
- $sku = $this->getActualSkuForQuoteItem($item);
-
- $this->assertTrue(
- isset($expectedResults['items_data'][$sku]),
- "Missing array key in 'expected_results' for $sku"
- );
-
- $expectedItemData = $expectedResults['items_data'][$sku];
- $this->verifyItem($item, $expectedItemData);
- }
-
- // Make sure all 'expected_result' items are present in quote
- foreach ($quoteItems as $item) {
- unset($expectedResults['items_data'][$this->getActualSkuForQuoteItem($item)]);
- }
- $this->assertEmpty(
- $expectedResults['items_data'],
- 'The following expected_results items were not present in quote: '
- . implode(', ', array_keys($expectedResults['items_data']))
- );
-
- return $this;
- }
-
- /**
- * Get actual SKU for quote item. This used since configurable product quote items report the child SKU when
- * $item->getProduct()->getSku() is called
- *
- * @param \Magento\Quote\Model\Quote\Item\AbstractItem $item
- * @return mixed
- */
- protected function getActualSkuForQuoteItem(\Magento\Quote\Model\Quote\Item\AbstractItem $item)
- {
- return $item->getProduct()->getData('sku');
- }
-
- /**
- * Test tax calculation with various configuration and combination of items
- * This method will test various collectors through $quoteAddress->collectTotals() method
- *
- * @param array $configData
- * @param array $quoteData
- * @param array $expectedResults
- * @magentoDbIsolation enabled
- * @magentoAppIsolation enabled
- * @dataProvider taxDataProvider
- * @return void
- */
- public function testTaxCalculation($configData, $quoteData, $expectedResults)
- {
- /** @var \Magento\Framework\ObjectManagerInterface $objectManager */
- $objectManager = Bootstrap::getObjectManager();
- /** @var \Magento\Quote\Model\Quote\TotalsCollector $totalsCollector */
- $totalsCollector = $objectManager->create('Magento\Quote\Model\Quote\TotalsCollector');
-
- //Setup tax configurations
- $this->setupUtil = new SetupUtil($objectManager);
- $this->setupUtil->setupTax($configData);
-
- $quote = $this->setupUtil->setupQuote($quoteData);
- $quoteAddress = $quote->getShippingAddress();
- $totalsCollector->collectAddressTotals($quote, $quoteAddress);
- $this->verifyResult($quoteAddress, $expectedResults);
- }
-
- /**
- * Test tax calculation with various configuration and combination of items
- * This method will test various collectors through $quoteAddress->collectTotals() method
- *
- * @param array $configData
- * @param array $quoteData
- * @param array $expectedResults
- * @magentoDbIsolation enabled
- * @magentoAppIsolation enabled
- * @dataProvider taxDataProvider
- * @return void
- */
- public function testNativeVsMagentoTaxCalculation($configData, $quoteData, $expectedResults)
- {
- // Only compare with native Magento taxes if this test is configured to do so
- if (!isset($expectedResults['compare_with_native_tax_calculation'])
- || !$expectedResults['compare_with_native_tax_calculation']
- ) {
- return;
- }
-
- /** @var \Magento\Framework\ObjectManagerInterface $objectManager */
- $objectManager = Bootstrap::getObjectManager();
- //Setup tax configurations
- $this->setupUtil = new SetupUtil($objectManager);
- // Ensure AvaTax is disabled
- $nativeConfigData = [
- SetupUtil::CONFIG_OVERRIDES => [
- \ClassyLlama\AvaTax\Helper\Config::XML_PATH_AVATAX_MODULE_ENABLED => 0,
- ],
- ];
- $nativeQuoteAddress = $this->calculateTaxes($nativeConfigData, $quoteData);
- $avaTaxQuoteAddress = $this->calculateTaxes($configData, $quoteData, false);
- $this->compareResults($nativeQuoteAddress, $avaTaxQuoteAddress, $expectedResults);
- }
-
- /**
- * Calculate taxes based on the specified config values
- *
- * @param $configData
- * @param $quoteData
- * @param bool $setupTaxData
- * @return \Magento\Quote\Model\Quote\Address
- */
- protected function calculateTaxes($configData, $quoteData, $setupTaxData = true)
- {
- /** @var \Magento\Framework\ObjectManagerInterface $objectManager */
- $objectManager = Bootstrap::getObjectManager();
- /** @var \Magento\Quote\Model\Quote\TotalsCollector $totalsCollector */
- $totalsCollector = $objectManager->create('Magento\Quote\Model\Quote\TotalsCollector');
-
- if ($setupTaxData) {
- $this->setupUtil->setupTax($configData);
- } elseif (!empty($configData[SetupUtil::CONFIG_OVERRIDES])) {
- //Tax calculation configuration
- $this->setupUtil->setConfig($configData[SetupUtil::CONFIG_OVERRIDES]);
- }
-
- $quote = $this->setupUtil->setupQuote($quoteData);
- $quoteAddress = $quote->getShippingAddress();
- $totalsCollector->collectAddressTotals($quote, $quoteAddress);
- return $quoteAddress;
- }
-
- /**
- * Compare two quote addresses and ensure that their values either match or don't match
- *
- * @param \Magento\Quote\Model\Quote\Address $nativeQuoteAddress
- * @param \Magento\Quote\Model\Quote\Address $avaTaxQuoteAddress
- * @param $expectedResults
- * @return $this
- * @throws \Exception
- */
- protected function compareResults(
- \Magento\Quote\Model\Quote\Address $nativeQuoteAddress,
- \Magento\Quote\Model\Quote\Address $avaTaxQuoteAddress,
- $expectedResults
- ) {
- $this->compareQuoteAddresses($nativeQuoteAddress, $avaTaxQuoteAddress);
-
- $avaTaxItemsBySku = [];
- foreach ($avaTaxQuoteAddress->getAllItems() as $item) {
- if (isset($avaTaxItemsBySku[$this->getActualSkuForQuoteItem($item)])) {
- throw new \Exception(__('Quote contains items containing the same SKU.'
- . ' This will not work since SKU must be used as the GUID to compare quote items.'));
- }
- $avaTaxItemsBySku[$this->getActualSkuForQuoteItem($item)] = $item;
- }
-
- $quoteItems = $nativeQuoteAddress->getAllItems();
- foreach ($quoteItems as $item) {
- /** @var \Magento\Quote\Model\Quote\Address\Item $item */
- $sku = $this->getActualSkuForQuoteItem($item);
-
- $this->assertTrue(
- isset($expectedResults['items_data'][$sku]),
- "Missing array key in 'expected_results' for $sku"
- );
-
- if (!isset($avaTaxItemsBySku[$sku])) {
- throw new \Exception(__('Sku %1 was not found in AvaTax quote.', $sku));
- }
-
- $avaTaxItem = $avaTaxItemsBySku[$sku];
- $this->compareItems($item, $avaTaxItem);
- }
-
- // Make sure all 'expected_result' items are present in quote
- foreach ($quoteItems as $item) {
- unset($expectedResults['items_data'][$this->getActualSkuForQuoteItem($item)]);
- }
- $this->assertEmpty(
- $expectedResults['items_data'],
- 'The following expected_results items were not present in quote: '
- . implode(', ', array_keys($expectedResults['items_data']))
- );
-
- return $this;
- }
-
- /**
- * Compare quote address and ensure fields match / don't match
- *
- * @param \Magento\Quote\Model\Quote\Address $nativeQuoteAddress
- * @param \Magento\Quote\Model\Quote\Address $avaTaxQuoteAddress
- * @return $this
- */
- protected function compareQuoteAddresses($nativeQuoteAddress, $avaTaxQuoteAddress)
- {
- foreach ($this->quoteAddressFieldsEnsureMatch as $value) {
- $this->assertEquals(
- $nativeQuoteAddress->getData($value),
- $avaTaxQuoteAddress->getData($value),
- 'native/AvaTax calculation does not match for quote address field: ' . $value
- );
- }
- foreach ($this->quoteAddressFieldsEnsureDiff as $value) {
- $this->assertNotEquals(
- $nativeQuoteAddress->getData($value),
- $avaTaxQuoteAddress->getData($value),
- 'native/AvaTax calculation matches (but shouldn\'t be) for quote address field: ' . $value
- );
- }
-
- return $this;
- }
-
- /**
- * Compare quote items and ensure fields match
- *
- * @param \Magento\Quote\Model\Quote\Item\AbstractItem $nativeItem
- * @param \Magento\Quote\Model\Quote\Item\AbstractItem $avaTaxItem
- * @return $this
- */
- protected function compareItems(
- \Magento\Quote\Model\Quote\Item\AbstractItem $nativeItem,
- \Magento\Quote\Model\Quote\Item\AbstractItem $avaTaxItem
- ) {
- foreach ($this->quoteItemFieldsEnsureMatch as $value) {
- $this->assertEquals(
- $nativeItem->getData($value),
- $avaTaxItem->getData($value),
- 'native/AvaTax calculation does not match for quote item field: ' . $value
- );
- }
-
- return $this;
- }
-
- /**
- * Read the array defined in ../../../../_files/tax_calculation_data_aggregated.php
- * and feed it to testTaxCalculation
- *
- * @return array
- */
- public function taxDataProvider()
- {
- global $taxCalculationData;
- return $taxCalculationData;
- }
-}
diff --git a/Test/Integration/_files/address_data.php b/Test/Integration/_files/address_data.php
deleted file mode 100644
index 229e20b9..00000000
--- a/Test/Integration/_files/address_data.php
+++ /dev/null
@@ -1,14 +0,0 @@
- 'CA',
- 'region_id' => '12',
- 'postcode' => '123-456',
- 'lastname' => 'lastname',
- 'firstname' => 'firstname',
- 'street' => 'street',
- 'city' => 'Los Angeles',
- 'email' => 'admin@example.com',
- 'telephone' => '11111111',
- 'country_id' => 'US'
-];
diff --git a/Test/Integration/_files/creditmemo.php b/Test/Integration/_files/creditmemo.php
deleted file mode 100644
index 442a61f8..00000000
--- a/Test/Integration/_files/creditmemo.php
+++ /dev/null
@@ -1,24 +0,0 @@
-get(CreditmemoFactory::class);
-$creditMemo = $creditMemoFactory->createByOrder($order, $order->getData());
-$creditMemo->setOrder($order);
-$creditMemo->setState(Creditmemo::STATE_OPEN);
-$creditMemo->setIncrementId('100000001');
-$creditMemo->setBaseAdjustmentPositive(5.00);
-$creditMemo->setBaseAdjustmentNegative(10.00);
-
-/** @var CreditmemoRepositoryInterface $creditMemoRepository */
-$creditMemoRepository = $objectManager->get(CreditmemoRepositoryInterface::class);
-$creditMemoRepository->save($creditMemo);
diff --git a/Test/Integration/_files/default_rollback.php b/Test/Integration/_files/default_rollback.php
deleted file mode 100644
index 604ebd61..00000000
--- a/Test/Integration/_files/default_rollback.php
+++ /dev/null
@@ -1,25 +0,0 @@
-get(Registry::class);
-$registry->unregister('isSecureArea');
-$registry->register('isSecureArea', true);
-/** @var OrderCollection $orderCollection */
-$orderCollection = Bootstrap::getObjectManager()->create(OrderCollection::class);
-
-/** @var Order $order */
-foreach ($orderCollection as $order) {
- $order->delete();
-}
-
-/** @var StockRegistryStorage $stockRegistryStorage */
-$stockRegistryStorage = Bootstrap::getObjectManager()->get(StockRegistryStorage::class);
-$stockRegistryStorage->clean();
-$registry->unregister('isSecureArea');
-$registry->register('isSecureArea', false);
diff --git a/Test/Integration/_files/order.php b/Test/Integration/_files/order.php
deleted file mode 100644
index 27377d40..00000000
--- a/Test/Integration/_files/order.php
+++ /dev/null
@@ -1,75 +0,0 @@
-create(OrderAddress::class, ['data' => $addressData]);
-$billingAddress->setAddressType('billing');
-
-/** @var OrderAddress $shippingAddress */
-$shippingAddress = clone $billingAddress;
-$shippingAddress->setId(null)->setAddressType('shipping');
-
-/** @var Payment $payment */
-$payment = $objectManager->create(Payment::class);
-$payment->setMethod('checkmo')
- ->setAdditionalInformation('last_trans_id', '1112233')
- ->setAdditionalInformation(
- 'metadata',
- [
- 'type' => 'free',
- 'fraudulent' => false,
- ]
- );
-
-/** @var OrderItem $orderItem */
-$orderItem = $objectManager->create(OrderItem::class);
-$orderItem->setProductId($product->getId())
- ->setQtyOrdered($product->getQty())
- ->setQtyInvoiced($product->getQty())
- ->setBasePrice($product->getPrice())
- ->setPrice($product->getPrice())
- ->setProductType($product->getTypeId())
- ->setName($product->getName())
- ->setRowTotal($product->getPrice());
-
-/** @var Order $order */
-$order = $objectManager->create(Order::class);
-$orderData = [
- 'increment_id' => '123456789',
- 'state' => Order::STATE_PROCESSING,
- 'status' => $order->getConfig()->getStateDefaultStatus(Order::STATE_PROCESSING),
- 'grand_total' => 160.00,
- 'base_grand_total' => 160.00,
- 'subtotal' => 160.00,
- 'total_paid' => 160.00,
- 'store_id' => $objectManager->get(StoreManagerInterface::class)->getStore()->getId(),
- 'website_id' => 1,
- 'payment' => $payment
-];
-
-$order
- ->setData($orderData)
- ->addItem($orderItem)
- ->setCustomerIsGuest(true)
- ->setCustomerEmail('email@example.com')
- ->setBillingAddress($billingAddress)
- ->setShippingAddress($shippingAddress);
-
-/** @var OrderRepositoryInterface $orderRepository */
-$orderRepository = $objectManager->create(OrderRepositoryInterface::class);
-$orderRepository->save($order);
diff --git a/Test/Integration/_files/product_simple.php b/Test/Integration/_files/product_simple.php
deleted file mode 100644
index 16d921ec..00000000
--- a/Test/Integration/_files/product_simple.php
+++ /dev/null
@@ -1,157 +0,0 @@
-reinitialize();
-
-/** @var ObjectManager $objectManager */
-$objectManager = Bootstrap::getObjectManager();
-/** @var CategoryLinkManagementInterface $categoryLinkManagement */
-$categoryLinkManagement = $objectManager->get(CategoryLinkManagementInterface::class);
-
-$tierPrices = [];
-/** @var ProductTierPriceInterfaceFactory $tierPriceFactory */
-$tierPriceFactory = $objectManager->get(ProductTierPriceInterfaceFactory::class);
-/** @var ProductTierPriceExtensionFactory $tpExtensionAttributes */
-$tpExtensionAttributesFactory = $objectManager->get(ProductTierPriceExtensionFactory::class);
-/** @var ProductExtensionFactory $productExtensionAttributes */
-$productExtensionAttributesFactory = $objectManager->get(ProductExtensionFactory::class);
-/** @var Website $adminWebsite */
-$adminWebsite = $objectManager->get(WebsiteRepositoryInterface::class)->get('admin');
-/** @var ProductTierPriceExtension $tierPriceExtensionAttributes1 */
-$tierPriceExtensionAttributes1 = $tpExtensionAttributesFactory->create()
- ->setWebsiteId($adminWebsite->getId());
-$productExtensionAttributesWebsiteIds = $productExtensionAttributesFactory->create(
- ['website_ids' => $adminWebsite->getId()]
-);
-
-$tierPrices[] = $tierPriceFactory->create(
- [
- 'data' => [
- 'customer_group_id' => Group::CUST_GROUP_ALL,
- 'qty' => 2,
- 'value' => 8
- ]
- ]
-)->setExtensionAttributes($tierPriceExtensionAttributes1);
-
-$tierPrices[] = $tierPriceFactory->create(
- [
- 'data' => [
- 'customer_group_id' => Group::CUST_GROUP_ALL,
- 'qty' => 5,
- 'value' => 5
- ]
- ]
-)->setExtensionAttributes($tierPriceExtensionAttributes1);
-
-$tierPriceExtensionAttributes2 = $tpExtensionAttributesFactory->create()
- ->setWebsiteId($adminWebsite->getId())
- ->setPercentageValue(50);
-
-$tierPrices[] = $tierPriceFactory->create(
- [
- 'data' => [
- 'customer_group_id' => Group::NOT_LOGGED_IN_ID,
- 'qty' => 10
- ]
- ]
-)->setExtensionAttributes($tierPriceExtensionAttributes2);
-
-/** @var $product Product */
-$product = $objectManager->create(Product::class);
-$product->isObjectNew(true);
-$product->setTypeId(ProductType::TYPE_SIMPLE)
- ->setId(1)
- ->setAttributeSetId(4)
- ->setWebsiteIds([1])
- ->setName('Simple Product')
- ->setSku('simple')
- ->setQty(100)
- ->setPrice(10)
- ->setWeight(1)
- ->setShortDescription('Short description')
- ->setTaxClassId(0)
- ->setTierPrices($tierPrices)
- ->setDescription('Description with html tag ')
- ->setExtensionAttributes($productExtensionAttributesWebsiteIds)
- ->setMetaTitle('meta title')
- ->setMetaKeyword('meta keyword')
- ->setMetaDescription('meta description')
- ->setVisibility(Visibility::VISIBILITY_BOTH)
- ->setStatus(SourceStatus::STATUS_ENABLED)
- ->setStockData(
- [
- 'use_config_manage_stock' => 1,
- 'qty' => 100,
- 'is_qty_decimal' => 0,
- 'is_in_stock' => 1,
- ]
- )->setCanSaveCustomOptions(true)
- ->setHasOptions(true);
-
-$oldOptions = [
- [
- 'previous_group' => 'text',
- 'title' => 'Test Field',
- 'type' => 'field',
- 'is_require' => 1,
- 'sort_order' => 0,
- 'price' => 1,
- 'price_type' => 'fixed',
- 'sku' => '1-text',
- 'max_characters' => 100,
- ],
- [
- 'previous_group' => 'date',
- 'title' => 'Test Date and Time',
- 'type' => 'date_time',
- 'is_require' => 1,
- 'sort_order' => 0,
- 'price' => 2,
- 'price_type' => 'fixed',
- 'sku' => '2-date',
- ]
-];
-
-$options = [];
-
-/** @var ProductCustomOptionInterfaceFactory $customOptionFactory */
-$customOptionFactory = $objectManager->create(ProductCustomOptionInterfaceFactory::class);
-
-foreach ($oldOptions as $option) {
- /** @var ProductCustomOptionInterface $option */
- $option = $customOptionFactory->create(['data' => $option]);
- $option->setProductSku($product->getSku());
- $options[] = $option;
-}
-
-$product->setOptions($options);
-/** @var ProductRepositoryInterface $productRepository */
-$productRepository = $objectManager->create(ProductRepositoryInterface::class);
-$productRepository->save($product);
-
-$categoryLinkManagement->assignProductToCategories(
- $product->getSku(),
- [2]
-);
diff --git a/Test/Integration/_files/scenarios/applied_taxes_multiple_rates.php b/Test/Integration/_files/scenarios/applied_taxes_multiple_rates.php
deleted file mode 100755
index a79f9529..00000000
--- a/Test/Integration/_files/scenarios/applied_taxes_multiple_rates.php
+++ /dev/null
@@ -1,163 +0,0 @@
- SetupUtil::SAN_DIEGO_POST_CODE,
- 'country_id' => SetupUtil::COUNTRY_US,
- 'city' => SetupUtil::SAN_DIEGO_CITY,
- 'street' => [SetupUtil::SAN_DIEGO_STREET_1],
- 'region_id' => SetupUtil::REGION_CA,
-];
-
-$taxCalculationData['applied_taxes_multiple_rates'] = [
- 'config_data' => [
- SetupUtil::CONFIG_OVERRIDES => $credentialsConfig,
- ],
- 'quote_data' => [
- 'billing_address' => $sanDiegoAddress,
- 'shipping_address' => $sanDiegoAddress,
- 'items' => [
- [
- 'type' => \Magento\Catalog\Model\Product\Type::TYPE_SIMPLE,
- 'sku' => 'simple1',
- 'price' => 10,
- 'qty' => 1,
- ],
- [
- 'type' => \Magento\Catalog\Model\Product\Type::TYPE_SIMPLE,
- 'sku' => 'simple2',
- 'price' => 10,
- 'qty' => 10,
- ],
- ],
- ],
- 'expected_results' => [
- 'compare_with_native_tax_calculation' => true,
- 'address_data' => [
- 'subtotal' => 110.0,
- 'subtotal_incl_tax' => 118.8,
- 'tax_amount' => 8.8,
- 'grand_total' => 118.80,
- 'applied_taxes' => [
- SetupUtil::AVATAX_CA_RATE_DESCRIPTION
- . ' - ' . SetupUtil::AVATAX_CA_COUNTY_RATE_DESCRIPTION
- . ' - ' . SetupUtil::AVATAX_CA_SAN_DIEGO_SPECIAL_RATE_DESCRIPTION
- => [
- 'percent' => 8,
- 'amount' => 8.8,
- 'base_amount' => 8.8,
- 'rates' => [
- [
- 'code' => SetupUtil::AVATAX_CA_RATE_JURISCODE,
- 'title' => SetupUtil::AVATAX_CA_RATE_DESCRIPTION,
- 'percent' => 6.5,
- ],
- [
- 'code' => SetupUtil::AVATAX_CA_COUNTY_RATE_JURISCODE,
- 'title' => SetupUtil::AVATAX_CA_COUNTY_RATE_DESCRIPTION,
- 'percent' => 1,
- ],
- [
- 'code' => SetupUtil::AVATAX_CA_SAN_DIEGO_SPECIAL_RATE_JURISCODE,
- 'title' => SetupUtil::AVATAX_CA_SAN_DIEGO_SPECIAL_RATE_DESCRIPTION,
- 'percent' => 0.5,
- ],
- ],
- ],
- ],
- ],
- 'items_data' => [
- 'simple1' => [
- 'row_total' => 10,
- 'tax_percent' => 8.0,
- 'price' => 10,
- 'price_incl_tax' => 10.8,
- 'row_total_incl_tax' => 10.8,
- 'tax_amount' => 0.8,
- 'applied_taxes' => [
- [
- 'percent' => 8,
- 'amount' => 0.8,
- 'base_amount' => 0.8,
- 'id' => SetupUtil::AVATAX_CA_RATE_DESCRIPTION
- . ' - ' . SetupUtil::AVATAX_CA_COUNTY_RATE_DESCRIPTION
- . ' - ' . SetupUtil::AVATAX_CA_SAN_DIEGO_SPECIAL_RATE_DESCRIPTION,
- 'rates' => [
- [
- 'code' => SetupUtil::AVATAX_CA_RATE_JURISCODE,
- 'title' => SetupUtil::AVATAX_CA_RATE_DESCRIPTION,
- 'percent' => 6.5,
- ],
- [
- 'code' => SetupUtil::AVATAX_CA_COUNTY_RATE_JURISCODE,
- 'title' => SetupUtil::AVATAX_CA_COUNTY_RATE_DESCRIPTION,
- 'percent' => 1,
- ],
- [
- 'code' => SetupUtil::AVATAX_CA_SAN_DIEGO_SPECIAL_RATE_JURISCODE,
- 'title' => SetupUtil::AVATAX_CA_SAN_DIEGO_SPECIAL_RATE_DESCRIPTION,
- 'percent' => 0.5,
- ],
- ],
- 'item_id' => null,
- 'item_type' => 'product',
- 'associated_item_id' => null,
- ],
- ],
- ],
- 'simple2' => [
- 'row_total' => 100,
- 'tax_percent' => 8.0,
- 'price' => 10,
- 'price_incl_tax' => 10.8,
- 'row_total_incl_tax' => 108,
- 'tax_amount' => 8.0,
- 'applied_taxes' => [
- [
- 'percent' => 8,
- 'amount' => 8,
- 'base_amount' => 8,
- 'id' => SetupUtil::AVATAX_CA_RATE_DESCRIPTION
- . ' - ' . SetupUtil::AVATAX_CA_COUNTY_RATE_DESCRIPTION
- . ' - ' . SetupUtil::AVATAX_CA_SAN_DIEGO_SPECIAL_RATE_DESCRIPTION,
- 'rates' => [
- [
- 'code' => SetupUtil::AVATAX_CA_RATE_JURISCODE,
- 'title' => SetupUtil::AVATAX_CA_RATE_DESCRIPTION,
- 'percent' => 6.5,
- ],
- [
- 'code' => SetupUtil::AVATAX_CA_COUNTY_RATE_JURISCODE,
- 'title' => SetupUtil::AVATAX_CA_COUNTY_RATE_DESCRIPTION,
- 'percent' => 1,
- ],
- [
- 'code' => SetupUtil::AVATAX_CA_SAN_DIEGO_SPECIAL_RATE_JURISCODE,
- 'title' => SetupUtil::AVATAX_CA_SAN_DIEGO_SPECIAL_RATE_DESCRIPTION,
- 'percent' => 0.5,
- ],
- ],
- 'item_id' => null,
- 'item_type' => 'product',
- 'associated_item_id' => null,
- ],
- ],
- ],
- ],
- ],
-];
diff --git a/Test/Integration/_files/scenarios/applied_taxes_one_rate.php b/Test/Integration/_files/scenarios/applied_taxes_one_rate.php
deleted file mode 100755
index f7029824..00000000
--- a/Test/Integration/_files/scenarios/applied_taxes_one_rate.php
+++ /dev/null
@@ -1,121 +0,0 @@
- [
- SetupUtil::CONFIG_OVERRIDES => $credentialsConfig,
- ],
- 'quote_data' => [
- 'billing_address' => [
- 'region_id' => SetupUtil::REGION_MI,
- ],
- 'shipping_address' => [
- 'region_id' => SetupUtil::REGION_MI,
- ],
- 'items' => [
- [
- 'type' => \Magento\Catalog\Model\Product\Type::TYPE_SIMPLE,
- 'sku' => 'simple1',
- 'price' => 10,
- 'qty' => 1,
- ],
- [
- 'type' => \Magento\Catalog\Model\Product\Type::TYPE_SIMPLE,
- 'sku' => 'simple2',
- 'price' => 10,
- 'qty' => 10,
- ],
- ],
- ],
- 'expected_results' => [
- 'compare_with_native_tax_calculation' => true,
- 'address_data' => [
- 'subtotal' => 110.0,
- 'subtotal_incl_tax' => 116.6,
- 'tax_amount' => 6.6,
- 'grand_total' => 116.60,
- 'applied_taxes' => [
- SetupUtil::AVATAX_MI_RATE_DESCRIPTION => [
- 'percent' => 6,
- 'amount' => 6.6,
- 'base_amount' => 6.6,
- 'rates' => [
- [
- 'title' => SetupUtil::AVATAX_MI_RATE_DESCRIPTION,
- 'percent' => 6,
- ],
- ],
- ],
- ],
- ],
- 'items_data' => [
- 'simple1' => [
- 'row_total' => 10,
- 'tax_percent' => 6.0,
- 'price' => 10,
- 'price_incl_tax' => 10.6,
- 'row_total_incl_tax' => 10.6,
- 'tax_amount' => 0.6,
- 'applied_taxes' => [
- [
- 'percent' => 6,
- 'amount' => 0.6,
- 'base_amount' => 0.6,
- 'id' => SetupUtil::AVATAX_MI_RATE_DESCRIPTION,
- 'rates' => [
- [
- 'code' => SetupUtil::AVATAX_MI_RATE_JURISCODE,
- 'title' => SetupUtil::AVATAX_MI_RATE_DESCRIPTION,
- 'percent' => 6,
- ],
- ],
- 'item_id' => null,
- 'item_type' => 'product',
- 'associated_item_id' => null,
- ],
- ],
- ],
- 'simple2' => [
- 'row_total' => 100,
- 'tax_percent' => 6.0,
- 'price' => 10,
- 'price_incl_tax' => 10.6,
- 'row_total_incl_tax' => 106,
- 'tax_amount' => 6.0,
- 'applied_taxes' => [
- [
- 'percent' => 6,
- 'amount' => 6,
- 'base_amount' => 6,
- 'id' => SetupUtil::AVATAX_MI_RATE_DESCRIPTION,
- 'rates' => [
- [
- 'code' => SetupUtil::AVATAX_MI_RATE_JURISCODE,
- 'title' => SetupUtil::AVATAX_MI_RATE_DESCRIPTION,
- 'percent' => 6,
- ],
- ],
- 'item_id' => null,
- 'item_type' => 'product',
- 'associated_item_id' => null,
- ],
- ],
- ],
- ],
- ],
-];
diff --git a/Test/Integration/_files/scenarios/bundled_product_dynamic_pricing.php b/Test/Integration/_files/scenarios/bundled_product_dynamic_pricing.php
deleted file mode 100755
index 11db7aea..00000000
--- a/Test/Integration/_files/scenarios/bundled_product_dynamic_pricing.php
+++ /dev/null
@@ -1,225 +0,0 @@
- [
- SetupUtil::CONFIG_OVERRIDES => $credentialsConfig,
- ],
- 'quote_data' => [
- 'billing_address' => [
- 'region_id' => SetupUtil::REGION_MI,
- ],
- 'shipping_address' => [
- 'region_id' => SetupUtil::REGION_MI,
- ],
- 'shipping' => [
- 'method' => 'flatrate_flatrate',
- 'amount' => 6,
- 'base_amount' => 6,
- ],
- 'shopping_cart_rules' => [
- [
- 'discount_amount' => 15,
- ],
- ],
- 'currency_rates' => [
- 'base_currency_code' => 'USD',
- 'quote_currency_code' => 'EUR',
- 'currency_conversion_rate' => 2,
- ],
- 'items' => [
- [
- 'type' => \Magento\Catalog\Model\Product\Type::TYPE_BUNDLE,
- 'price_type' => \Magento\Bundle\Model\Product\Price::PRICE_TYPE_DYNAMIC,
- 'sku' => 'bundle1',
- 'price' => 10, // Price doesn't matter if price_type is dynamic
- 'qty' => 3,
- 'bundled_options' => [
- [
- 'title' => 'Option 1',
- 'default_title' => 'Option 1',
- 'type' => 'select',
- 'required' => 1,
- 'delete' => '',
- 'qty' => 5,
- // Only add multiple SKUs for multi/checkbox options
- 'selected_skus' => [
- 'bundle1_child1',
- ]
- ],
- [
- 'title' => 'Option 2',
- 'default_title' => 'Option 2',
- 'type' => 'checkbox',
- 'required' => 1,
- 'delete' => '',
- 'qty' => 7,
- // Only add multiple SKUs for multi/checkbox options
- 'selected_skus' => [
- 'bundle1_child2',
- 'bundle1_child3',
- ]
- ],
- [
- 'title' => 'Option 3',
- 'default_title' => 'Option 3',
- 'type' => 'checkbox',
- 'required' => 1,
- 'delete' => '',
- 'qty' => 9,
- // Only add multiple SKUs for multi/checkbox options
- 'selected_skus' => [
- 'bundle1_child4',
- ]
- ],
- ],
- // Children items don't have quantity specified, as quantity is determined by the 'bundled_options' array
- 'children' => [
- [
- 'type' => \Magento\Catalog\Model\Product\Type::TYPE_SIMPLE,
- 'sku' => 'bundle1_child1',
- 'price' => 5,
- ],
- [
- 'type' => \Magento\Catalog\Model\Product\Type::TYPE_SIMPLE,
- 'sku' => 'bundle1_child2',
- 'price' => 10,
- ],
- [
- 'type' => \Magento\Catalog\Model\Product\Type::TYPE_SIMPLE,
- 'sku' => 'bundle1_child3',
- 'price' => 15,
- ],
- [
- 'type' => \Magento\Catalog\Model\Product\Type::TYPE_SIMPLE,
- 'sku' => 'bundle1_child4',
- 'price' => 20,
- ],
- ],
- ],
- ],
- ],
- 'expected_results' => [
- // There is an issue comparing with bundled products, so disabling comparison with native Magento
- 'compare_with_native_tax_calculation' => false,
- 'address_data' => [
- 'subtotal' => 2280.0,
- 'base_subtotal' => 1140.0,
- 'subtotal_incl_tax' => 2416.80,
- 'base_subtotal_incl_tax' => 1208.42,
- 'tax_amount' => 118.08,
- 'base_tax_amount' => 59.05,
- 'shipping_amount' => 30.0,
- 'base_shipping_amount' => 15,
- 'shipping_incl_tax' => 31.80,
- 'base_shipping_incl_tax' => 15.9,
- 'shipping_taxable' => 0,
- 'base_shipping_taxable' => 0,
- 'shipping_tax_amount' => 1.8,
- 'base_shipping_tax_amount' => 0.9,
- 'discount_amount' => -342.0,
- 'base_discount_amount' => -171.0,
- 'discount_tax_compensation_amount' => 0,
- 'base_discount_tax_compensation_amount' => 0,
- 'shipping_discount_tax_compensation_amount' => 0,
- 'base_shipping_discount_tax_compensation_amount' => 0,
- 'grand_total' => 2086.08,
- 'base_grand_total' => 1043.05,
- ],
- 'items_data' => [
- 'bundle1' => [
- 'row_total' => 2280.0,
- 'base_row_total' => 1140.0,
- 'tax_percent' => null,
- 'price' => 380, // Price is not multiplied by conversion rate, which is same as native Magento
- 'base_price' => 380.0,
- 'price_incl_tax' => 805.60,
- 'base_price_incl_tax' => 402.81,
- 'row_total_incl_tax' => 2416.80,
- 'base_row_total_incl_tax' => 1208.42,
- 'tax_amount' => 116.28,
- 'base_tax_amount' => 58.15,
- 'discount_amount' => 0,
- 'base_discount_amount' => 0,
- 'discount_percent' => 15,
- 'discount_tax_compensation_amount' => 0,
- 'base_discount_tax_compensation_amount' => 0,
- ],
- 'bundle1_child1' => [
- 'row_total' => 150.0,
- 'base_row_total' => 75.0,
- 'tax_percent' => 6.0,
- 'price' => 5.0,
- 'base_price' => 5.0,
- 'price_incl_tax' => 10.6,
- 'base_price_incl_tax' => 5.30,
- 'row_total_incl_tax' => 159.0,
- 'base_row_total_incl_tax' => 79.51,
- 'tax_amount' => 7.65,
- 'base_tax_amount' => 3.83,
- 'discount_amount' => 22.5,
- 'base_discount_amount' => 11.25,
- ],
- 'bundle1_child2' => [
- 'row_total' => 420.0,
- 'base_row_total' => 210.0,
- 'tax_percent' => 6.0,
- 'price' => 10,
- 'base_price' => 10,
- 'price_incl_tax' => 21.20,
- 'base_price_incl_tax' => 10.6,
- 'row_total_incl_tax' => 445.20,
- 'base_row_total_incl_tax' => 222.60,
- 'tax_amount' => 21.42,
- 'base_tax_amount' => 10.71,
- 'discount_amount' => 63.0,
- 'base_discount_amount' => 31.5,
- ],
- 'bundle1_child3' => [
- 'row_total' => 630.0,
- 'base_row_total' => 315.0,
- 'tax_percent' => 6.0,
- 'price' => 15.0,
- 'base_price' => 15.0,
- 'price_incl_tax' => 31.80,
- 'base_price_incl_tax' => 15.9,
- 'row_total_incl_tax' => 667.80,
- 'base_row_total_incl_tax' => 333.91,
- 'tax_amount' => 32.13,
- 'base_tax_amount' => 16.07,
- 'discount_amount' => 94.5,
- 'base_discount_amount' => 47.25,
- ],
- 'bundle1_child4' => [
- 'row_total' => 1080.0,
- 'base_row_total' => 540.0,
- 'tax_percent' => 6.0,
- 'price' => 20.0,
- 'base_price' => 20.0,
- 'price_incl_tax' => 42.40,
- 'base_price_incl_tax' => 21.20,
- 'row_total_incl_tax' => 1144.8,
- 'base_row_total_incl_tax' => 572.40,
- 'tax_amount' => 55.08,
- 'base_tax_amount' => 27.54,
- 'discount_amount' => 162.0,
- 'base_discount_amount' => 81.0,
- ],
- ],
- ],
-];
diff --git a/Test/Integration/_files/scenarios/bundled_product_fixed_pricing.php b/Test/Integration/_files/scenarios/bundled_product_fixed_pricing.php
deleted file mode 100755
index 6f26ce3d..00000000
--- a/Test/Integration/_files/scenarios/bundled_product_fixed_pricing.php
+++ /dev/null
@@ -1,172 +0,0 @@
- [
- SetupUtil::CONFIG_OVERRIDES => $credentialsConfig,
- ],
- 'quote_data' => [
- 'billing_address' => [
- 'region_id' => SetupUtil::REGION_MI,
- ],
- 'shipping_address' => [
- 'region_id' => SetupUtil::REGION_MI,
- ],
- 'shipping' => [
- 'method' => 'flatrate_flatrate',
- 'amount' => 6,
- 'base_amount' => 6,
- ],
- 'shopping_cart_rules' => [
- [
- 'discount_amount' => 15,
- ],
- ],
- 'currency_rates' => [
- 'base_currency_code' => 'USD',
- 'quote_currency_code' => 'EUR',
- 'currency_conversion_rate' => 2,
- ],
- 'items' => [
- [
- 'type' => \Magento\Catalog\Model\Product\Type::TYPE_BUNDLE,
- 'price_type' => \Magento\Bundle\Model\Product\Price::PRICE_TYPE_FIXED,
- 'sku' => 'bundle1',
- // This price is arbitrary, but is based on the dynamic price in the bundled_product_dynamic_pricing.php file
- 'price' => 380,
- 'qty' => 3,
- 'bundled_options' => [
- [
- 'title' => 'Option 1',
- 'default_title' => 'Option 1',
- 'type' => 'select',
- 'required' => 1,
- 'delete' => '',
- 'qty' => 5,
- // Only add multiple SKUs for multi/checkbox options
- 'selected_skus' => [
- 'bundle1_child1',
- ]
- ],
- [
- 'title' => 'Option 2',
- 'default_title' => 'Option 2',
- 'type' => 'checkbox',
- 'required' => 1,
- 'delete' => '',
- 'qty' => 7,
- // Only add multiple SKUs for multi/checkbox options
- 'selected_skus' => [
- 'bundle1_child2',
- 'bundle1_child3',
- ]
- ],
- [
- 'title' => 'Option 3',
- 'default_title' => 'Option 3',
- 'type' => 'checkbox',
- 'required' => 1,
- 'delete' => '',
- 'qty' => 9,
- // Only add multiple SKUs for multi/checkbox options
- 'selected_skus' => [
- 'bundle1_child4',
- ]
- ],
- ],
- // Children items don't have quantity specified, as quantity is determined by the 'bundled_options' array
- 'children' => [
- [
- 'type' => \Magento\Catalog\Model\Product\Type::TYPE_SIMPLE,
- 'sku' => 'bundle1_child1',
- 'price' => 5, // Price doesn't affect anything since price_type is fixed
- ],
- [
- 'type' => \Magento\Catalog\Model\Product\Type::TYPE_SIMPLE,
- 'sku' => 'bundle1_child2',
- 'price' => 10, // Price doesn't affect anything since price_type is fixed
- ],
- [
- 'type' => \Magento\Catalog\Model\Product\Type::TYPE_SIMPLE,
- 'sku' => 'bundle1_child3',
- 'price' => 15, // Price doesn't affect anything since price_type is fixed
- ],
- [
- 'type' => \Magento\Catalog\Model\Product\Type::TYPE_SIMPLE,
- 'sku' => 'bundle1_child4',
- 'price' => 20, // Price doesn't affect anything since price_type is fixed
- ],
- ],
- ],
- ],
- ],
- 'expected_results' => [
- // There is an issue comparing with bundled products, so disabling comparison with native Magento
- 'compare_with_native_tax_calculation' => false,
- 'address_data' => [
- 'subtotal' => 2280.0,
- 'base_subtotal' => 1140.0,
- 'subtotal_incl_tax' => 2416.80,
- 'base_subtotal_incl_tax' => 1208.40,
- 'tax_amount' => 118.08,
- 'base_tax_amount' => 59.04,
- 'shipping_amount' => 30.0,
- 'base_shipping_amount' => 15,
- 'shipping_incl_tax' => 31.80,
- 'base_shipping_incl_tax' => 15.9,
- 'shipping_taxable' => 0,
- 'base_shipping_taxable' => 0,
- 'shipping_tax_amount' => 1.8,
- 'base_shipping_tax_amount' => 0.9,
- 'discount_amount' => -342.0,
- 'base_discount_amount' => -171.0,
- 'discount_tax_compensation_amount' => 0,
- 'base_discount_tax_compensation_amount' => 0,
- 'shipping_discount_tax_compensation_amount' => 0,
- 'base_shipping_discount_tax_compensation_amount' => 0,
- 'grand_total' => 2086.08,
- 'base_grand_total' => 1043.04,
- ],
- 'items_data' => [
- 'bundle1' => [
- 'row_total' => 2280.0,
- 'base_row_total' => 1140.0,
- 'tax_percent' => 6.0,
- 'price' => 380, // Price is not multiplied by conversion rate, which is same as native Magento
- 'base_price' => 380.0,
- 'price_incl_tax' => 805.60,
- 'base_price_incl_tax' => 402.80,
- 'row_total_incl_tax' => 2416.80,
- 'base_row_total_incl_tax' => 1208.40,
- 'tax_amount' => 116.28,
- 'base_tax_amount' => 58.14,
- 'discount_amount' => 342.0,
- 'base_discount_amount' => 171.0,
- 'discount_percent' => 15,
- 'discount_tax_compensation_amount' => 0,
- 'base_discount_tax_compensation_amount' => 0,
- 'qty' => 3,
- ],
- // Since the price is fixed, the parent item will contain the price information
- 'bundle1_child1' => ['row_total' => null, 'qty' => 5],
- 'bundle1_child2' => ['row_total' => null, 'qty' => 7],
- 'bundle1_child3' => ['row_total' => null, 'qty' => 7],
- 'bundle1_child4' => ['row_total' => null, 'qty' => 9],
- ],
- ],
-];
diff --git a/Test/Integration/_files/scenarios/configurable_product.php b/Test/Integration/_files/scenarios/configurable_product.php
deleted file mode 100755
index 43839ccc..00000000
--- a/Test/Integration/_files/scenarios/configurable_product.php
+++ /dev/null
@@ -1,96 +0,0 @@
- [
- SetupUtil::CONFIG_OVERRIDES => $credentialsConfig,
- ],
- 'quote_data' => [
- 'billing_address' => [
- 'region_id' => SetupUtil::REGION_MI,
- ],
- 'shipping_address' => [
- 'region_id' => SetupUtil::REGION_MI,
- ],
- 'shopping_cart_rules' => [
- [
- 'discount_amount' => 15,
- ],
- ],
- 'items' => [
- [
- 'type' => \Magento\ConfigurableProduct\Model\Product\Type\Configurable::TYPE_CODE,
- 'sku' => 'configurable1',
- 'price' => 10,
- 'qty' => 5,
- // Child products will be automatically created for each option. The first child product/option will be
- // selected and added to cart. The SKU naming pattern is _child where
- // AUTO_INCREMENT_INDEX is starting at one. e.g., configurable1_child1
- 'options' => [
- 'value' => [
- 'option_0' => ['Option 1'],
- 'option_1' => ['Option 2']
- ],
- 'order' => [
- 'option_0' => 1,
- 'option_1' => 2
- ],
- ],
- ],
- ],
- ],
- 'expected_results' => [
- 'compare_with_native_tax_calculation' => true,
- 'address_data' => [
- 'subtotal' => 50,
- 'subtotal_incl_tax' => 53,
- 'tax_amount' => 2.55,
- 'discount_amount' => -7.5,
- 'discount_tax_compensation_amount' => 0,
- 'shipping_discount_tax_compensation_amount' => 0,
- 'grand_total' => 45.05,
- ],
- 'items_data' => [
- 'configurable1' => [
- 'qty' => 5,
- 'row_total' => 50,
- 'tax_percent' => 6.0,
- 'price' => 10,
- 'price_incl_tax' => 10 + 0.6,
- 'row_total_incl_tax' => 53,
- 'tax_amount' => 2.55,
- 'discount_amount' => 7.5,
- 'discount_percent' => 15,
- 'discount_tax_compensation_amount' => 0,
- ],
- 'configurable1_child1' => [
- 'qty' => 1, // Simple children have a QTY of 1, regardless of parent quantity
- // Simple children don't have values calculated
- 'row_total' => 0,
- 'tax_percent' => 0,
- 'price' => 0,
- 'price_incl_tax' => 0,
- 'row_total_incl_tax' => 0,
- 'tax_amount' => 0,
- 'discount_amount' => 0,
- 'discount_percent' => 0,
- 'discount_tax_compensation_amount' => 0,
- ],
- ],
- ],
-];
diff --git a/Test/Integration/_files/scenarios/currency_conversion_rounding.php b/Test/Integration/_files/scenarios/currency_conversion_rounding.php
deleted file mode 100755
index 483cd9f8..00000000
--- a/Test/Integration/_files/scenarios/currency_conversion_rounding.php
+++ /dev/null
@@ -1,76 +0,0 @@
- [
- SetupUtil::CONFIG_OVERRIDES => $credentialsConfig,
- ],
- 'quote_data' => [
- 'billing_address' => [
- 'region_id' => SetupUtil::REGION_MI,
- ],
- 'shipping_address' => [
- 'region_id' => SetupUtil::REGION_MI,
- ],
- 'currency_rates' => [
- 'base_currency_code' => 'USD',
- 'quote_currency_code' => 'EUR',
- 'currency_conversion_rate' => 2,
- ],
- 'items' => [
- [
- 'type' => \Magento\Catalog\Model\Product\Type::TYPE_SIMPLE,
- 'sku' => 'simple1',
- 'price' => 9.90,
- 'qty' => 1,
- ],
- ],
- ],
- 'expected_results' => [
- 'compare_with_native_tax_calculation' => true,
- 'address_data' => [
- 'subtotal' => 19.8,
- 'base_subtotal' => 9.9,
- 'subtotal_incl_tax' => 19.8 + 1.19,
- 'base_subtotal_incl_tax' => 9.9 + 0.59,
- 'tax_amount' => 1.19,
- 'base_tax_amount' => 0.59,
- 'grand_total' => 19.8 + 1.19,
- 'base_grand_total' => 9.9 + 0.59,
- ],
- 'items_data' => [
- 'simple1' => [
- 'row_total' => 19.8,
- 'base_row_total' => 9.9,
- 'tax_percent' => 6.0,
- 'price' => 9.9, // It seems like this should be 19.8, but it's not. It's also 9.9 in native Magento.
- 'base_price' => 9.9,
- 'price_incl_tax' => 19.8 + 1.19, // 1.19 is 1.188 rounded up
- 'base_price_incl_tax' => 9.9 + 0.59, // 0.59 is .594 rounded down
- 'row_total_incl_tax' => 19.8 + 1.19,
- 'base_row_total_incl_tax' => 9.9 + 0.59,
- 'tax_amount' => 1.19,
- 'base_tax_amount' => 0.59,
- ],
- ],
- ],
-];
diff --git a/Test/Integration/_files/scenarios/customer_tax_class.php b/Test/Integration/_files/scenarios/customer_tax_class.php
deleted file mode 100755
index 518fdfcb..00000000
--- a/Test/Integration/_files/scenarios/customer_tax_class.php
+++ /dev/null
@@ -1,62 +0,0 @@
- [
- SetupUtil::CONFIG_OVERRIDES => $credentialsConfig,
- ],
- 'quote_data' => [
- 'customer_data' => [
- 'tax_class_name' => SetupUtil::CUSTOMER_TAX_CLASS_2_NON_PROFIT
- ],
- 'billing_address' => [
- 'region_id' => SetupUtil::REGION_MI,
- ],
- 'shipping_address' => [
- 'region_id' => SetupUtil::REGION_MI,
- ],
- 'items' => [
- [
- 'type' => \Magento\Catalog\Model\Product\Type::TYPE_SIMPLE,
- 'sku' => 'simple1',
- 'price' => 10,
- 'qty' => 1,
- ],
- ],
- ],
- 'expected_results' => [
- // Not comparing with native Magento since we'd have to setup associated tax rules in Magento
- 'compare_with_native_tax_calculation' => false,
- 'address_data' => [
- 'subtotal' => 10,
- 'subtotal_incl_tax' => 10,
- 'tax_amount' => 0,
- 'grand_total' => 10,
- ],
- 'items_data' => [
- 'simple1' => [
- 'row_total' => 10,
- 'tax_percent' => 6,
- 'price' => 10,
- 'price_incl_tax' => 10,
- 'row_total_incl_tax' => 10,
- 'tax_amount' => 0,
- ],
- ],
- ],
-];
diff --git a/Test/Integration/_files/scenarios/product_tax_classes.php b/Test/Integration/_files/scenarios/product_tax_classes.php
deleted file mode 100755
index 0d5832d8..00000000
--- a/Test/Integration/_files/scenarios/product_tax_classes.php
+++ /dev/null
@@ -1,74 +0,0 @@
- [
- SetupUtil::CONFIG_OVERRIDES => $credentialsConfig,
- ],
- 'quote_data' => [
- 'billing_address' => [
- 'region_id' => SetupUtil::REGION_MI,
- ],
- 'shipping_address' => [
- 'region_id' => SetupUtil::REGION_MI,
- ],
- 'items' => [
- [
- 'type' => \Magento\Catalog\Model\Product\Type::TYPE_SIMPLE,
- 'sku' => 'simple1',
- 'price' => 10,
- 'qty' => 1,
- ],
- [
- 'type' => \Magento\Catalog\Model\Product\Type::TYPE_SIMPLE,
- 'sku' => 'simple2_digital_good',
- 'price' => 10,
- 'qty' => 1,
- 'tax_class_name' => SetupUtil::PRODUCT_TAX_CLASS_3_DIGITAL_GOODS
- ],
- ],
- ],
- 'expected_results' => [
- // Not comparing with native Magento since we'd have to setup associated tax rules in Magento
- 'compare_with_native_tax_calculation' => false,
- 'address_data' => [
- 'subtotal' => 20,
- 'subtotal_incl_tax' => 20.6,
- 'tax_amount' => 0.6,
- 'grand_total' => 20.60,
- ],
- 'items_data' => [
- 'simple1' => [
- 'row_total' => 10,
- 'tax_percent' => 6.0,
- 'price' => 10,
- 'price_incl_tax' => 10.6,
- 'row_total_incl_tax' => 10.6,
- 'tax_amount' => 0.6,
- ],
- 'simple2_digital_good' => [
- 'row_total' => 10,
- 'tax_percent' => 6.0,
- 'price' => 10,
- 'price_incl_tax' => 10,
- 'row_total_incl_tax' => 10,
- 'tax_amount' => 0,
- ],
- ],
- ],
-];
diff --git a/Test/Integration/_files/scenarios/tax_before_discount_applies_to_partial_taxable_amount.php b/Test/Integration/_files/scenarios/tax_before_discount_applies_to_partial_taxable_amount.php
deleted file mode 100755
index 9ebf911f..00000000
--- a/Test/Integration/_files/scenarios/tax_before_discount_applies_to_partial_taxable_amount.php
+++ /dev/null
@@ -1,74 +0,0 @@
- '37243-9034',
- 'country_id' => SetupUtil::COUNTRY_US,
- 'city' => 'Nashville',
- 'street' => ['600 Charlotte Ave'],
- 'region_id' => 56, // Tennessee
-];
-
-/**
- * The purpose of this test is to verify the "$taxableAmountPercentage" functionality in
- * @see \ClassyLlama\AvaTax\Framework\Interaction\TaxCalculation::getTaxDetailsItem
- */
-$taxCalculationData['customer_tax_class'] = [
- 'config_data' => [
- SetupUtil::CONFIG_OVERRIDES => $credentialsConfig,
- ],
- 'quote_data' => [
- 'billing_address' => $tennesseeAddress,
- 'shipping_address' => $tennesseeAddress,
- 'shopping_cart_rules' => [
- [
- 'discount_amount' => 20,
- ],
- ],
- 'items' => [
- [
- 'type' => \Magento\Catalog\Model\Product\Type::TYPE_SIMPLE,
- 'sku' => 'simple1',
- 'price' => 10,
- 'qty' => 1,
- ],
- ],
- ],
- 'expected_results' => [
- 'compare_with_native_tax_calculation' => false,
- 'address_data' => [
- 'subtotal' => 10,
- 'subtotal_incl_tax' => 10.71, // If functionality is broken, it will return 10.76
- 'tax_amount' => 0.56999999999999995,
- 'grand_total' => 8.57,
- ],
- 'items_data' => [
- 'simple1' => [
- 'row_total' => 10,
- 'tax_percent' => 9.25,
- 'price' => 10,
- 'price_incl_tax' => 10.71, // If functionality is broken, it will return 10.76
- 'row_total_incl_tax' => 10.71, // If functionality is broken, it will return 10.76
- 'tax_amount' => 0.56999999999999995,
-
- 'discount_amount' => 2,
- 'tax_before_discount' => 0,
- ],
- ],
- ],
-];
diff --git a/Test/Integration/_files/scenarios/tax_before_discount_only_applies_to_taxable_amount.php b/Test/Integration/_files/scenarios/tax_before_discount_only_applies_to_taxable_amount.php
deleted file mode 100755
index 3797f749..00000000
--- a/Test/Integration/_files/scenarios/tax_before_discount_only_applies_to_taxable_amount.php
+++ /dev/null
@@ -1,69 +0,0 @@
- [
- SetupUtil::CONFIG_OVERRIDES => $credentialsConfig,
- ],
- 'quote_data' => [
- 'customer_data' => [
- 'tax_class_name' => SetupUtil::CUSTOMER_TAX_CLASS_2_NON_PROFIT
- ],
- 'billing_address' => [
- 'region_id' => SetupUtil::REGION_MI,
- ],
- 'shipping_address' => [
- 'region_id' => SetupUtil::REGION_MI,
- ],
- 'shopping_cart_rules' => [
- [
- 'discount_amount' => 20,
- ],
- ],
- 'items' => [
- [
- 'type' => \Magento\Catalog\Model\Product\Type::TYPE_SIMPLE,
- 'sku' => 'simple1',
- 'price' => 10,
- 'qty' => 1,
- ],
- ],
- ],
- 'expected_results' => [
- 'compare_with_native_tax_calculation' => false,
- 'address_data' => [
- 'subtotal' => 10,
- 'subtotal_incl_tax' => 10,
- 'tax_amount' => 0,
- 'grand_total' => 8,
- ],
- 'items_data' => [
- 'simple1' => [
- 'row_total' => 10,
- 'tax_percent' => 6,
- 'price' => 10,
- 'price_incl_tax' => 10,
- 'row_total_incl_tax' => 10,
- 'tax_amount' => 0,
-
- 'discount_amount' => 2,
- 'tax_before_discount' => 0,
- ],
- ],
- ],
-];
diff --git a/Test/Integration/_files/tax_calculation_data_aggregated.php b/Test/Integration/_files/tax_calculation_data_aggregated.php
deleted file mode 100755
index ec2b442f..00000000
--- a/Test/Integration/_files/tax_calculation_data_aggregated.php
+++ /dev/null
@@ -1,42 +0,0 @@
- 1,
- Config::XML_PATH_AVATAX_LIVE_MODE => 0,
- Config::XML_PATH_AVATAX_DEVELOPMENT_COMPANY_CODE => 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX',
- Config::XML_PATH_AVATAX_DEVELOPMENT_ACCOUNT_NUMBER => 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX',
- Config::XML_PATH_AVATAX_DEVELOPMENT_LICENSE_KEY => 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX',
-];
diff --git a/Test/Integration/phpunit.xml b/Test/Integration/phpunit.xml
deleted file mode 100755
index b82a62b0..00000000
--- a/Test/Integration/phpunit.xml
+++ /dev/null
@@ -1,67 +0,0 @@
-
-
-
-
-
-
- testsuite/Magento/MemoryUsageTest.php
-
-
- ./
-
-
-
-
-
- ../*
-
- ./
-
-
-
-
-
- .
- ../../../../../dev/tests/integration
- testsuite
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/Test/README.md b/Test/README.md
deleted file mode 100755
index 317283f1..00000000
--- a/Test/README.md
+++ /dev/null
@@ -1,53 +0,0 @@
-# General
-
-This document assumes this extension has been installed via Composer and resides in `vendor/classyllama/module-avatax`.
-
-# Test Coverage
-
-The integration tests cover two things:
-
-1. Build multiple quotes and request AvaTax tax rates for the quotes. The rates are then applied to the quotes and the values on the quote and quote items are verified against the "expected_results" arrays in the `vendor/classyllama/module-avatax/Tests/Integration/_files/scenarios/*.php` files to ensure they contain the proper values.
-
-2. Since Magento may change how tax rates are applied to quotes and quote items, there are also tests in place that compare quotes/quote items after running through AvaTax tax calculation vs native Magento tax calculation. Scenarios with "compare_with_native_tax_calculation" set to true are compared to native Magento tax calculation. The following properties are using for determining which fields to compare:
- * `\ClassyLlama\AvaTax\Tests\Integration\Model\Tax\Sales\Total\Quote\TaxTest::$quoteAddressFieldsEnsureMatch`
- * `\ClassyLlama\AvaTax\Tests\Integration\Model\Tax\Sales\Total\Quote\TaxTest::$quoteAddressFieldsEnsureDiff`
- * `\ClassyLlama\AvaTax\Tests\Integration\Model\Tax\Sales\Total\Quote\TaxTest::$quoteItemFieldsEnsureMatch`
-
-The following scenarios are tested:
-
-* Quote with a single applied rate
-* Quote with multiple applied rates
-* Simple products
-* Bundled products with dynamic pricing
-* Bundled products with simple pricing
-* Configurable products
-* Currency conversion, including rounding accuracy
-* Customer tax classes (customer use types)
-* Product tax classes (tax codes)
-* Discounts
-* Tax on shipping
-
-# AvaTax Admin Configuration
-
-The integration tests assume the following information has been configured in the AvaTax admin:
-
-1. These tax jurisdictions have been setup:
- * Michigan (it has a 6% flat sales tax)
- * San Diego, California (we've used the San Diego Zoo: 2920 Zoo Dr, San Diego CA 92101, US)
- * Tennessee (it has a 9.25% flat sales tax)
-2. A "D0000000" Tax Code has been created and an associated Tax Rule has been created that marks that Tax Code as tax exempt for the Michigan tax jurisdiction.
-3. A "Base Override" Tax Rule has been created that changes Tennessee tax to 77% of the taxable amount
-
-# Running Integration Tests
-
-Follow these steps to run the integration tests:
-
-1. Create a database for the integration tests (such as "magento_integration_tests")
-
- 1. Update the `dev/tests/integration/etc/install-config-mysql.php.dist` file with your MySQL credentials.
-
-1. You'll need an AvaTax development account setup with the rules specified in `vendor/classyllama/module-avatax/Tests/Integration/credentials.php.dist`
-
- 1. Copy the `vendor/classyllama/module-avatax/Tests/Integration/credentials.php.dist` file to `vendor/classyllama/module-avatax/Tests/Integration/credentials.php` and update the "Company Code", "Account Number", and "License Key" values
-
-1. Run the integration tests using this command: `vendor/bin/phpunit --debug -c /vendor/classyllama/module-avatax/Tests/Integration/phpunit.xml`
diff --git a/Test/Unit/Framework/Interaction/Request/AddressBuilderTest.php b/Test/Unit/Framework/Interaction/Request/AddressBuilderTest.php
deleted file mode 100644
index 4b5684ef..00000000
--- a/Test/Unit/Framework/Interaction/Request/AddressBuilderTest.php
+++ /dev/null
@@ -1,185 +0,0 @@
-objectManager = new ObjectManager($this);
- $this->avaTaxLoggerMock = $this->createMock(AvaTaxLogger::class);
- $this->avaTaxHelperRestConfigMock = $this->createMock(AvaTaxHelperRestConfig::class);
- $this->interactionAddressMock = $this->createMock(InteractionAddress::class);
- $this->frameworkInteractionAddressMock = $this->createMock(FrameworkInteractionAddress::class);
- $this->avataxHelperConfigMock = $this->createMock(AvaTaxHelperConfig::class);
- $this->orderMock = $this->createMock(Order::class);
- $this->orderAddressMock = $this->getMockForAbstractClass(OrderAddress::class);
- $this->addressBuilder = $this->objectManager->getObject(AddressBuilder::class, [
- 'avaTaxLogger' => $this->avaTaxLoggerMock,
- 'avaTaxHelperRestConfig' => $this->avaTaxHelperRestConfigMock,
- 'interactionAddress' => $this->interactionAddressMock,
- 'frameworkInteractionAddress' => $this->frameworkInteractionAddressMock,
- 'avataxHelperConfig' => $this->avataxHelperConfigMock
- ]);
- }
-
- /**
- * @test
- * @covers \ClassyLlama\AvaTax\Framework\Interaction\Request\AddressBuilder::build
- */
- public function checkThatWeGetTheCorrectResponseType()
- {
- $storeId = 1;
- $mockData = $this->getMockData();
- $originMockAddress = array_shift($mockData);
- $addressTypeTo = array_pop($mockData);
-
- $this->orderMock->expects(static::atLeastOnce())
- ->method('getIsVirtual')
- ->willReturn(false);
- $this->orderMock->expects(static::once())
- ->method('getShippingAddress')
- ->willReturn($this->orderAddressMock);
- $this->interactionAddressMock->expects(static::once())
- ->method('getAddress')
- ->with($this->orderAddressMock)
- ->willReturn(new \Magento\Framework\DataObject($addressTypeTo));
- $this->avataxHelperConfigMock->expects(static::atLeastOnce())
- ->method('getOriginAddress')
- ->with($storeId)
- ->willReturn($originMockAddress);
- $this->frameworkInteractionAddressMock->expects(static::atLeastOnce())
- ->method('getAddress')
- ->with($originMockAddress)
- ->willReturn(new \Magento\Framework\DataObject($originMockAddress));
- $this->avaTaxHelperRestConfigMock->expects(static::once())
- ->method('getAddrTypeTo')
- ->willReturn(\Avalara\TransactionAddressType::C_SHIPTO);
- $this->avaTaxHelperRestConfigMock->expects(static::once())
- ->method('getAddrTypeFrom')
- ->willReturn(\Avalara\TransactionAddressType::C_SHIPFROM);
-
-
- /** @var array $addresses */
- $addresses = $this->addressBuilder->build($this->orderMock, $storeId);
-
- $this->assertArrayHasKey(\Avalara\TransactionAddressType::C_SHIPTO, $addresses);
- $this->assertArrayHasKey(\Avalara\TransactionAddressType::C_SHIPFROM, $addresses);
- $this->assertCount(2, $addresses);
- $this->assertInternalType('array', $addresses);
- $this->assertInstanceOf(\Magento\Framework\DataObject::class, $addresses[\Avalara\TransactionAddressType::C_SHIPTO]);
- $this->assertInstanceOf(\Magento\Framework\DataObject::class, $addresses[\Avalara\TransactionAddressType::C_SHIPFROM]);
- }
-
- /**
- * @test
- * @covers \ClassyLlama\AvaTax\Framework\Interaction\Request\AddressBuilder::build
- */
- public function checkThatWeGetAnEmptyArrayEvenIfAnExceptionWillBeThrown()
- {
- $storeId = 1;
- $message = 'something went wrong';
- $exception = new \Exception($message);
-
- $this->orderMock->expects(static::once())
- ->method('getIsVirtual')
- ->willThrowException($exception);
-
- /** @var array $addresses */
- $addresses = $this->addressBuilder->build($this->orderMock, $storeId);
-
- $this->assertCount(0, $addresses);
- $this->assertInternalType('array', $addresses);
- }
-
- /**
- * Get mock data
- *
- * @return array
- */
- private function getMockData(): array
- {
- return [
- [
- 'line_1' => null,
- 'line_2' => null,
- 'city' => null,
- 'region_id' => '12',
- 'postal_code' => '90034',
- 'country' => 'US'
- ],
- [
- 'line_1' => '900 Winslow Way E',
- 'line_2' => '',
- 'line_3' => '',
- 'city' => 'Bainbridge Island',
- 'region' => 'WA',
- 'postal_code' => '98110-2450',
- 'country' => 'US'
- ]
- ];
- }
-}
diff --git a/Test/Unit/Framework/Interaction/Request/TaxCompositeTest.php b/Test/Unit/Framework/Interaction/Request/TaxCompositeTest.php
deleted file mode 100644
index 466d4f81..00000000
--- a/Test/Unit/Framework/Interaction/Request/TaxCompositeTest.php
+++ /dev/null
@@ -1,173 +0,0 @@
-objectManager = new ObjectManager($this);
- $this->resultStorageMock = $this->createMock(ResultStorage::class);
- $this->loggerMock = $this->getMockForAbstractClass(LoggerInterface::class);
- $this->dataObjectFactoryMock = $this->getMockBuilder(DataObjectFactory::class)
- ->disableOriginalConstructor()
- ->getMock();
- $this->clientPoolMock = $this->createMock(ClientPool::class);
- $this->transactionBuilderFactoryMock = $this->getMockBuilder(TransactionBuilderFactory::class)
- ->disableOriginalConstructor()
- ->getMock();
- $this->taxResultFactoryMock = $this->getMockBuilder(TaxResultFactory::class)
- ->disableOriginalConstructor()
- ->getMock();
- $this->restConfigMock = $this->createMock(RestConfig::class);
- $this->customsConfigMock = $this->createMock(CustomsConfig::class);
- $this->requestInterfaceMock = $this->getMockBuilder(RequestInterface::class)
- ->disableOriginalConstructor()
- ->setMethods(['hasData', 'unsetData'])
- ->getMock();
- $this->taxComposite = $this->objectManager->getObject(TaxComposite::class, [
- 'resultStorage' => $this->resultStorageMock,
- 'logger' => $this->loggerMock,
- 'dataObjectFactory' => $this->dataObjectFactoryMock,
- 'clientPool' => $this->clientPoolMock,
- 'transactionBuilderFactory' => $this->transactionBuilderFactoryMock,
- 'taxResultFactory' => $this->taxResultFactoryMock,
- 'restConfig' => $this->restConfigMock,
- 'customsConfigHelper' => $this->customsConfigMock
- ]);
- }
-
- /**
- * @test
- * @covers \ClassyLlama\AvaTax\Framework\Interaction\Request\TaxComposite::calculateTax
- */
- public function checkThatWeGetCorrectResponseWithTaxesFromTheCache()
- {
- $storeId = 1;
-
- /** @var \Magento\Framework\DataObject $taxes */
- $taxes = new RestTaxResult($this->getMockData());
-
- $this->requestInterfaceMock->expects(static::atLeastOnce())
- ->method('hasData')
- ->with('code')
- ->willReturn(true);
- $this->requestInterfaceMock->expects(static::atLeastOnce())
- ->method('unsetData')
- ->with('code')
- ->willReturnSelf();
- $this->resultStorageMock->expects(static::atLeastOnce())
- ->method('find')
- ->willReturn($taxes);
-
- /** @var RestTaxResult $collectedTaxes */
- $collectedTaxes = $this->taxComposite->calculateTax(
- $this->requestInterfaceMock,
- $storeId,
- ScopeInterface::SCOPE_STORE,
- [RestTaxInterface::FLAG_FORCE_NEW_RATES => true],
- null
- );
-
- $this->assertInstanceOf(RestTaxResult::class, $collectedTaxes);
- $this->assertInternalType('object', $collectedTaxes);
- $this->assertArrayHasKey('cache', $collectedTaxes->getData());
- $this->assertArrayHasKey('total_tax', $collectedTaxes->getData());
- $this->assertArrayHasKey('total_tax_calculated', $collectedTaxes->getData());
- }
-
- /**
- * Get mock data
- *
- * @return array
- */
- private function getMockData(): array
- {
- return [
- 'total_amount' => -158.0,
- 'total_tax' => -14.24,
- 'total_taxable' => -158.0,
- 'total_tax_calculated' => -14.24,
- 'creation_timestamp' => 1568901642,
- 'cache' => true
- ];
- }
-}
diff --git a/Test/Unit/Framework/Interaction/Storage/ConfigTest.php b/Test/Unit/Framework/Interaction/Storage/ConfigTest.php
deleted file mode 100644
index 483e096c..00000000
--- a/Test/Unit/Framework/Interaction/Storage/ConfigTest.php
+++ /dev/null
@@ -1,72 +0,0 @@
-objectManager = new ObjectManager($this);
- $this->scopeConfigMock = $this->getMockForAbstractClass(ScopeConfigInterface::class);
-
- $this->storageConfig = $this->objectManager->getObject(StorageConfig::class, [
- 'scopeConfig' => $this->scopeConfigMock
- ]);
- }
-
- /**
- * @test
- * @covers \ClassyLlama\AvaTax\Framework\Interaction\Storage\Config::getResultCacheTtl
- * @dataProvider dataProvider
- */
- public function checkThatWeGetCorrectCacheTtlValue($storageTime)
- {
- $this->scopeConfigMock->expects(static::once())
- ->method('getValue')
- ->with(StorageConfig::RESULT_CACHE_TTL)
- ->willReturn($storageTime);
-
- $result = $this->storageConfig->getResultCacheTtl();
- $this->assertSame($result, $storageTime);
- $this->assertInternalType('int', $result);
- }
-
- /**
- * @return array
- */
- public function dataProvider(): array
- {
- return [
- [15],
- [10],
- [25]
- ];
- }
-}
diff --git a/Test/Unit/Framework/Interaction/Storage/SessionTest.php b/Test/Unit/Framework/Interaction/Storage/SessionTest.php
deleted file mode 100644
index fb304a93..00000000
--- a/Test/Unit/Framework/Interaction/Storage/SessionTest.php
+++ /dev/null
@@ -1,112 +0,0 @@
-objectManager = new ObjectManager($this);
- $this->storageSession = $this->objectManager->getObject(StorageSession::class);
-
- $this->storageMock = $this->getMockBuilder(Storage::class)
- ->disableOriginalConstructor()
- ->setMethods(['getData','setData'])
- ->getMock();
-
- $this->objectManager->setBackwardCompatibleProperty(
- $this->storageSession,
- 'storage',
- $this->storageMock
- );
- }
-
- /**
- * @test
- * @covers \ClassyLlama\AvaTax\Framework\Interaction\Storage\Session::getResults
- */
- public function checkThatWeCanGetResultsFromTheSessionCache()
- {
- /** @var array $storageData */
- $storageData = $this->getMockData();
-
- $this->storageMock->expects(static::atLeastOnce())
- ->method('getData')
- ->with($this->namespace)
- ->willReturn($storageData);
-
- /** @var array $cacheResult */
- $cacheResult = $this->storageSession->getResults($this->namespace);
- $this->assertSame($cacheResult, $storageData);
- $this->assertArrayHasKey('storage_data', $cacheResult);
-
- $cacheResultNoNamespace = $this->storageSession->getResults('');
- $this->assertSame($cacheResultNoNamespace, []);
- $this->assertArrayNotHasKey('storage_data', $cacheResultNoNamespace);
- }
-
- /**
- * @test
- * @covers \ClassyLlama\AvaTax\Framework\Interaction\Storage\Session::setResults
- */
- public function checkThatWeCanSetResultsIntoTheSessionCache()
- {
- /** @var array $storageData */
- $storageData = $this->getMockData();
-
- $this->storageMock->expects(static::atLeastOnce())
- ->method('setData')
- ->with($this->namespace, $storageData)
- ->willReturnSelf();
-
- /** @var StorageSession $setCacheResults */
- $setCacheResults = $this->storageSession->setResults($this->namespace, $storageData);
- $this->assertInstanceOf(StorageSession::class, $setCacheResults);
-
- /** @var StorageSession $setCacheResultsNoNamespace */
- $setCacheResultsNoNamespace = $this->storageSession->setResults('', $storageData);
- $this->assertInstanceOf(StorageSession::class, $setCacheResultsNoNamespace);
- }
-
- /**
- * @return array
- */
- private function getMockData(): array
- {
- return [
- 'storage_data' => 'some data'
- ];
- }
-}
diff --git a/Test/Unit/Model/CertificatesTest.php b/Test/Unit/Model/CertificatesTest.php
deleted file mode 100755
index dbc9ef9d..00000000
--- a/Test/Unit/Model/CertificatesTest.php
+++ /dev/null
@@ -1,188 +0,0 @@
-objectManager = new ObjectManager($this);
- $this->authSessionMock = $this->createMock(AuthSession::class);
- $this->certificateHelperMock = $this->createMock(CertificateHelper::class);
- $this->avaTaxLoggerMock = $this->createMock(AvaTaxLogger::class);
- $this->certificates = $this->objectManager->getObject(Certificates::class, [
- 'authSession' => $this->authSessionMock,
- 'certificateHelper' => $this->certificateHelperMock,
- 'avaTaxLogger' => $this->avaTaxLoggerMock
- ]);
- }
-
- /**
- * @test
- * @covers \ClassyLlama\AvaTax\Model\Certificates::getCertificatesList
- */
- public function checkCorrectReturnTypeWhileGettingCertificatesList()
- {
- $userId = 1;
- $viewUrl = 'example/view_url';
- $deleteUrl = 'example/delete_url';
-
- $this->certificateHelperMock->expects(static::atLeastOnce())
- ->method('getCertificates')
- ->willReturn($this->getMockData());
- $this->certificateHelperMock->expects(static::atLeastOnce())
- ->method('getCertificateUrl')
- ->willReturn($viewUrl);
- $this->certificateHelperMock->expects(static::atLeastOnce())
- ->method('getCertificateDeleteUrl')
- ->willReturn($deleteUrl);
-
- /** @var array $result */
- $result = $this->certificates->getCertificatesList($userId);
-
- $this->assertInternalType('array', $result);
- $this->assertCount(2, $result);
- $this->assertInstanceOf(DataObject::class, $result[0]);
- $this->assertInstanceOf(DataObject::class, $result[1]);
- $this->assertSame($viewUrl, $result[0]->getData('certificate_url'));
- $this->assertSame($deleteUrl, $result[0]->getData('certificate_delete_url'));
- $this->assertSame($viewUrl, $result[1]->getData('certificate_url'));
- $this->assertSame($deleteUrl, $result[1]->getData('certificate_delete_url'));
- }
-
- /**
- * @test
- * @covers \ClassyLlama\AvaTax\Model\Certificates::getCertificatesList
- */
- public function checkCorrectReturnTypeInCaseOfError()
- {
- $userId = 1;
-
- $this->certificateHelperMock->expects(static::atLeastOnce())
- ->method('getCertificates')
- ->willThrowException(new \Exception('Error happened'));
-
- /** @var array $result */
- $result = $this->certificates->getCertificatesList($userId);
-
- $this->assertInternalType('array', $result);
- $this->assertCount(0, $result);
- }
-
- /**
- * Get mock data
- *
- * @return array
- */
- public function getMockData(): array
- {
- return [
- new DataObject([
- 'id' => 5,
- 'company_id' => 170111,
- 'signed_date' => '2018-04-23',
- 'expiration_date' => '2021-04-23',
- 'filename' => '71011_auto_5.pdf',
- 'document_exists' => true,
- 'valid' => true,
- 'verified' => false,
- 'exempt_percentage' => 100.0,
- 'is_single_certificate' => false,
- 'exemption_number' => '388383838383',
- 'validated_exemption_reason' => new DataObject([
- 'id' => 71,
- 'name' => 'RESALE'
- ]),
- 'exemption_reason' => new DataObject([
- 'id' => 71,
- 'name' => 'RESALE'
- ]),
- 'status' => 'COMPLETE',
- 'created_date' => '2018-04-23T20:49:40.860677',
- 'modified_date' => '2018-06-08',
- 'page_count' => 0,
- 'exposure_zone' => new DataObject([
- 'id' => 127,
- 'name' => 'Idaho',
- 'tag' => 'EZ_US_ID',
- 'description' => 'Idaho Sales Tax',
- 'region' => 'ID',
- 'country' => 'US'
- ])
- ]),
- new DataObject([
- 'id' => 35,
- 'company_id' => 170111,
- 'signed_date' => '2018-07-04',
- 'expiration_date' => '2021-07-04',
- 'filename' => '71011_auto_35.pdf',
- 'document_exists' => true,
- 'valid' => true,
- 'verified' => false,
- 'exempt_percentage' => 100.0,
- 'is_single_certificate' => false,
- 'exemption_number' => 'asd',
- 'validated_exemption_reason' => new DataObject([
- 'id' => 71,
- 'name' => 'RESALE'
- ]),
- 'exemption_reason' => new DataObject([
- 'id' => 71,
- 'name' => 'RESALE'
- ]),
- 'status' => 'COMPLETE',
- 'created_date' => '2018-07-04T08:49:35.232304',
- 'modified_date' => '2018-07-04',
- 'page_count' => 1,
- 'exposure_zone' => new DataObject([
- 'id' => 127,
- 'name' => 'Idaho',
- 'tag' => 'EZ_US_ID',
- 'description' => 'Idaho Sales Tax',
- 'region' => 'ID',
- 'country' => 'US'
- ])
- ])
- ];
- }
-}
diff --git a/Test/Unit/Model/Customer/CustomerUpdateTest.php b/Test/Unit/Model/Customer/CustomerUpdateTest.php
deleted file mode 100644
index 7bd153ea..00000000
--- a/Test/Unit/Model/Customer/CustomerUpdateTest.php
+++ /dev/null
@@ -1,155 +0,0 @@
-objectManager = new ObjectManager($this);
- $this->loggerMock = $this->createMock(AvaTaxLogger::class);
- $this->customerUpdateResultsMock = $this->createMock(CustomerUpdateResults::class);
- $this->customerRepositoryMock = $this->getMockForAbstractClass(CustomerRepositoryInterface::class);
- $this->avalaraCustomerUpdateServiceMock = $this->createMock(AvalaraCustomerUpdateService::class);
- $this->customerMock = $this->createMock(Customer::class);
-
- $this->customerUpdate = $this->objectManager->getObject(CustomerUpdate::class, [
- 'logger' => $this->loggerMock,
- 'customerUpdateResults' => $this->customerUpdateResultsMock,
- 'customerRepository' => $this->customerRepositoryMock,
- 'avalaraCustomerUpdateService' => $this->avalaraCustomerUpdateServiceMock
- ]);
- $this->objectManager->setBackwardCompatibleProperty(
- $this->customerUpdate,
- 'customerUpdateResults',
- new \Magento\Framework\DataObject()
- );
- }
-
- /**
- * @test
- * @covers \ClassyLlama\AvaTax\Model\Customer\CustomerUpdate::prepareAvalaraServiceResponse
- */
- public function checkCorrectReturnTypeForPrepareAvalaraServiceResponseMethod()
- {
- $successMessage = 'Success message';
- $errorStatus = false;
-
- $result = $this->invokeMethod($this->customerUpdate, 'prepareAvalaraServiceResponse', [
- 'errorStatus' => $errorStatus,
- 'message' => $successMessage
- ]);
-
- static::assertInstanceOf(CustomerUpdateInterface::class, $result);
- static::assertSame($successMessage, $result->customerUpdateResults->getResult()['message']);
- static::assertSame($errorStatus, $result->customerUpdateResults->getResult()['error_status']);
- }
-
- /**
- * @test
- * @covers \ClassyLlama\AvaTax\Model\Customer\CustomerUpdate::updateCustomerInformation
- */
- public function checkCorrectReturnTypeForUpdateCustomerInformationMethod()
- {
- $customerId = 1;
- $storeId = 8;
- $successMessage = 'success';
- $errorStatus = false;
- $responseData = new \Magento\Framework\DataObject([
- 'id' => 99,
- 'company_id' => 170111,
- 'customer_code' => "3",
- 'name' => 'avalara customer name',
- 'line_1' => '5th Ave',
- 'line_2' => '',
- 'city' => 'New York',
- 'email_address' => 'email@example.com'
- ]);
-
- $this->customerRepositoryMock->expects(static::atLeastOnce())
- ->method('getById')
- ->willReturn($this->customerMock);
- $this->customerMock->expects(static::atLeastOnce())
- ->method('getStoreId')
- ->willReturn($storeId);
- $this->avalaraCustomerUpdateServiceMock->expects(static::atLeastOnce())
- ->method('updateCustomer')
- ->willReturn($responseData);
-
- $result = $this->customerUpdate->updateCustomerInformation($customerId);
-
- static::assertInstanceOf(CustomerUpdateInterface::class, $result);
- static::assertSame($successMessage, $result->customerUpdateResults->getResult()['message']);
- static::assertSame($errorStatus, $result->customerUpdateResults->getResult()['error_status']);
- }
-
- /**
- * Call protected/private method of a class
- *
- * @param $object
- * @param string $methodName
- * @param array $parameters
- * @return mixed
- * @throws \ReflectionException
- */
- private function invokeMethod(&$object, string $methodName, array $parameters = [])
- {
- $reflection = new \ReflectionClass(get_class($object));
- $method = $reflection->getMethod($methodName);
- $method->setAccessible(true);
-
- return $method->invokeArgs($object, $parameters);
- }
-}
diff --git a/Test/Unit/Model/Order/Creditmemo/Total/AvataxAdjustmentTaxesTest.php b/Test/Unit/Model/Order/Creditmemo/Total/AvataxAdjustmentTaxesTest.php
deleted file mode 100644
index d99ba50a..00000000
--- a/Test/Unit/Model/Order/Creditmemo/Total/AvataxAdjustmentTaxesTest.php
+++ /dev/null
@@ -1,335 +0,0 @@
-objectManager = new ObjectManager($this);
- $this->avataxLoggerMock = $this->createMock(AvaTaxLogger::class);
- $this->taxCompositeInterfaceMock = $this->getMockForAbstractClass(TaxCompositeInterface::class);
- $this->creditmemoRequestBuilderMock = $this->createMock(CreditmemoRequestBuilder::class);
- $this->storeManagerMock = $this->getMockForAbstractClass(StoreManagerInterface::class);
- $this->scopeConfigMock = $this->getMockForAbstractClass(ScopeConfigInterface::class);
- $this->storeInterfaceMock = $this->getMockForAbstractClass(StoreInterface::class);
- $this->creditmemoMock = $this->getMockBuilder(Creditmemo::class)
- ->disableOriginalConstructor()
- ->setMethods(['getBaseAdjustmentPositive', 'getBaseAdjustmentNegative', 'getStoreId', 'getTaxAmount', 'getBaseTaxAmount'])
- ->getMock();
-
- $this->avataxAdjustmentTaxes = $this->objectManager->getObject(AvataxAdjustmentTaxes::class, [
- 'avataxLogger' => $this->avataxLoggerMock,
- 'taxCompositeService' => $this->taxCompositeInterfaceMock,
- 'creditmemoRequestBuilder' => $this->creditmemoRequestBuilderMock,
- 'storeManager' => $this->storeManagerMock,
- 'scopeConfig' => $this->scopeConfigMock,
- 'data' => []
- ]);
- }
-
- /**
- * @test
- * @covers \ClassyLlama\AvaTax\Model\Order\Creditmemo\Total\AvataxAdjustmentTaxes::isTaxCalculationEnabledForAdjustments
- * @throws \ReflectionException
- */
- public function checkCorrectReturnTypeForisTaxCalculationEnabledForAdjustmentsMethod()
- {
- $storeId = 1;
-
- $this->storeManagerMock->expects(static::atLeastOnce())
- ->method('getStore')
- ->willReturn($this->storeInterfaceMock);
- $this->storeInterfaceMock->expects(static::once())
- ->method('getId')
- ->willReturn($storeId);
- $this->scopeConfigMock->expects(static::atLeastOnce())
- ->method('getValue')
- ->with(AvataxAdjustmentTaxes::ADJUSTMENTS_CONFIG_PATH, ScopeConfigInterface::SCOPE_TYPE_DEFAULT, $storeId)
- ->willReturn($storeId);
-
- /** @var bool $result */
- $result = $this->invokeMethod($this->avataxAdjustmentTaxes, 'isTaxCalculationEnabledForAdjustments');
-
- $this->assertTrue($result);
- $this->assertInternalType('bool', $result);
- }
-
- /**
- * @test
- * @covers \ClassyLlama\AvaTax\Model\Order\Creditmemo\Total\AvataxAdjustmentTaxes::isTaxCalculationEnabledForAdjustments
- * @throws \ReflectionException
- */
- public function checkCorrectReturnTypeForisTaxCalculationEnabledForAdjustmentsMethodInCaseOfError()
- {
- $storeId = 1;
- $message = 'error happened';
-
- $this->storeManagerMock->expects(static::atLeastOnce())
- ->method('getStore')
- ->willReturn($this->storeInterfaceMock);
- $this->storeInterfaceMock->expects(static::atLeastOnce())
- ->method('getId')
- ->willReturn($storeId);
- $this->scopeConfigMock->expects($this->once())
- ->method('getValue')
- ->with(AvataxAdjustmentTaxes::ADJUSTMENTS_CONFIG_PATH, ScopeConfigInterface::SCOPE_TYPE_DEFAULT, $storeId)
- ->willThrowException(new \Exception($message));
-
- /** @var bool $result */
- $result = $this->invokeMethod($this->avataxAdjustmentTaxes, 'isTaxCalculationEnabledForAdjustments');
-
- $this->assertFalse($result);
- $this->assertInternalType('bool', $result);
- }
-
- /**
- * @test
- * @covers \ClassyLlama\AvaTax\Model\Order\Creditmemo\Total\AvataxAdjustmentTaxes::getCreditmemoTaxesForAdjustments
- * @throws \ReflectionException
- */
- public function checkThatWeGetCorrectEstimatedAdjustmentRefundAndAdjustmentFeeTaxes()
- {
- /** @var array $lines */
- $lines = [
- new DataObject([
- 'description' => 'Chaz Kangeroo Hoodie',
- 'tax' => -0.9
- ]),
- new DataObject([
- 'description' => 'Adjustment refund',
- 'tax' => -0,41
- ]),
- new DataObject([
- 'description' => 'Adjustment fee',
- 'tax' => 0.83
- ])
- ];
- /** @var RestTaxResult $response */
- $response = new RestTaxResult(['lines' => $lines]);
-
- $result = $this->invokeMethod($this->avataxAdjustmentTaxes, 'getCreditmemoTaxesForAdjustments', [$response]);
-
- $this->assertInternalType('array', $result);
- $this->assertCount(2, $result);
- $this->assertArrayHasKey('adjustment_refund', $result);
- $this->assertArrayHasKey('adjustment_fee', $result);
- $this->assertInternalType('object', $result['adjustment_refund']);
- $this->assertInternalType('object', $result['adjustment_fee']);
- $this->assertInstanceOf(DataObject::class, $result['adjustment_refund']);
- $this->assertInstanceOf(DataObject::class, $result['adjustment_fee']);
- }
-
- /**
- * @test
- * @covers \ClassyLlama\AvaTax\Model\Order\Creditmemo\Total\AvataxAdjustmentTaxes::getCreditmemoTaxesForAdjustments
- * @throws \ReflectionException
- */
- public function checkThatWeGetCorrectResponseInCaseOfNullInputParameter()
- {
- $response = null;
-
- /** @var array $result */
- $result = $this->invokeMethod($this->avataxAdjustmentTaxes, 'getCreditmemoTaxesForAdjustments', [$response]);
-
- $this->assertCount(0 ,$result);
- $this->assertInternalType('array', $result);
- }
-
- /**
- * @test
- * @covers \ClassyLlama\AvaTax\Model\Order\Creditmemo\Total\AvataxAdjustmentTaxes::collect
- */
- public function checkThatWeDoNotSetAdjustmentsTaxesForCreditmemoInCaseItIsNotEnabled()
- {
- $storeId = 1;
-
- $this->storeManagerMock->expects(static::atLeastOnce())
- ->method('getStore')
- ->willReturn($this->storeInterfaceMock);
- $this->storeInterfaceMock->expects(static::atLeastOnce())
- ->method('getId')
- ->willReturn($storeId);
- $this->scopeConfigMock->expects(static::once())
- ->method('getValue')
- ->with(AvataxAdjustmentTaxes::ADJUSTMENTS_CONFIG_PATH, ScopeConfigInterface::SCOPE_TYPE_DEFAULT, $storeId)
- ->willReturn(false);
-
- /** @var Creditmemo $result */
- $result = $this->avataxAdjustmentTaxes->collect($this->creditmemoMock);
-
- $this->assertInternalType('object', $result);
- $this->assertInstanceOf(AvataxAdjustmentTaxes::class, $result);
- $this->assertCount(0, $result->getData());
- }
-
- /**
- * @test
- * @covers \ClassyLlama\AvaTax\Model\Order\Creditmemo\Total\AvataxAdjustmentTaxes::collect
- */
- public function checkThatWeGetCorrectCalculatedAdjustmentsTaxesForCreditmemo()
- {
- $storeId = 1;
- $baseAdjustmentPositive = 5;
-
- // \ClassyLlama\AvaTax\Model\Order\Creditmemo\Total\AvataxAdjustmentTaxes::isTaxCalculationEnabledForAdjustments
- $this->storeManagerMock->expects(static::atLeastOnce())
- ->method('getStore')
- ->willReturn($this->storeInterfaceMock);
- $this->storeInterfaceMock->expects(static::atLeastOnce())
- ->method('getId')
- ->willReturn($storeId);
- $this->scopeConfigMock->expects(static::once())
- ->method('getValue')
- ->with(AvataxAdjustmentTaxes::ADJUSTMENTS_CONFIG_PATH, ScopeConfigInterface::SCOPE_TYPE_DEFAULT, $storeId)
- ->willReturn(true);
-
- // \ClassyLlama\AvaTax\Model\Order\Creditmemo\Total\AvataxAdjustmentTaxes::adjustmentsAreNotEmpty
- $this->creditmemoMock->expects(static::atLeastOnce())
- ->method('getBaseAdjustmentPositive')
- ->willReturn($baseAdjustmentPositive);
- $this->creditmemoMock->expects(static::never())
- ->method('getBaseAdjustmentNegative');
-
- /** @var CreditmemoRequest $creditmemoRequest */
- $creditmemoRequest = new CreditmemoRequest([
- 'commit' => false,
- 'type' => 'ReturnOrder'
- ]);
- $this->creditmemoRequestBuilderMock->expects(static::atLeastOnce())
- ->method('build')
- ->willReturn($creditmemoRequest);
- $this->creditmemoMock->expects(static::atLeastOnce())
- ->method('getStoreId')
- ->willReturn($storeId);
-
- /** @var array $lines */
- $lines = [
- new DataObject([
- 'description' => 'Chaz Kangeroo Hoodie (random product name)',
- 'tax' => -0.9
- ]),
- new DataObject([
- 'description' => 'Adjustment refund',
- 'tax' => -0.41,
- 'tax_calculated' => -0.41
- ]),
- new DataObject([
- 'description' => 'Adjustment fee',
- 'tax' => 0.83,
- 'tax_calculated' => 0.83
- ])
- ];
- $response = new RestTaxResult(['lines' => $lines]);
- $this->taxCompositeInterfaceMock->expects(static::atLeastOnce())
- ->method('calculateTax')
- ->with($creditmemoRequest, $storeId, ScopeInterface::SCOPE_STORE, [RestTaxInterface::FLAG_FORCE_NEW_RATES => true], null)
- ->willReturn($response);
- $this->creditmemoMock->expects(static::atLeastOnce())
- ->method('getTaxAmount')
- ->willReturn(0);
- $this->creditmemoMock->expects(static::atLeastOnce())
- ->method('getBaseTaxAmount')
- ->willReturn(0);
-
-
- /** @var Creditmemo $result */
- $result = $this->avataxAdjustmentTaxes->collect($this->creditmemoMock);
-
- $this->assertInstanceOf(AvataxAdjustmentTaxes::class, $result);
- $this->assertInternalType('object', $result);
- $this->assertArrayHasKey('tax_amount', $this->creditmemoMock->getData());
- $this->assertArrayHasKey('base_tax_amount', $this->creditmemoMock->getData());
- $this->assertCount(2, $this->creditmemoMock->getData());
- $this->assertInternalType('float', $this->creditmemoMock->getData('tax_amount'));
- $this->assertInternalType('float', $this->creditmemoMock->getData('base_tax_amount'));
- $this->assertSame(-0.42, $this->creditmemoMock->getData('tax_amount'));
- $this->assertSame(-0.42, $this->creditmemoMock->getData('base_tax_amount'));
- }
-
- /**
- * Call protected/private method of a class
- *
- * @param $object
- * @param string $methodName
- * @param array $parameters
- * @return mixed
- * @throws \ReflectionException
- */
- private function invokeMethod(&$object, string $methodName, array $parameters = [])
- {
- $reflection = new \ReflectionClass(get_class($object));
- $method = $reflection->getMethod($methodName);
- $method->setAccessible(true);
-
- return $method->invokeArgs($object, $parameters);
- }
-}
diff --git a/composer.json b/composer.json
index 237a75f9..f6055408 100644
--- a/composer.json
+++ b/composer.json
@@ -1,7 +1,7 @@
{
"name": "avalara/avatax-magento",
"type": "magento2-module",
- "version": "2.4.1",
+ "version": "2.4.2",
"license": "OSL-3.0",
"description": "Magento module for Avalara's AvaTax suite of business tax calculation and processing services. Uses the AvaTax REST v2 API.",
"require": {
diff --git a/docs/getting-started.md b/docs/getting-started.md
index 2b35b165..990b5802 100644
--- a/docs/getting-started.md
+++ b/docs/getting-started.md
@@ -57,7 +57,7 @@ This is the recommended installation method as it allows you to easily update th
1. Require the desired version of AvaTax. Latest version can be installed by running following command:
```
- composer require avalara/avatax-magento:2.4.1
+ composer require avalara/avatax-magento:2.4.2
```
2. Setup the AvaTax module in magento
diff --git a/etc/adminhtml/di.xml b/etc/adminhtml/di.xml
index c2abc25a..ebc29455 100644
--- a/etc/adminhtml/di.xml
+++ b/etc/adminhtml/di.xml
@@ -30,12 +30,12 @@
- - tax_avatax_general_development_account_number
- - tax_avatax_general_development_license_key
- - tax_avatax_general_development_company_code
- - avatax
+ - tax_avatax_configuration_extension_mode_development_account_number
+ - tax_avatax_configuration_extension_mode_development_license_key
+ - tax_avatax_configuration_extension_mode_development_company_code
+ - avatax_configuration
- development_company_code
- - tax_avatax_general_development_company_id
+ - tax_avatax_configuration_extension_mode_development_company_id
- \ClassyLlama\AvaTax\Model\Config\Source\Mode::DEVELOPMENT
@@ -44,12 +44,12 @@
- - tax_avatax_general_production_account_number
- - tax_avatax_general_production_license_key
- - tax_avatax_general_production_company_code
- - avatax
+ - tax_avatax_configuration_extension_mode_production_account_number
+ - tax_avatax_configuration_extension_mode_production_license_key
+ - tax_avatax_configuration_extension_mode_production_company_code
+ - avatax_configuration
- production_company_code
- - tax_avatax_general_production_company_id
+ - tax_avatax_configuration_extension_mode_production_company_id
- \ClassyLlama\AvaTax\Model\Config\Source\Mode::PRODUCTION
diff --git a/etc/adminhtml/menu.xml b/etc/adminhtml/menu.xml
index 5f8a1883..840c39c4 100644
--- a/etc/adminhtml/menu.xml
+++ b/etc/adminhtml/menu.xml
@@ -16,12 +16,27 @@
-->
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
+
+
+
+
+
+
diff --git a/etc/adminhtml/system.xml b/etc/adminhtml/system.xml
index 1a4d7c50..731d031a 100755
--- a/etc/adminhtml/system.xml
+++ b/etc/adminhtml/system.xml
@@ -17,813 +17,19 @@
-
- AvaTax - General
- github.com/avadev/Avalara-AvaTax-for-Magento2/blob/master/docs/getting-started.md.
- ]]>
-
- AvaTax Extension Version:
-
-
-
- tax/avatax/enabled
- Enable AvaTax
- Magento\Config\Model\Config\Source\Yesno
-
-
-
- tax/avatax/tax_included
- Taxation Policy
- ClassyLlama\AvaTax\Model\Config\Source\TaxIncluded
- ClassyLlama\AvaTax\Block\Adminhtml\System\Config\TaxIncluded
-
- 1
-
-
-
- tax/avatax/tax_mode
- Tax Mode
- ClassyLlama\AvaTax\Model\Config\Source\TaxMode
- Disabled — AvaTax tax estimation will be disabled and native Magento tax estimation will be used. Only use this option if you want to use Address Validation without tax estimation.Estimate Tax — AvaTax tax estimation will run during checkout, but completed orders will not be submitted to AvaTax.Estimate Tax & Submit Transactions to AvaTax — AvaTax tax estimation will run during checkout and invoices and credit memos will be submitted to AvaTax. ]]>
-
- 1
-
-
-
- tax/avatax/commit_submitted_transactions
- Commit Submitted Transactions
- Magento\Config\Model\Config\Source\Yesno
- No if you have specific reason to do so.]]>
-
- 1
- 3
-
-
-
- tax/avatax/tax_calculation_countries_enabled
- Taxable Countries
- ClassyLlama\AvaTax\Model\Config\Source\TaxCalculationCountries
-
- configured below).]]>
-
- 1
- 1
-
-
-
- tax/avatax/filter_tax_by_region
- Filter Tax Calculation By Region
- Magento\Config\Model\Config\Source\Yesno
- Yes if you have a specific reason to do so. See the [documentation](https://github.com/avadev/Avalara-AvaTax-for-Magento2/blob/develop/docs/sales-tax.md#filter_by_region) for more details.]]>
-
- 1
- 1
-
-
-
- tax/avatax/region_filter_list
- Enabled Regions
- ClassyLlama\AvaTax\Model\Config\Source\RegionFilterList
- Taxable Countries field, you must save this page for this region list to update.]]>
-
- 1
- 1
- 1
-
-
-
- tax/avatax/calculate_tax_before_discounts
- Calculate Tax Before Discount
- Magento\Config\Model\Config\Source\Yesno
-
-
- 1
- 1
-
-
-
-
- tax/avatax/live_mode
- Mode
- Production or Development credentials will be used. You will get your Account Number, License Key, and Company Code from your AvaTax representative. If Production is selected, then https://avatax.avalara.net will be used as the API url. If Development is selected, then https://development.avalara.net will be used as the API url. When you save this page, if you have entered credentials below for the selected mode, the AvaTax API will be pinged to ensure the credentials are working.]]>
- ClassyLlama\AvaTax\Model\Config\Source\Mode
-
- 1
-
-
-
- tax/avatax/production_account_number
- Account Number (Production)
- Magento\Config\Model\Config\Backend\Encrypted
-
- 1
-
-
-
- tax/avatax/production_license_key
- License Key (Production)
- Magento\Config\Model\Config\Backend\Encrypted
-
- 1
-
-
-
- tax/avatax/production_company_id
- Company (Production)
- productionCompanyCodeFrontendModel
- ClassyLlama\AvaTax\Model\Config\Source\CompanyCode
- Account Number and License Key fields above.]]>
-
- 1
-
-
-
- tax/avatax/development_account_number
- Account Number (Development)
- Magento\Config\Model\Config\Backend\Encrypted
-
- 1
-
-
-
- tax/avatax/development_license_key
- License Key (Development)
- Magento\Config\Model\Config\Backend\Encrypted
-
- 1
-
-
-
- tax/avatax/development_company_id
- Company (Development)
- developmentCompanyCodeFrontendModel
- ClassyLlama\AvaTax\Model\Config\Source\CompanyCode
- Account Number and License Key fields above.]]>
-
- 1
-
-
-
-
-
-
-
- tax/avatax/production_company_code
- Company Code (Production)
-
- 1
-
-
-
- tax/avatax/development_company_code
- Company Code (Development)
-
- 1
-
-
-
-
-
-
- tax/avatax/customer_code_format
- Customer Code Format
- ClassyLlama\AvaTax\Model\Config\Source\CustomerCode
-
-
- 1
-
-
-
- tax/avatax/upc_attribute
- UPC Attribute To Use As Item Code
- ClassyLlama\AvaTax\Model\Config\Source\Product\Attributes
- ItemCode field. However if you want to use a UPC product attribute as the AvaTax ItemCode, select which attribute above maps to your UPC attribute. If a UPC attribute is present on a product, it will be used as the AvaTax ItemCode and will be prepended with "UPC: ". Otherwise the product's SKU will be sent. Sending the UPC in the ItemCode field will allow you to bypass the Avalara Tax Code selection and mapping in your product record. The UPC, when sent in the ItemCode field, maps directly to the Avalara Product Tax Code so you don’t have to map those codes separately.]]>
-
- 1
-
-
-
- tax/avatax/ref1_attribute
- Ref1 Attribute
- ClassyLlama\AvaTax\Model\Config\Source\Product\Attributes
- Ref1 field. Only the first 250 characters of this attribute will be sent to AvaTax.]]>
-
- 1
-
-
-
- tax/avatax/ref2_attribute
- Ref2 Attribute
- ClassyLlama\AvaTax\Model\Config\Source\Product\Attributes
- Ref2 field. Only the first 250 characters of this attribute will be sent to AvaTax.]]>
-
- 1
-
-
-
- tax/avatax/use_business_identification_number
- Submit VAT Number to AvaTax
- Magento\Config\Model\Config\Source\Yesno
- Yes if you want to send VAT tax numbers to AvaTax to affect tax calculation. If a guest or customer has a VAT number set on their Magento shipping address, it will be used. Otherwise the Tax/VAT Number attribute value from the customer record will be used. If a VAT number is not found, nothing will be sent. The VAT number will be sent to the BusinessIdentificationNo field in AvaTax.]]>
-
- 1
-
-
-
- Submit VAT Transport
- ClassyLlama\AvaTax\Block\Adminhtml\Form\Field\Transport
- Magento\Config\Model\Config\Backend\Serialized\ArraySerialized
-
-
- tax/avatax/location_code
- Location Code
- validate-length maximum-length-50
- AvaTax documentation.]]>
-
- 1
-
-
-
- tax/avatax/shipping_tax_code
- Shipping Tax Code
- The Avalara tax code used to classify the shipping service type.
-
- 1
-
-
-
- tax/avatax/sku_shipping
- Shipping SKU
- The SKU sent to denote shipping costs.
- required-entry validate-length maximum-length-50
-
- 1
-
-
-
- tax/avatax/sku_adjustment_positive
- Adjustment Refund SKU
- The SKU sent to denote positive adjustments on Credit Memos.
- required-entry validate-length maximum-length-50
-
- 1
-
-
-
- tax/avatax/sku_adjustment_negative
- Adjustment Fee SKU
- The SKU sent to denote negative adjustments on Credit Memos.
- required-entry validate-length maximum-length-50
-
- 1
-
-
-
- tax/avatax/sku_gift_wrap_order
- Gift Wrap Order SKU
- The SKU sent AvaTax to denote gift wrap order costs. Only relevant for Magento Enterprise.
- required-entry validate-length maximum-length-50
-
- 1
-
-
-
- tax/avatax/sku_gift_wrap_item
- Gift Wrap Items SKU
- The SKU sent AvaTax to denote gift wrap item costs. Only relevant for Magento Enterprise.
- required-entry validate-length maximum-length-50
-
- 1
-
-
-
- tax/avatax/sku_gift_wrap_card
- Gift Wrap Printed Card SKU
- The SKU sent to denote gift wrap printed card costs. Only relevant for Magento Enterprise.
- required-entry validate-length maximum-length-50
-
- 1
-
-
-
-
- AvaTax - Address Validation
-
- tax/avatax/address_validation_enabled
- Enable Address Validation
- Magento\Config\Model\Config\Source\Yesno
- Enable validation of shipping address using the AvaTax Address Validation API.
-
- 1
-
-
-
- tax/avatax/address_validation_countries_enabled
- Enabled Countries
- ClassyLlama\AvaTax\Model\Config\Source\AddressValidationCountries
- Select which countries to enable for address validation. AvaTax Address Validation currently only supports United States and Canada.
-
- 1
- 1
-
-
-
- tax/avatax/address_validation_user_has_choice
- Allow User To Choose Original (Invalid) Address
- Magento\Config\Model\Config\Source\Yesno
- Yes to allow the user to choose between the original and validated addresses (valid address will be selected by default). If set to No , user will be required to use the validated address or update their original address. This setting is ignored in the backend and the user will always have a choice.]]>
-
- 1
- 1
-
-
-
- tax/avatax/address_validation_instructions_with_choice
- Address Validation Instructions
- Review & Payments step of the checkout, this text will be displayed above the Suggested Address and Original Address checkboxes.]]>
-
- 1
- 1
- 1
-
-
-
- tax/avatax/address_validation_instructions_without_choice
- Address Validation Instructions
- Review & Payments step of the checkout, this text will be displayed above the suggested address.]]>
-
- 1
- 1
- 0
-
-
-
- tax/avatax/address_validation_error_instructions
- Address Validation Error Instructions
- This text will be displayed when there is an error in the address validation process. The element assigned the "error-message" class will be filled with the error message summary returned by AvaTax.
-
- 1
- 1
-
-
-
-
- AvaTax - Customs
-
- Enable Duty
- Magento\Config\Model\Config\Source\Yesno
- Cross Border Classes (see Stores > AvaTax > Cross Border Classes) and assignment
- of Cross Border Types to products.
- ]]>
-
-
- Map Shipping Methods]]>
-
-
-
-
- Ground Shipping Methods
- ClassyLlama\AvaTax\Model\Config\Source\AvailableShippingMethods
-
-
- 1
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- AvaTax - Document Management
-
- Enable Document Management
- Magento\Config\Model\Config\Source\Yesno
- AvaTax Document Management allows users to upload documents that verify that they’re tax exempt and if they do, they won’t be charged tax in the checkout. This feature must be enabled in your Avalara account.
-
-
- Enabled Countries
- ClassyLlama\AvaTax\Model\Config\Source\DocumentManagementCountries
- Select which countries to enable for Document Management.
-
- 1
-
-
-
- Checkout Link Text: New Cert(No certs exist)
- The text of the link that appears at checkout allowing the initiation of a new certificate. This text shows if there are no existing certificates for the customer.
-
- 1
-
-
-
- Checkout Link Text: New Cert(Certs exist)
- The text of the link that appears at checkout allowing the initiation of a new certificate. This text shows if there are already existing certificates for the customer.
-
- 1
-
-
-
- Checkout Link Text: Manage Existing Certs
- The text of the link that appears at checkout allowing the user to navigate to certificate management in My Account. This text shows only if there are existing certificates for the customer.
-
- 1
-
-
-
- Change Status name of the Certificate
- Magento\Config\Model\Config\Source\Yesno
- Rename Status of the Certificate
-
- 1
-
-
-
- 'Approved' Status Name(Default name)
- This text will be shown instead of the default certificate status name('Approved') in the 'Tax Certificates' grid of the My Account.
-
- 1
- 1
-
-
-
- 'Denied' Status Name(Default name)
- This text will be shown instead of the default certificate status name('Denied') in the 'Tax Certificates' grid of the My Account.
-
- 1
- 1
-
-
-
- 'Pending' Status Name(Default name)
- This text will be shown instead of the default certificate status name('Pending') in the 'Tax Certificates' grid of the My Account.
-
- 1
- 1
-
-
-
-
- AvaTax - Advanced
-
- Enable tax calculation for Adjustment Refund and Adjustment Fee
- Magento\Config\Model\Config\Source\Yesno
-
-
-
- Tables Exemptions List (comma-separated list)
-
-
-
- Error Handling Settings]]>
-
-
-
- Enable logging of AvaTax response data
- Magento\Config\Model\Config\Source\Yesno
-
-
-
- tax/avatax/error_action
- Error Action
- ClassyLlama\AvaTax\Model\Config\Source\ErrorAction
- Disable checkout & show error message is selected, the extension will prevent users and admins from placing orders.]]>
-
- 1
-
-
-
- tax/avatax/error_action_disable_checkout_message_frontend
- Frontend Error Message
- Disable checkout & show error message is selected above.]]>
-
- 1
- 1
-
-
-
- tax/avatax/error_action_disable_checkout_message_backend
- Backend Error Message
- Disable checkout & show error message is selected above.]]>
-
- 1
- 1
-
-
-
- AvaTax API Timeout
-
-
-
-
- tax/avatax/logging_db_level
- Database Log Level
- ClassyLlama\AvaTax\Model\Config\Source\LogLevel
-
- 1
-
- Warning is recommended for production use.]]>
-
-
- tax/avatax/logging_db_detail
- Database Log Detail
- ClassyLlama\AvaTax\Model\Config\Source\LogDetail
-
- 1
-
- Minimal is recommended for production use.]]>
-
-
- tax/avatax/logging_db_lifetime
- Database Log Record Lifetime
- Required. Days before entries are auto-purged.
- validate-number
- required-entry integer validate-greater-than-zero
-
- 1
-
-
-
- tax/avatax/logging_file_enabled
- Enable Logging To File
- Magento\Config\Model\Config\Source\Yesno
-
- 1
-
- Archiving of log files is affected by System -> Admin Actions Log Archiving
-
-
- tax/avatax/logging_file_mode
- File Log Mode
- ClassyLlama\AvaTax\Model\Config\Source\LogFileMode
-
- 1
- 1
-
- Log files are located in the magento var/log/ directory
-
-
- tax/avatax/logging_file_builtin_rotation_enabled
- Enable Built-In Log File Rotation
- Magento\Config\Model\Config\Source\Yesno
-
- 1
- 1
- 2
-
- Automatic log file rotation will allow you to control how much history is maintained in
- the AvaTax log files, and separate them by day. For more efficient management of log files you
- should disable this option and use something like logrotate to handle the rotation of log files
- at the system level.
-
-
-
- tax/avatax/logging_file_builtin_rotation_max_files
- Built-In Log File Rotation Max Files
- validate-number
- required-entry integer validate-greater-than-zero
-
- 1
- 1
- 2
- 1
-
- The number of files/days to maintain in the log directory when rotating. The log file rotator
- will create a new file each day.
-
-
-
- tax/avatax/logging_file_level
- File Log Level
- ClassyLlama\AvaTax\Model\Config\Source\LogLevel
-
- 1
- 1
-
- Warning is recommended for production use.]]>
-
-
- tax/avatax/logging_file_detail
- File Log Detail
- ClassyLlama\AvaTax\Model\Config\Source\LogDetail
-
- 1
- 1
-
- Normal is recommended for production use.]]>
-
-
-
- tax/avatax/queue_processing_type
- Queue Processing Type
- ClassyLlama\AvaTax\Model\Config\Source\QueueProcessingType
-
- 1
- 1
-
- Normal Queue Processing - each item of Queue will be processed separately.
- Batch Queue Processing - Queue will be processed by 1000 items batch.
-
-
-
- tax/avatax/queue_admin_notification_enabled
- Enable Queue Admin Notification
- Magento\Config\Model\Config\Source\Yesno
-
- 1
- 1
-
- A notification will be displayed at the top of any admin page if there are pending queue records waiting to be submitted to AvaTax but no attempts have been made in the last 24 hours to submit them.
-
-
- tax/avatax/queue_failure_notification_enabled
- Enable Queue Failure Notification
- Magento\Config\Model\Config\Source\Yesno
-
- 1
- 1
-
- A notification will be displayed at the top of any admin page if there are any failed queue records.
-
-
- tax/avatax/queue_max_retry_attempts
- Max Queue Retry Attempts
- Please enter a number 1 or greater in this field.
- validate-number
- required-entry integer validate-greater-than-zero
-
- 1
-
-
-
- tax/avatax/queue_complete_lifetime
- Complete Queue Lifetime
- Required. Days before entries are auto-purged.
- validate-number
- required-entry integer validate-greater-than-zero
-
- 1
- 1
-
-
-
- tax/avatax/queue_failed_lifetime
- Failed Queue Lifetime
- Required. Days before entries are auto-purged.
- validate-number
- required-entry integer validate-greater-than-zero
-
- 1
- 1
-
-
-
- Allowed Attributes
-
- Payment details attribute codes
- Comma-separated list
-
-
- Shipping information attribute codes
- Comma-separated list
-
-
- Quote details item attribute codes
- Comma-separated list
-
-
- Cart attribute codes
- Comma-separated list
-
-
- Order attribute codes
- Comma-separated list
-
-
- Invoice attribute codes
- Comma-separated list
-
-
- Credit memo attribute codes
- Comma-separated list
-
-
- Applied tax rate attribute codes
- Comma-separated list
-
-
- Cart item attribute codes
- Comma-separated list
-
-
- Order item attribute codes
- Comma-separated list
-
-
- Invoice item attribute codes
- Comma-separated list
-
-
- Credit memo item attribute codes
- Comma-separated list
-
-
- Totals attribute codes
- Comma-separated list
-
-
-
-
- AvaTax - Certificate Capture Management
-
- Disable certificates auto validation
- Magento\Config\Model\Config\Source\Yesno
-
-
+
+ AvaTax Configuration
+ Connector for Magento 2 for Sales Tax.
+ ]]>
+ ClassyLlama\AvaTax\Block\Adminhtml\System\Config\AvaTax
+
+
+
+
+
+
+
+
diff --git a/etc/adminhtml/system/address_validation.xml b/etc/adminhtml/system/address_validation.xml
new file mode 100644
index 00000000..f226317a
--- /dev/null
+++ b/etc/adminhtml/system/address_validation.xml
@@ -0,0 +1,72 @@
+
+
+
+
+ Address Validation
+ ClassyLlama\AvaTax\Block\Adminhtml\System\Config\ExpandedFieldSet
+
+ tax/avatax/address_validation_enabled
+ Enable Address Validation
+ Magento\Config\Model\Config\Source\Yesno
+ Enable validation of shipping address using the AvaTax Address Validation API.
+
+
+ tax/avatax/address_validation_countries_enabled
+ Enabled Countries
+ ClassyLlama\AvaTax\Model\Config\Source\AddressValidationCountries
+ Select which countries to enable for address validation. AvaTax Address Validation currently only supports United States and Canada.
+
+ 1
+
+
+
+ tax/avatax/address_validation_user_has_choice
+ Allow User To Choose Original Address
+ Magento\Config\Model\Config\Source\Yesno
+ Yes to allow the user to choose between the original and validated addresses (valid address will be selected by default). If set to No , user will be required to use the validated address or update their original address. This setting is ignored in the backend and the user will always have a choice.]]>
+
+ 1
+
+
+
+ tax/avatax/address_validation_instructions_with_choice
+ Address Validation Instructions
+ Review & Payments step of the checkout, this text will be displayed above the Suggested Address and Original Address checkboxes.]]>
+
+ 1
+ 1
+
+
+
+ tax/avatax/address_validation_instructions_without_choice
+ Address Validation Instructions
+ Review & Payments step of the checkout, this text will be displayed above the suggested address.]]>
+
+ 1
+ 0
+
+
+
+ tax/avatax/address_validation_error_instructions
+ Address Validation Error Message
+ This text will be displayed when there is an error in the address validation process. The element assigned the "error-message" class will be filled with the error message summary returned by AvaTax.
+
+ 1
+
+
+
+
\ No newline at end of file
diff --git a/etc/adminhtml/system/advanced.xml b/etc/adminhtml/system/advanced.xml
new file mode 100644
index 00000000..161d92f9
--- /dev/null
+++ b/etc/adminhtml/system/advanced.xml
@@ -0,0 +1,106 @@
+
+
+
+
+ Advanced
+ ClassyLlama\AvaTax\Block\Adminhtml\System\Config\ExpandedFieldSet
+
+ tax/avatax_advanced/avatax_adjustment_taxes
+ Enable Tax Calculation for Adjustment Refund and Adjustment Fee
+ Magento\Config\Model\Config\Source\Yesno
+
+
+
+ tax/avatax_advanced/avatax_table_exemptions
+ Tables Exemptions List (comma-separated list)
+
+
+
+ Allowed Attributes
+ 0
+ Magento\Config\Block\System\Config\Form\Fieldset
+
+ tax/avatax_advanced_attribute_codes/paymentdetails
+ Payment details attribute codes
+ Comma-separated list
+
+
+ tax/avatax_advanced_attribute_codes/shippinginformation
+ Shipping information attribute codes
+ Comma-separated list
+
+
+ tax/avatax_advanced_attribute_codes/quotedetailsitem
+ Quote details item attribute codes
+ Comma-separated list
+
+
+ tax/avatax_advanced_attribute_codes/cart
+ Cart attribute codes
+ Comma-separated list
+
+
+ tax/avatax_advanced_attribute_codes/order
+ Order attribute codes
+ Comma-separated list
+
+
+ tax/avatax_advanced_attribute_codes/invoice
+ Invoice attribute codes
+ Comma-separated list
+
+
+ tax/avatax_advanced_attribute_codes/creditmemo
+ Credit memo attribute codes
+ Comma-separated list
+
+
+ tax/avatax_advanced_attribute_codes/appliedtaxrate
+ Applied tax rate attribute codes
+ Comma-separated list
+
+
+ tax/avatax_advanced_attribute_codes/cartitem
+ Cart item attribute codes
+ Comma-separated list
+
+
+ tax/avatax_advanced_attribute_codes/orderitem
+ Order item attribute codes
+ Comma-separated list
+
+
+ tax/avatax_advanced_attribute_codes/invoiceitem
+ Invoice item attribute codes
+ Comma-separated list
+
+
+ tax/avatax_advanced_attribute_codes/creditmemoitem
+ Credit memo item attribute codes
+ Comma-separated list
+
+
+ tax/avatax_advanced_attribute_codes/totals
+ Totals attribute codes
+ Comma-separated list
+
+
+
+ 1
+
+
+
\ No newline at end of file
diff --git a/etc/adminhtml/system/cross_border.xml b/etc/adminhtml/system/cross_border.xml
new file mode 100644
index 00000000..13905685
--- /dev/null
+++ b/etc/adminhtml/system/cross_border.xml
@@ -0,0 +1,50 @@
+
+
+
+
+ Cross-Border
+ ClassyLlama\AvaTax\Block\Adminhtml\System\Config\ExpandedFieldSet
+
+ tax/avatax_customs/enabled
+ Enable Duty
+ Magento\Config\Model\Config\Source\Yesno
+ Cross Border Classes (see Stores > AvaTax > Cross Border Classes) and assignment
+ of Cross Border Types to products.
+ ]]>
+
+
+ tax/avatax_customs/map_shipping_methods
+ Map Shipping Methods]]>
+
+
+
+ tax/avatax_customs/ground_shipping_methods
+ Ground Shipping Methods
+ ClassyLlama\AvaTax\Model\Config\Source\AvailableShippingMethods
+
+
+ 1
+
+
+
+ 1
+
+
+
\ No newline at end of file
diff --git a/etc/adminhtml/system/error_logs_and_queue.xml b/etc/adminhtml/system/error_logs_and_queue.xml
new file mode 100644
index 00000000..65b162da
--- /dev/null
+++ b/etc/adminhtml/system/error_logs_and_queue.xml
@@ -0,0 +1,212 @@
+
+
+
+
+ Error, Logs and Queue
+ ClassyLlama\AvaTax\Block\Adminhtml\System\Config\ExpandedFieldSet
+
+ Error Handling Settings
+ 1
+ Magento\Config\Block\System\Config\Form\Fieldset
+
+ tax/avatax_advanced/response_logging_enabled
+ Enable Logging of AvaTax Response Data
+ Magento\Config\Model\Config\Source\Yesno
+
+
+
+ tax/avatax/error_action
+ Error Action
+ ClassyLlama\AvaTax\Model\Config\Source\ErrorAction
+ Disable checkout & show error message is selected, the extension will prevent users and admins from placing orders.]]>
+
+
+ tax/avatax/error_action_disable_checkout_message_frontend
+ Frontend Error Message
+ Disable checkout & show error message is selected above.]]>
+
+ 1
+
+
+
+ tax/avatax/error_action_disable_checkout_message_backend
+ Backend Error Message
+ Disable checkout & show error message is selected above.]]>
+
+ 1
+
+
+
+ AvaTax API Timeout
+
+
+
+
+ Logging Settings
+ 1
+ Magento\Config\Block\System\Config\Form\Fieldset
+
+ tax/avatax/logging_db_level
+ Database Log Level
+ ClassyLlama\AvaTax\Model\Config\Source\LogLevel
+ Warning is recommended for production use.]]>
+
+
+ tax/avatax/logging_db_detail
+ Database Log Detail
+ ClassyLlama\AvaTax\Model\Config\Source\LogDetail
+ Minimal is recommended for production use.]]>
+
+
+ tax/avatax/logging_db_lifetime
+ Database Log Record Lifetime
+ Required. Days before entries are auto-purged.
+ validate-number
+ required-entry integer validate-greater-than-zero
+
+
+ tax/avatax/logging_file_enabled
+ Enable Logging To File
+ Magento\Config\Model\Config\Source\Yesno
+ Archiving of log files is affected by System -> Admin Actions Log Archiving
+
+
+ tax/avatax/logging_file_mode
+ File Log Mode
+ ClassyLlama\AvaTax\Model\Config\Source\LogFileMode
+
+ 1
+
+ Log files are located in the magento var/log/ directory
+
+
+ tax/avatax/logging_file_builtin_rotation_enabled
+ Enable Built-In Log File Rotation
+ Magento\Config\Model\Config\Source\Yesno
+
+ 1
+ 2
+
+ Automatic log file rotation will allow you to control how much history is maintained in
+ the AvaTax log files, and separate them by day. For more efficient management of log files you
+ should disable this option and use something like logrotate to handle the rotation of log files
+ at the system level.
+
+
+
+ tax/avatax/logging_file_builtin_rotation_max_files
+ Built-In Log File Rotation Max Files
+ validate-number
+ required-entry integer validate-greater-than-zero
+
+ 1
+ 2
+ 1
+
+ The number of files/days to maintain in the log directory when rotating. The log file rotator
+ will create a new file each day.
+
+
+
+ tax/avatax/logging_file_level
+ File Log Level
+ ClassyLlama\AvaTax\Model\Config\Source\LogLevel
+
+ 1
+
+ Warning is recommended for production use.]]>
+
+
+ tax/avatax/logging_file_detail
+ File Log Detail
+ ClassyLlama\AvaTax\Model\Config\Source\LogDetail
+
+ 1
+
+ Normal is recommended for production use.]]>
+
+
+
+ Queue Processing Settings
+ Tax Mode is set to Estimate Tax & Submit Transactions to AvaTax , then queue processing is enabled. Otherwise the queue will not submit invoices and credit memos to AvaTax as transaction submissions are disabled.]]>
+ 1
+ Magento\Config\Block\System\Config\Form\Fieldset
+
+ tax/avatax/queue_processing_type
+ Queue Processing Type
+ ClassyLlama\AvaTax\Model\Config\Source\QueueProcessingType
+
+ 1
+
+ Normal Queue Processing - each item of Queue will be processed separately.
+ Batch Queue Processing - Queue will be processed by 1000 items batch.
+
+
+
+ tax/avatax/queue_admin_notification_enabled
+ Enable Queue Admin Notification
+ Magento\Config\Model\Config\Source\Yesno
+
+ 1
+
+ A notification will be displayed at the top of any admin page if there are pending queue records waiting to be submitted to AvaTax but no attempts have been made in the last 24 hours to submit them.
+
+
+ tax/avatax/queue_failure_notification_enabled
+ Enable Queue Failure Notification
+ Magento\Config\Model\Config\Source\Yesno
+
+ 1
+
+ A notification will be displayed at the top of any admin page if there are any failed queue records.
+
+
+ tax/avatax/queue_max_retry_attempts
+ Max Queue Retry Attempts
+ Please enter a number 1 or greater in this field.
+ validate-number
+ required-entry integer validate-greater-than-zero
+
+
+ tax/avatax/queue_complete_lifetime
+ Complete Queue Lifetime
+ Required. Days before entries are auto-purged.
+ validate-number
+ required-entry integer validate-greater-than-zero
+
+ 1
+
+
+
+ tax/avatax/queue_failed_lifetime
+ Failed Queue Lifetime
+ Required. Days before entries are auto-purged.
+ validate-number
+ required-entry integer validate-greater-than-zero
+
+ 1
+
+
+
+ 3
+
+
+
+ 1
+
+
+
\ No newline at end of file
diff --git a/etc/adminhtml/system/exemption_certcapture_management.xml b/etc/adminhtml/system/exemption_certcapture_management.xml
new file mode 100644
index 00000000..8c61e9b3
--- /dev/null
+++ b/etc/adminhtml/system/exemption_certcapture_management.xml
@@ -0,0 +1,106 @@
+
+
+
+
+ Exemption CertCapture Management
+ ClassyLlama\AvaTax\Block\Adminhtml\System\Config\ExpandedFieldSet
+
+ tax/avatax_document_management/enabled
+ Enable Exemption CertCapture Management
+ Magento\Config\Model\Config\Source\Yesno
+ AvaTax Document Management allows users to upload documents that verify that they’re tax exempt and if they do, they won’t be charged tax in the checkout. This feature must be enabled in your Avalara account.
+
+
+ tax/avatax_document_management/enabled_countries
+ Enabled Countries
+ ClassyLlama\AvaTax\Model\Config\Source\DocumentManagementCountries
+ Select which countries to enable for Document Management.
+
+ 1
+
+
+
+ tax/avatax_document_management/checkout_link_text_new_cert_no_certs_exist
+ Checkout Link Text: New Cert(No certs exist)
+ The text of the link that appears at checkout allowing the initiation of a new certificate. This text shows if there are no existing certificates for the customer.
+
+ 1
+
+
+
+ tax/avatax_document_management/checkout_link_text_new_cert_certs_exist
+ Checkout Link Text: New Cert(Certs exist)
+ The text of the link that appears at checkout allowing the initiation of a new certificate. This text shows if there are already existing certificates for the customer.
+
+ 1
+
+
+
+ tax/avatax_document_management/checkout_link_text_manage_existing_certs
+ Checkout Link Text: Manage Existing Certs
+ The text of the link that appears at checkout allowing the user to navigate to certificate management in My Account. This text shows only if there are existing certificates for the customer.
+
+ 1
+
+
+
+ tax/avatax_document_management/custom_status_name_certificate
+ Change Status name of the Certificate
+ Magento\Config\Model\Config\Source\Yesno
+ Rename Status of the Certificate
+
+ 1
+
+
+
+ tax/avatax_document_management/approved_status_name
+ 'Approved' Status Name(Default name)
+ This text will be shown instead of the default certificate status name('Approved') in the 'Tax Certificates' grid of the My Account.
+
+ 1
+ 1
+
+
+
+ tax/avatax_document_management/denied_status_name
+ 'Denied' Status Name(Default name)
+ This text will be shown instead of the default certificate status name('Denied') in the 'Tax Certificates' grid of the My Account.
+
+ 1
+ 1
+
+
+
+ tax/avatax_document_management/pending_status_name
+ 'Pending' Status Name(Default name)
+ This text will be shown instead of the default certificate status name('Pending') in the 'Tax Certificates' grid of the My Account.
+
+ 1
+ 1
+
+
+
+ tax/avatax_certificate_capture/disable_certcapture_auto_validation
+ Disable Certificates Auto Validation
+ Magento\Config\Model\Config\Source\Yesno
+
+
+
+ 1
+
+
+
\ No newline at end of file
diff --git a/etc/adminhtml/system/extension_mode.xml b/etc/adminhtml/system/extension_mode.xml
new file mode 100644
index 00000000..3b294d98
--- /dev/null
+++ b/etc/adminhtml/system/extension_mode.xml
@@ -0,0 +1,119 @@
+
+
+
+
+ Extension Mode
+ ClassyLlama\AvaTax\Block\Adminhtml\System\Config\ExpandedFieldSet
+
+ AvaTax Extension Version:
+
+
+
+ tax/avatax/enabled
+ Enable AvaTax
+ Magento\Config\Model\Config\Source\Yesno
+
+
+ tax/avatax/live_mode
+ Mode
+ Production or Development credentials will be used. You will get your Account Number, License Key, and Company Code from your AvaTax representative. If Production is selected, then https://avatax.avalara.net will be used as the API url. If Development is selected, then https://development.avalara.net will be used as the API url. When you save this page, if you have entered credentials below for the selected mode, the AvaTax API will be pinged to ensure the credentials are working.]]>
+ ClassyLlama\AvaTax\Model\Config\Source\Mode
+
+ 1
+
+
+
+ tax/avatax/production_account_number
+ Account Number
+ Magento\Config\Model\Config\Backend\Encrypted
+
+ 1
+ 1
+
+
+
+ tax/avatax/production_license_key
+ License Key
+ Magento\Config\Model\Config\Backend\Encrypted
+
+ 1
+ 1
+
+
+
+ tax/avatax/production_company_id
+ Company
+ productionCompanyCodeFrontendModel
+ ClassyLlama\AvaTax\Model\Config\Source\CompanyCode
+ Account Number and License Key fields above.]]>
+
+ 1
+ 1
+
+
+
+ tax/avatax/development_account_number
+ Account Number (Development)
+ Magento\Config\Model\Config\Backend\Encrypted
+
+ 1
+ 0
+
+
+
+ tax/avatax/development_license_key
+ License Key (Development)
+ Magento\Config\Model\Config\Backend\Encrypted
+
+ 1
+ 0
+
+
+
+ tax/avatax/development_company_id
+ Company (Development)
+ developmentCompanyCodeFrontendModel
+ ClassyLlama\AvaTax\Model\Config\Source\CompanyCode
+ Account Number and License Key fields above.]]>
+
+ 1
+ 0
+
+
+
+
+
+
+ tax/avatax/production_company_code
+ Company Code
+
+ 1
+ 1
+
+
+
+ tax/avatax/development_company_code
+ Company Code
+
+ 1
+ 0
+
+
+
+
+
\ No newline at end of file
diff --git a/etc/adminhtml/system/sales_tax.xml b/etc/adminhtml/system/sales_tax.xml
new file mode 100644
index 00000000..3432ae0f
--- /dev/null
+++ b/etc/adminhtml/system/sales_tax.xml
@@ -0,0 +1,179 @@
+
+
+
+
+ Sales Tax
+ ClassyLlama\AvaTax\Block\Adminhtml\System\Config\ExpandedFieldSet
+
+ tax/avatax/tax_included
+ Taxation Policy
+ ClassyLlama\AvaTax\Model\Config\Source\TaxIncluded
+ ClassyLlama\AvaTax\Block\Adminhtml\System\Config\TaxIncluded
+
+
+ Gross: - Included taxes are part of the catalog price and are not added separately to the cart subtotal.
+
+
+ Net: — Included taxes are NOT part of the catalog price and are added separately to the cart subtotal.
+
+
+ ]]>
+
+
+ tax/avatax/tax_mode
+ Tax Mode
+ ClassyLlama\AvaTax\Model\Config\Source\TaxMode
+
+
+ Disabled — Disables AvaTax tax estimation and uses native Magento tax estimation. Use this option when you want to use address validation only.
+
+
+ Estimate Tax — Runs AvaTax tax estimation during order checkout but does NOT submit completed orders to AvaTax.
+
+
+ Estimate Tax & Submit Transactions to AvaTax — Runs AvaTax tax estimation during order checkout and submits invoices and credit memos to AvaTax.
+
+
+ ]]>
+
+
+ tax/avatax/tax_calculation_countries_enabled
+ Taxable Countries
+ ClassyLlama\AvaTax\Model\Config\Source\TaxCalculationCountries
+ configured below).]]>
+
+ 1
+
+
+
+ tax/avatax/filter_tax_by_region
+ Filter Tax Calculation By Region
+ Magento\Config\Model\Config\Source\Yesno
+ Yes if you have a specific reason to do so. See the [documentation](https://github.com/avadev/Avalara-AvaTax-for-Magento2/blob/develop/docs/sales-tax.md#filter_by_region) for more details.]]>
+
+ 1
+
+
+
+ tax/avatax/region_filter_list
+ Enabled Regions
+ ClassyLlama\AvaTax\Model\Config\Source\RegionFilterList
+ Taxable Countries field, you must save this page for this region list to update.]]>
+
+ 1
+ 1
+
+
+
+ tax/avatax/calculate_tax_before_discounts
+ Calculate Tax Before Discount
+ Magento\Config\Model\Config\Source\Yesno
+
+
+ 1
+
+
+
+ tax/avatax/commit_submitted_transactions
+ Commit Submitted Transactions
+ Magento\Config\Model\Config\Source\Yesno
+ No if you have specific reason to do so.]]>
+
+ 3
+
+
+
+
+ tax/avatax/customer_code_format
+ Customer Code Format
+ ClassyLlama\AvaTax\Model\Config\Source\CustomerCode
+
+
+
+ tax/avatax/upc_attribute
+ UPC Attribute To Use As Item Code
+ ClassyLlama\AvaTax\Model\Config\Source\Product\Attributes
+ ItemCode field. However if you want to use a UPC product attribute as the AvaTax ItemCode, select which attribute above maps to your UPC attribute. If a UPC attribute is present on a product, it will be used as the AvaTax ItemCode and will be prepended with "UPC: ". Otherwise the product's SKU will be sent. Sending the UPC in the ItemCode field will allow you to bypass the Avalara Tax Code selection and mapping in your product record. The UPC, when sent in the ItemCode field, maps directly to the Avalara Product Tax Code so you don’t have to map those codes separately.]]>
+
+
+ tax/avatax/ref1_attribute
+ Ref1 Attribute
+ ClassyLlama\AvaTax\Model\Config\Source\Product\Attributes
+ Ref1 field. Only the first 250 characters of this attribute will be sent to AvaTax.]]>
+
+
+ tax/avatax/ref2_attribute
+ Ref2 Attribute
+ ClassyLlama\AvaTax\Model\Config\Source\Product\Attributes
+ Ref2 field. Only the first 250 characters of this attribute will be sent to AvaTax.]]>
+
+
+ tax/avatax/location_code
+ Location Code
+ validate-length maximum-length-50
+ AvaTax documentation.]]>
+
+
+ tax/avatax/shipping_tax_code
+ Shipping Tax Code
+ The Avalara tax code used to classify the shipping service type.
+
+
+ tax/avatax/sku_shipping
+ Shipping SKU
+ The SKU sent to denote shipping costs.
+ required-entry validate-length maximum-length-50
+
+
+ tax/avatax/sku_adjustment_positive
+ Adjustment Refund SKU
+ The SKU sent to denote positive adjustments on Credit Memos.
+ required-entry validate-length maximum-length-50
+
+
+ tax/avatax/sku_adjustment_negative
+ Adjustment Fee SKU
+ The SKU sent to denote negative adjustments on Credit Memos.
+ required-entry validate-length maximum-length-50
+
+
+ tax/avatax/sku_gift_wrap_order
+ Gift Wrap Order SKU
+ The SKU sent AvaTax to denote gift wrap order costs. Only relevant for Magento Enterprise.
+ required-entry validate-length maximum-length-50
+
+
+ tax/avatax/sku_gift_wrap_item
+ Gift Wrap Items SKU
+ The SKU sent AvaTax to denote gift wrap item costs. Only relevant for Magento Enterprise.
+ required-entry validate-length maximum-length-50
+
+
+ tax/avatax/sku_gift_wrap_card
+ Gift Wrap Printed Card SKU
+ The SKU sent to denote gift wrap printed card costs. Only relevant for Magento Enterprise.
+ required-entry validate-length maximum-length-50
+
+
+ 1
+
+
+
\ No newline at end of file
diff --git a/etc/adminhtml/system/vat.xml b/etc/adminhtml/system/vat.xml
new file mode 100644
index 00000000..af12d30f
--- /dev/null
+++ b/etc/adminhtml/system/vat.xml
@@ -0,0 +1,37 @@
+
+
+
+
+ VAT
+ ClassyLlama\AvaTax\Block\Adminhtml\System\Config\ExpandedFieldSet
+
+ tax/avatax/use_business_identification_number
+ Submit VAT Number to AvaTax
+ Magento\Config\Model\Config\Source\Yesno
+ Yes if you want to send VAT tax numbers to AvaTax to affect tax calculation. If a guest or customer has a VAT number set on their Magento shipping address, it will be used. Otherwise the Tax/VAT Number attribute value from the customer record will be used. If a VAT number is not found, nothing will be sent. The VAT number will be sent to the BusinessIdentificationNo field in AvaTax.]]>
+
+
+ tax/avatax_general/vat_transport
+ Submit VAT Transport
+ ClassyLlama\AvaTax\Block\Adminhtml\Form\Field\Transport
+ Magento\Config\Model\Config\Backend\Serialized\ArraySerialized
+
+
+ 1
+
+
+
\ No newline at end of file
diff --git a/etc/config.xml b/etc/config.xml
index d466d06f..9751638b 100755
--- a/etc/config.xml
+++ b/etc/config.xml
@@ -69,7 +69,7 @@
0
- Is this purchase tax-exempt?
+ Upload your first certificate
Add a new certificate
Manage existing certificates
@@ -79,22 +79,22 @@
0
negotiable_quote_item,company_order_entity
15
-
- valid_address,original_address,error_message
- should_validate_address
- total_quantity,avatax_item_code,avatax_tax_code,avatax_description,avatax_ref1,avatax_ref2,hs_code,unit_name,unit_amount,pref_program_indicator
- avatax_response
- avatax_response
- avatax_is_unbalanced,base_avatax_tax_amount,avatax_response
- avatax_is_unbalanced,base_avatax_tax_amount,avatax_response
- rate_percent,tax_name,juris_code,taxable,tax
- hs_code,unit_name,unit_amount,pref_program_indicator
- hs_code,unit_name,unit_amount,pref_program_indicator
- hs_code,unit_name,unit_amount,pref_program_indicator
- hs_code,unit_name,unit_amount,pref_program_indicator
- avatax_messages
-
+
+ valid_address,original_address,error_message
+ should_validate_address
+ total_quantity,avatax_item_code,avatax_tax_code,avatax_description,avatax_ref1,avatax_ref2,hs_code,unit_name,unit_amount,pref_program_indicator
+ avatax_response
+ avatax_response
+ avatax_is_unbalanced,base_avatax_tax_amount,avatax_response
+ avatax_is_unbalanced,base_avatax_tax_amount,avatax_response
+ rate_percent,tax_name,juris_code,taxable,tax
+ hs_code,unit_name,unit_amount,pref_program_indicator
+ hs_code,unit_name,unit_amount,pref_program_indicator
+ hs_code,unit_name,unit_amount,pref_program_indicator
+ hs_code,unit_name,unit_amount,pref_program_indicator
+ avatax_messages
+
0
diff --git a/view/adminhtml/templates/form/field/company-code.phtml b/view/adminhtml/templates/form/field/company-code.phtml
index c8e67096..b2b54462 100644
--- a/view/adminhtml/templates/form/field/company-code.phtml
+++ b/view/adminhtml/templates/form/field/company-code.phtml
@@ -19,7 +19,7 @@
['form_key' => $this->getFormKey(), 'mode' => $this->getData('avatax_mode')]
); ?>
getData('company_code_group') ?>][groups][extension_mode][fields][getData(
'company_code_field'
) ?>][value]" value="" type="hidden">