FLUX-SE / SyliusEUVatPlugin

This Sylius Plugin allow you to add European VAT Number to the addresses and manage European VAT number rule
MIT License
16 stars 8 forks source link

Latest Version on Packagist Software License Build Status Quality Score

EU VAT field and validation for Sylius using VIES API Webservice

This plugin is adding :

Screenshots

Shop checkout

Shop checkout address step form

Shop checkout summary page

Shop account

Shop account address book

Shop account order details

Installation

composer require flux-se/sylius-eu-vat-plugin

Configuration

Enable this plugin :

<?php

# config/bundles.php

return [
    // ...
    FluxSE\SyliusEUVatPlugin\FluxSESyliusEUVatPlugin::class => ['all' => true],
    // ...
];

Add default config if you want to get access to the default fixtures this plugin need.

# config/packages/flux_se_sylius_eu_vat.yaml

imports:
    - { resource: "@FluxSESyliusEUVatPlugin/config/config.yaml" }
    # If you are using SyliusAdminBundle
    - { resource: "@FluxSESyliusEUVatPlugin/config/admin.yaml" }

Copy Sylius overridden templates to your templates directory (e.g templates/bundles/):

# If you are using SyliusAdminBundle
mkdir -p templates/bundles/SyliusAdminBundle/
cp -R vendor/flux-se/sylius-eu-vat-plugin/templates/SyliusAdminBundle/* templates/bundles/SyliusAdminBundle/

# If you are using SyliusShopBundle
mkdir -p templates/bundles/SyliusShopBundle/
cp -R vendor/flux-se/sylius-eu-vat-plugin/templates/SyliusShopBundle/* templates/bundles/SyliusShopBundle/

Update Channel entity : src/Entity/Channel/Channel.php

<?php

declare(strict_types=1);

namespace App\Entity\Channel;

use Doctrine\ORM\Mapping as ORM;
use FluxSE\SyliusEUVatPlugin\Entity\EuropeanChannelAwareTrait;
use Sylius\Component\Core\Model\Channel as BaseChannel;

/**
 * @ORM\Entity()
 * @ORM\Table(name="sylius_channel")
 */
#[ORM\Entity]
#[ORM\Table(name: 'sylius_channel')]
class Channel extends BaseChannel implements ChannelInterface
{
    use EuropeanChannelAwareTrait;
}

And the corresponding interface : src/Entity/Channel/ChannelInterface.php

<?php

declare(strict_types=1);

namespace App\Entity\Channel;

use FluxSE\SyliusEUVatPlugin\Entity\EuropeanChannelAwareInterface;
use Sylius\Component\Core\Model\ChannelInterface as BaseChannelInterface;

interface ChannelInterface extends BaseChannelInterface, EuropeanChannelAwareInterface
{
}
Click me : if you are using YAML ORM definitions ```yaml # config/doctrine/Address.orm.yml App\Entity\Adressing\Address : type: entity table: sylius_address fields: vatNumber: name: vat_number type: string nullable: true ```

Then change the default Sylius model class :

# config/packages/sylius_channel.yaml

sylius_channel:
    resources:
        channel:
            classes:
                model: App\Entity\Channel\Channel

Update Address entity : src/Entity/Addressing/Address.php

<?php

declare(strict_types=1);

namespace App\Entity\Addressing;

use Doctrine\ORM\Mapping as ORM;
use FluxSE\SyliusEUVatPlugin\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 AddressInterface
{
    use VATNumberAwareTrait;
}

And the corresponding interface : src/Entity/Addressing/AddressInterface.php

<?php

declare(strict_types=1);

namespace App\Entity\Addressing;

use FluxSE\SyliusEUVatPlugin\Entity\VATNumberAwareInterface;
use Sylius\Component\Core\Model\AddressInterface as BaseAddressInterface;

interface AddressInterface extends BaseAddressInterface, VATNumberAwareInterface
{
}
Click me : if you are using YAML ORM definitions ```yaml # config/doctrine/Channel.orm.yml App\Entity\Channel\Channel: type: entity table: sylius_channel manyToOne: baseCountry: targetEntity: Sylius\Component\Addressing\Model\CountryInterface fetch: EAGER joinColumn: name: base_country_id onDelete: "SET NULL" europeanZone: targetEntity: Sylius\Component\Addressing\Model\ZoneInterface fetch: EAGER joinColumn: name: european_zone_id onDelete: "SET NULL" ```

Then change the default Sylius model class :

# config/packages/sylius_addressing.yaml

sylius_addressing:
    resources:
        address:
            classes:
                model: App\Entity\Addressing\Address

Update your database :

# This bundle use doctrine migrations ^3 (see `src/Migrations` folder for more details)
php ./bin/console doctrine:migrations:migrate

Load some required fixtures :

./bin/console sylius:fixture:load european_vat_zones

Go to your admin panel and edit your Channel to set the two fields to indicate to this plugin :

  1. What is your base country to compare to your customer country.
  2. What is the European zone to know if the customer is part of the Europe or not.

Fixtures

You can add some fixtures to auto-configure your channel, for example add this into a yaml file :

# config/packages/my_fixtures.yaml

sylius_fixtures:
    suites:

        french_european_channel:    

            listeners:
                logger: ~

            fixtures:

                address_with_vat_number:
                    options:
                        custom:
                            my_customer:
                                first_name: "John"
                                last_name: "Doe"
                                phone_number: "+33912345678"
                                company: "My Company Inc."
                                street: "1234 Street Avenue"
                                city: "London"
                                postcode: "1234"
                                country_code: "GB"
                                customer: "john.doe@mycompany.com"
                                vat_number: ~ # could also be "GB123456789"

                eu_vat_plugin_european_channel:
                    options:
                        custom:
                            default:
                                channel: "default_channel_code" # Put an existing Channel code
                                base_country: "FR" # Existing Country code
                                european_zone: "EU" # Existing Zone code

API