moduleDataSetup; $connection = $setup->getConnection(); $setup->startSetup(); $taxClassTable = $setup->getTable('tax_class'); $rateTable = $setup->getTable('tax_calculation_rate'); $ruleTable = $setup->getTable('tax_calculation_rule'); $calculationTable = $setup->getTable('tax_calculation'); $this->ensureTaxClass($taxClassTable, self::EXEMPT_TAX_CLASS, 'CUSTOMER'); $customerClassIds = array_map('intval', $connection->fetchCol( $connection->select()->from($taxClassTable, 'class_id')->where('class_type = ?', 'CUSTOMER') )); $productClassIds = array_map('intval', $connection->fetchCol( $connection->select()->from($taxClassTable, 'class_id')->where('class_type = ?', 'PRODUCT') )); $euStandardRule = $this->ensureRule( $ruleTable, 'eSUN EU Calculated VAT', ['eSUN EU Standard VAT 19'] ); $ukRule = $this->ensureRule($ruleTable, 'eSUN UK VAT 20'); $legacyRuleIds = array_map('intval', $connection->fetchCol( $connection->select()->from($ruleTable, 'tax_calculation_rule_id') ->where('code IN (?)', ['eSUN EU VAT Exempt 0']) )); $connection->delete( $calculationTable, ['tax_calculation_rule_id IN (?)' => array_merge([$euStandardRule, $ukRule], $legacyRuleIds)] ); foreach (EuCountries::CODES as $countryId) { $nominalRate = EuCountries::RATES[$countryId] ?? 19.0; $standardRateId = $this->ensureRate( $rateTable, sprintf('ESUN-EU-%s-NOMINAL-%s', $countryId, (int)$nominalRate), $countryId, EuCountries::toAppliedRate($nominalRate) ); $this->link($calculationTable, $standardRateId, $euStandardRule, $customerClassIds, $productClassIds); } $ukRateId = $this->ensureRate( $rateTable, 'ESUN-GB-NOMINAL-20', 'GB', EuCountries::toAppliedRate(20.0) ); $this->link($calculationTable, $ukRateId, $ukRule, $customerClassIds, $productClassIds); // The database initially contains Magento sample US state tax data. These markets must be tax-free. $noTaxRateIds = $connection->fetchCol( $connection->select()->from($rateTable, 'tax_calculation_rate_id')->where('tax_country_id IN (?)', ['US', 'CA', 'AU']) ); if ($noTaxRateIds) { $connection->delete($calculationTable, ['tax_calculation_rate_id IN (?)' => $noTaxRateIds]); } $this->configureWebsites(); $setup->endSetup(); return $this; } private function ensureTaxClass(string $table, string $name, string $type): int { $connection = $this->moduleDataSetup->getConnection(); $id = $connection->fetchOne($connection->select()->from($table, 'class_id') ->where('class_name = ?', $name)->where('class_type = ?', $type)); if ($id) { return (int)$id; } $connection->insert($table, ['class_name' => $name, 'class_type' => $type]); return (int)$connection->lastInsertId($table); } private function ensureRate(string $table, string $code, string $countryId, float $rate): int { $connection = $this->moduleDataSetup->getConnection(); $id = $connection->fetchOne($connection->select()->from($table, 'tax_calculation_rate_id')->where('code = ?', $code)); $data = ['tax_country_id' => $countryId, 'tax_region_id' => 0, 'tax_postcode' => '*', 'code' => $code, 'rate' => $rate, 'zip_is_range' => null, 'zip_from' => null, 'zip_to' => null]; if ($id) { $connection->update($table, $data, ['tax_calculation_rate_id = ?' => (int)$id]); return (int)$id; } $connection->insert($table, $data); return (int)$connection->lastInsertId($table); } private function ensureRule(string $table, string $code, array $legacyCodes = []): int { $connection = $this->moduleDataSetup->getConnection(); $id = $connection->fetchOne( $connection->select()->from($table, 'tax_calculation_rule_id') ->where('code IN (?)', array_merge([$code], $legacyCodes)) ->order('tax_calculation_rule_id ASC') ); if ($id) { $connection->update($table, ['code' => $code], ['tax_calculation_rule_id = ?' => (int)$id]); return (int)$id; } $connection->insert($table, ['code' => $code, 'priority' => 0, 'position' => 0, 'calculate_subtotal' => 0]); return (int)$connection->lastInsertId($table); } private function link(string $table, int $rateId, int $ruleId, array $customerClassIds, array $productClassIds): void { $rows = []; foreach ($customerClassIds as $customerClassId) { foreach ($productClassIds as $productClassId) { $rows[] = ['tax_calculation_rate_id' => $rateId, 'tax_calculation_rule_id' => $ruleId, 'customer_tax_class_id' => $customerClassId, 'product_tax_class_id' => $productClassId]; } } if ($rows) { $this->moduleDataSetup->getConnection()->insertMultiple($table, $rows); } } private function configureWebsites(): void { $connection = $this->moduleDataSetup->getConnection(); $websiteTable = $this->moduleDataSetup->getTable('store_website'); $configTable = $this->moduleDataSetup->getTable('core_config_data'); $countries = [ 'eu' => 'DE', 'eu_site' => 'DE', 'uk' => 'GB', 'gb_site' => 'GB', 'us_site' => 'US', 'au' => 'AU', 'au_site' => 'AU', ]; foreach ($countries as $websiteCode => $countryId) { $websiteId = (int)$connection->fetchOne( $connection->select()->from($websiteTable, 'website_id')->where('code = ?', $websiteCode) ); if (!$websiteId) { continue; } $values = [ 'tax/calculation/price_includes_tax' => '0', 'tax/calculation/shipping_includes_tax' => '0', 'tax/calculation/based_on' => 'shipping', 'tax/calculation/cross_border_trade_enabled' => '1', 'tax/calculation/apply_after_discount' => '1', 'tax/defaults/country' => $countryId, 'tax/display/type' => '1', 'tax/cart_display/price' => '1', 'tax/cart_display/subtotal' => '1', 'tax/cart_display/shipping' => '1', 'tax/sales_display/price' => '1', 'tax/sales_display/subtotal' => '1', 'tax/sales_display/shipping' => '1', ]; foreach ($values as $path => $value) { $connection->insertOnDuplicate($configTable, ['scope' => 'websites', 'scope_id' => $websiteId, 'path' => $path, 'value' => $value], ['value']); } } } public static function getDependencies(): array { return []; } public function getAliases(): array { return []; } }