(v3) Internals' Documentation - lat9/vat4eu GitHub Wiki

Design Notes

This article identifies the various changes provided by VAT4EU versions prior to v4.0.0.

Storefront Changes

VAT4EU provides

  • The gathering of a business customer's VAT Number, possibly to provide a means for a store to provide a VAT refund to that business customer.
  • Inclusion of the customer's entered VAT Number in various displays of a formatted address.
  • Order-total modules (ot_vat_refund and ot_var_reverse_charges) that identify that a VAT Refund is provided to a customer's order and instructions regarding those reverse-charges, respectively.

Gathering a VAT Number

VAT4EU assumes that any VAT Number gathered is associated with a business customer's account, since a VAT refund is available for B2B purchases only. As such, the modification required to various address-gathering pages should be placed within the Company block of the page's template and should be accompanied by the setting of Configuration :: Customer Details :: Company to true. Here's the common snippet to be included in those pages' templates:

//-bof-vat4eu-lat9  *** 1 of 1 ***
    include $template->get_template_dir('tpl_modules_vat4eu_display.php', DIR_WS_TEMPLATE, $current_page_base, 'templates') . '/tpl_modules_vat4eu_display.php'; 
//-eof-vat4eu-lat9  *** 1 of 1 ***

The use of include instead of require is intentional, so that the associated page will still load, albeit with a PHP Warning, if the VAT4EU module is not present on the site!

VAT4EU supports, via its auto-loaded observer, the addition of a VAT Number entry on the following pages:

  • address_book_process, where the customer can provide a new or change an existing VAT Number.
  • checkout_one, where a customer can update the VAT Number on their current billing address or provide a VAT Number when creating a new permanent address. VAT Numbers aren't saved for temporary addresses, since there's no way for the site admin to make modifications once the order is placed!
  • checkout_payment_address, where the customer can include a VAT Number in a newly-registered payment address.
  • create_account, where a new customer can include a VAT Number at initial registration.
  • login, when the site has chosen to include the create_account processing as part of that page.

Adding a VAT Number to a Formatted Address

VAT4EU's auto-loaded observer watches for calls to zen_address_format on specific pages to provide any VAT Number addition to the requested address' formatting. If the address-array provided to that function contains a VAT Number, that value is conditionally (see below) appended to the formatted version of the address. That "incoming" address is provided in the 'address' element of the first (read-only) parameter provided by the function's NOTIFY_END_ZEN_ADDRESS_FORMAT notification.

Note: An installation of VAT4EU on a zc158a base requires core-file changes, the first as in zc200 via this merged PR. You'll need to edit the zc158a version of /includes/classes/Customer.php, changing the SQL query in getFormattedAddressBookList from

        $sql = "SELECT address_book_id,
                       entry_firstname AS firstname, entry_lastname AS lastname,
                       entry_company AS company, entry_street_address AS street_address,
                       entry_suburb AS suburb, entry_city AS city, entry_postcode AS postcode,
                       entry_state AS state,
                       entry_zone_id AS zone_id,
                       zone_name, zone_code AS zone_iso,
                       entry_country_id AS country_id,
                       countries_name AS country_name,
                       countries_iso_code_3 AS country_iso
                FROM " . TABLE_ADDRESS_BOOK . " ab
                INNER JOIN " . TABLE_COUNTRIES . " c ON (ab.entry_country_id=c.countries_id)
                LEFT JOIN " . TABLE_ZONES . " z ON (ab.entry_zone_id=z.zone_id AND z.zone_country_id=c.countries_id)
                WHERE customers_id = :customersID
                ORDER BY firstname, lastname";

to

        $sql = "SELECT ab.*,
                       entry_firstname AS firstname, entry_lastname AS lastname,
                       entry_company AS company, entry_street_address AS street_address,
                       entry_suburb AS suburb, entry_city AS city, entry_postcode AS postcode,
                       entry_state AS state,
                       entry_zone_id AS zone_id,
                       zone_name, zone_code AS zone_iso,
                       entry_country_id AS country_id,
                       countries_name AS country_name,
                       countries_iso_code_3 AS country_iso
                FROM " . TABLE_ADDRESS_BOOK . " ab
                INNER JOIN " . TABLE_COUNTRIES . " c ON (ab.entry_country_id=c.countries_id)
                LEFT JOIN " . TABLE_ZONES . " z ON (ab.entry_zone_id=z.zone_id AND z.zone_country_id=c.countries_id)
                WHERE customers_id = :customersID
                ORDER BY firstname, lastname";

An additional change, identified in this Zen Cart PR is to maintain those values on the zen_address_format function's notification. You'll need to edit /includes/functions/functions_addresses.php, finding the following line in the zen_address_format function:

    // store translated values into original array, just for the sake of the notifier
    $incoming = $address;

and changing it to:

    // store translated values into original array, just for the sake of the notifier
    $incoming = array_merge($incoming, $address);

Without those changes, VAT Numbers will not be included in a formatted address' output on zc158a!

account_history_info and checkout_success Pages

The billing-address' formatting contains the VAT Number, if recorded as part of the order's billing address.

address_book Page

Each request to zen_address_format contains an address' VAT Number, if supplied.

checkout_confirmation, checkout_one_confirmation and checkout_process Pages

If the formatting request is for the current $_SESSION['billto'], the formatted output includes any associated VAT Number. This is used on the checkout_process page to include the VAT Number in the to-be-generated order-confirmation email.

checkout_one Page

If the formatting request is issued in the presence of global $which; and $which is set to 'bill' (indicating that the bill-to section of the OPC addresses is being formatted), any formatted address is appended with its VAT Number. Noting that the zen_address_format might be called multiple times, once for the currently-selected address' format and once for each address in the customer's address_book for the drop-down selection of additional addresses.

Note: VAT Numbers are supported only for account-holders using permanent addresses!

checkout_payment and checkout_payment_address Pages

The Billing Address' format contains, if present, the associated VAT Number.

create_account_success Page

The customer's newly-created primary address contains its VAT Number, if supplied on the create_account page's form.

Order-Total Modules

ot_vat_refund

A VAT refund is applied to the order if all of the following are true:

  1. A validated VAT Number is associated with the order's billing address.
  2. For non-virtual orders, the country to which the order is being shipped is in the list of configured EU countries.
  3. The ship-to country is either not the country from which the order is shipped (STORE_COUNTRY) or VAT refunds are enabled for in-country purchases.

If applied, the VAT refund (essentially refunding the order's tax) is subtracted from the order's total.

ot_vat_reverse_charges

If the VAT is refundable, see above, this module displays explanatory text regarding the VAT reverse charges.