- Installer for EU VAT rates with countries and zones
- New fields for VAT number at
AddressandShopBillingDataentity - Configure VAT number field requirement:
- Optional / Required
- Required if customer filled “Company” field
- Required in selected countries
- Validate VAT number:
- Revalidate customers VAT numbers after a given time
- Placing an order without VAT in the EU, if
- VAT number validation was successful
- Customers taxation country is different from shop billing country
composer require gewebe/sylius-vat-plugin# config/bundles.php
return [
# ...
Gewebe\SyliusVATPlugin\GewebeSyliusVATPlugin::class => ['all' => true],
];# config/packages/_sylius.yaml
imports:
# ...
- { resource: '@GewebeSyliusVATPlugin/config/config.yaml'}For EU VAT, the address for taxation should be set to the shipping address in the Sylius configuration.
# config/packages/_sylius.yaml
sylius_core:
shipping_address_based_taxation: true# src/Entity/Addressing/Address.php
namespace App\Entity\Addressing;
use Doctrine\ORM\Mapping as ORM;
use Gewebe\SyliusVATPlugin\Entity\VatNumberAddressInterface;
use Gewebe\SyliusVATPlugin\Entity\VatNumberAwareTrait;
use Sylius\Component\Core\Model\Address as BaseAddress;
/**
* @ORM\Entity
* @ORM\Table(name="sylius_address")
*/
#[ORM\Entity]
#[ORM\Table(name: 'sylius_address')]
class Address extends BaseAddress implements VatNumberAddressInterface
{
use VatNumberAwareTrait;If you use yaml mapping add also:
# config/doctrine/Address.orm.yaml
App\Entity\Addressing\Address:
type: entity
table: sylius_address
fields:
vatNumber:
type: string
column: vat_number
nullable: true
vatValid:
type: boolean
column: vat_valid
vatValidatedAt:
type: datetime
column: vat_validated_at
nullable: true# src/Entity/Channel/ShopBillingData.php
namespace App\Entity\Channel;
use Doctrine\ORM\Mapping as ORM;
use Gewebe\SyliusVATPlugin\Entity\ShopBillingDataVatNumberAwareTrait;
use Gewebe\SyliusVATPlugin\Entity\ShopBillingDataVatNumberInterface;
use Sylius\Component\Core\Model\ShopBillingData as BaseShopBillingData;
/**
* @ORM\Entity
* @ORM\Table(name="sylius_shop_billing_data")
*/
#[ORM\Entity]
#[ORM\Table(name: 'sylius_shop_billing_data')]
class ShopBillingData extends BaseShopBillingData implements ShopBillingDataVatNumberInterface
{
use ShopBillingDataVatNumberAwareTrait;If you use yaml mapping add also:
# config/doctrine/ShopBillingData.orm.yaml
App\Entity\Channel\ShopBillingData:
type: entity
table: sylius_shop_billing_data
fields:
vatNumber:
type: string
column: vat_number
nullable: trueOverride the resource for shop_billing_data in your sylius config:
# config/packages/_sylius.yaml
sylius_core:
resources:
shop_billing_data:
classes:
model: App\Entity\Channel\ShopBillingDatabin/console doctrine:migrations:diff
bin/console doctrine:migrations:migrate# EU VAT on digital services (MOSS scheme)
bin/console vat:install:eu
# EU with French VAT (cross-border)
bin/console vat:install:eu FR
# EU with French VAT and passed threshold in Spain and Portugal (cross-border)
bin/console vat:install:eu FR -t ES,PT
# EU with French VAT included in price
bin/console vat:install:eu FR -i
# EU with German standard and reduced VAT categories
bin/console vat:install:eu DE -c standard,reducedVAT numbers of addresses in the United Kingdom (country code GB) are validated against the
open access HMRC "Check a UK VAT number" API.
No credentials are required. The defaults can be changed in the application config:
# config/packages/_sylius.yaml
gewebe_sylius_vat:
hmrc:
enabled: true # disable to skip UK VAT number validation
base_url: 'https://api.service.hmrc.gov.uk' # https://test-api.service.hmrc.gov.uk for the sandbox
timeout: 10.0 # request timeout in seconds
countries: ['GB'] # countries validated with the HMRC APIAccepted formats are standard (GB123456789), branch traders (GB123456789001), government
departments (GBGD001) and health authorities (GBHA599); the GB prefix is optional.
Government department and health authority numbers cannot be looked up online and are therefore
only checked for their format.
If the HMRC service is unavailable a ClientException is thrown, which is handled by the
validate.on_service_unavailable setting, just like a VIES outage.
-
From the plugin skeleton root directory, run the following commands:
(cd vendor/sylius/test-application && yarn install) (cd vendor/sylius/test-application && yarn build) vendor/bin/console assets:install vendor/bin/console doctrine:database:create vendor/bin/console doctrine:migrations:migrate -n # Optionally load data fixtures vendor/bin/console sylius:fixtures:load -n
To be able to set up a plugin's database, remember to configure your database credentials in tests/TestApplication/.env and tests/TestApplication/.env.test.
-
Run your local server:
symfony server:ca:install symfony server:start -d
-
Open your browser and navigate to
https://localhost:8000.
-
Execute
make initto initialize the container and install the dependencies. -
Execute
make database-initto create the database and run migrations. -
(Optional) Execute
make load-fixturesto load the fixtures. -
Your app is available at
http://localhost.
-
PHPUnit
vendor/bin/phpunit
-
Behat (non-JS scenarios)
vendor/bin/behat --strict --tags="~@javascript&&~@mink:chromedriver" -
PHPStan - Static Analysis
vendor/bin/phpstan analyse -c phpstan.neon -l max src/
-
Coding Standard
vendor/bin/ecs check
-

