public function resolve(TaxableInterface $taxable, Context $context)
{
$taxTypes = $this->getTaxTypes();
$customerAddress = $context->getCustomerAddress();
$customerCountry = $customerAddress->getCountryCode();
$customerTaxTypes = $this->filterByAddress($taxTypes, $customerAddress);
if (empty($customerTaxTypes)) {
// The customer is not in the EU.
return [];
}
$storeAddress = $context->getStoreAddress();
$storeCountry = $storeAddress->getCountryCode();
$storeTaxTypes = $this->filterByAddress($taxTypes, $storeAddress);
$storeRegistrationTaxTypes = $this->filterByStoreRegistration($taxTypes, $context);
if (empty($storeTaxTypes) && empty($storeRegistrationTaxTypes)) {
// The store is not in the EU nor registered to collect EU VAT.
return [];
}
$customerTaxNumber = $context->getCustomerTaxNumber();
// Since january 1st 2015 all digital services sold to EU customers
// must apply the destination tax type(s). For example, an ebook sold
// to Germany needs to have German VAT applied.
$isDigital = $context->getDate()->format('Y') >= '2015' && !$taxable->isPhysical();
$resolvedTaxTypes = [];
if (empty($storeTaxTypes) && !empty($storeRegistrationTaxTypes)) {
// The store is not in the EU but is registered to collect VAT.
// This VAT is only charged on B2C digital services.
$resolvedTaxTypes = self::NO_APPLICABLE_TAX_TYPE;
if ($isDigital && !$customerTaxNumber) {
$resolvedTaxTypes = $customerTaxTypes;
}
} elseif ($customerTaxNumber && $customerCountry != $storeCountry) {
// Intra-community supply (B2B).
$icTaxType = $this->taxTypeRepository->get('eu_ic_vat');
$resolvedTaxTypes = [$icTaxType];
} elseif ($isDigital) {
$resolvedTaxTypes = $customerTaxTypes;
} else {
// Physical products use the origin tax types, unless the store is
// registered to pay taxes in the destination zone. This is required
// when the total yearly transactions breach the defined threshold.
// See http://www.vatlive.com/eu-vat-rules/vat-registration-threshold/
$resolvedTaxTypes = $storeTaxTypes;
$customerTaxType = reset($customerTaxTypes);
if ($this->checkStoreRegistration($customerTaxType->getZone(), $context)) {
$resolvedTaxTypes = $customerTaxTypes;
}
}
return $resolvedTaxTypes;
}