We have a single page checkout where the items are selected and addressed added before going to a cart summary page showing amount owed and tax due.
Was confused as to why certain codes were not working (checking validation against the service at https://ec.europa.eu/taxation_customs/vies/vatResponse.html) and realised the Craft Commerce submission requires the country ISO code as a prefix, eg a UK submission
166211234 needs to be
GB166211234. Similarly dots and spacesm, etc need to be stripped out. Unless these are in the correct format relevant rules (eg do not add VAT if valid VAT tax record is added will not kick in).
So as a means for preparing this data thought could tap into an event to update this value.
Addresses::EVENT_BEFORE_SAVE_ADDRESS event won't work as the update cart method/action saves the address after adding the line items and relevant calculations are made.
So then looked into the
LineItems::EVENT_POPULATE_LINE_ITEM event so can theoretically fetch and update the address associated with the cart/line item being saved (we are only ever adding one item to the cart at a time. If an item already exists in the cart then that is removed first.
The following code looked promising (would ideally like to limit to EU tax zone but for now assume all sales are EU):
// get line item $lineItem = $event->lineItem; // get order $order = $lineItem->order; // get billing address $billingAddress = $order->billingAddressId; // get billing address by ID $address = craftCommerce::getInstance()->getAddresses()->getAddressById($billingAddress); // get billing address tax ID $taxId = $address->businessTaxId; // get billing address country ID $countryId = $address->countryId; // get country ISO $country = craftCommerce::getInstance()->getCountries()->getCountryById($countryId); $countryIso = $country->iso; // strip non-alphanumeric characters from tax ID $cleanTax = preg_replace("/[^A-Za-z0-9 ]/", '', $taxId); // specify new, ideal tax ID $newTax = $countryIso . $cleanTax; // check if tax is specified, is not already optimised if not already changed if ($cleanTax !== '' && strpos($cleanTax,$countryIso) === false && $address->businessTaxId != $newTax) $address->businessTaxId = $newTax; // save the new address craftCommerce::getInstance()->getAddresses()->saveAddress($address, false);
However, whilst this saves the new address it doesn't update the existing one.
Any thoughts? Am I doing about this completely the wrong way. Would rather than do this in the front-end JS if at all possible.
Craft 188.8.131.52. Craft Commerce 3.1.12