From 78814e56b88360b73b7ceec2a7391f052689bec2 Mon Sep 17 00:00:00 2001 From: Lorenzo Ruozzi Date: Tue, 10 Feb 2026 12:56:10 +0100 Subject: [PATCH 01/10] Update actions --- .github/workflows/build.yml | 50 ++++++++++++++++--------------------- 1 file changed, 21 insertions(+), 29 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index d20e138..1ef5c64 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -6,7 +6,7 @@ on: - 'dependabot/**' pull_request: ~ release: - types: [created] + types: [ created ] schedule: - cron: "0 1 * * 6" # Run at 1am every Saturday @@ -21,11 +21,11 @@ jobs: strategy: fail-fast: false matrix: - php: ["8.4"] - symfony: ["^7.3"] - sylius: ["~2.2.0"] - node: ["22.x"] - mysql: ["8.4"] + php: [ "8.3", "8.4" ] + symfony: [ "^7.4" ] + sylius: [ "~2.2.1" ] + node: [ "22.x" ] + mysql: [ "8.4" ] env: APP_ENV: test @@ -42,7 +42,7 @@ jobs: with: php-version: "${{ matrix.php }}" extensions: intl - tools: flex,symfony + tools: flex, symfony coverage: none - @@ -66,10 +66,6 @@ jobs: name: Output PHP version for Symfony CLI run: php -v | head -n 1 | awk '{ print $2 }' > .php-version - - - name: Validate composer.json - run: composer validate --ansi --strict - - name: Get Composer cache directory id: composer-cache @@ -102,11 +98,7 @@ jobs: run: composer install --no-interaction - - name: Validate container - run: vendor/bin/console lint:container - - - - name: Run ECS + name: RUN EasyCodingStandard run: vendor/bin/ecs check - @@ -117,10 +109,6 @@ jobs: name: Run Psalm run: vendor/bin/psalm - - - name: Run PHPSpec - run: vendor/bin/phpspec run --ansi -f progress --no-interaction - - name: Run unit tests run: vendor/bin/phpunit --colors=always --testsuite=unit @@ -149,10 +137,6 @@ jobs: (vendor/bin/console doctrine:database:create -vvv) (vendor/bin/console doctrine:schema:create -vvv) - - - name: Validate database schema - run: vendor/bin/console doctrine:schema:validate - - name: Prepare test application assets run: | @@ -168,24 +152,32 @@ jobs: run: vendor/bin/console sylius:fixtures:load -n - - name: Run Non-unit PHPUnit tests - run: vendor/bin/phpunit --colors=always --testsuite=non-unit + name: Validate composer.json + run: composer validate --ansi --strict - - name: Install certificates - run: symfony server:ca:install || true + name: Validate container + run: vendor/bin/console lint:container + + - + name: Run Non-unit PHPUnit tests + run: vendor/bin/phpunit --colors=always --testsuite=non-unit - name: Run Chrome Headless run: google-chrome-stable --enable-automation --disable-background-networking --no-default-browser-check --no-first-run --disable-popup-blocking --disable-default-apps --allow-insecure-localhost --disable-translate --disable-extensions --no-sandbox --enable-features=Metal --headless --remote-debugging-port=9222 --window-size=2880,1800 --proxy-server='direct://' --proxy-bypass-list='*' http://127.0.0.1 > /dev/null 2>&1 & + - + name: Install certificates + run: symfony server:ca:install || true + - name: Run webserver run: symfony server:start --port=8080 --daemon - name: Run Behat - run: vendor/bin/behat --colors --strict -vvv --no-interaction || vendor/bin/behat --colors --strict -vvv --no-interaction --rerun + run: vendor/bin/behat --colors --strict -vvv --no-interaction -f progress || vendor/bin/behat --colors --strict -vvv --no-interaction -f progress --rerun - name: Upload Behat logs From 29656b380ccc0dfdc6049e63e14e05112ceddfbb Mon Sep 17 00:00:00 2001 From: Lorenzo Ruozzi Date: Tue, 10 Feb 2026 14:24:23 +0100 Subject: [PATCH 02/10] Use php file loader --- config/config.yaml | 1 + config/services.php | 9 ++++++ config/services.yaml | 2 -- config/services/comparator.php | 18 +++++++++++ config/services/form.php | 18 +++++++++++ config/services/modifier.php | 15 +++++++++ config/services/services.yaml | 31 ------------------- config/services/strategy.php | 26 ++++++++++++++++ config/services/validator.php | 13 ++++++++ config/twig_hooks/.gitignore | 0 ...nInvoiceableAddressComparatorDecorator.php | 5 +-- ...SyliusItalianInvoiceableOrderExtension.php | 6 ++-- 12 files changed, 106 insertions(+), 38 deletions(-) create mode 100644 config/services.php delete mode 100644 config/services.yaml create mode 100644 config/services/comparator.php create mode 100644 config/services/form.php create mode 100644 config/services/modifier.php delete mode 100644 config/services/services.yaml create mode 100644 config/services/strategy.php create mode 100644 config/services/validator.php delete mode 100644 config/twig_hooks/.gitignore diff --git a/config/config.yaml b/config/config.yaml index d2a2a46..513c04b 100644 --- a/config/config.yaml +++ b/config/config.yaml @@ -3,3 +3,4 @@ imports: parameters: sylius.form.type.address.validation_groups: [ 'Default' ] + app.taxation.eu_zone_code: 'EU' diff --git a/config/services.php b/config/services.php new file mode 100644 index 0000000..8cc3ee1 --- /dev/null +++ b/config/services.php @@ -0,0 +1,9 @@ +import('services/*.php'); +}; diff --git a/config/services.yaml b/config/services.yaml deleted file mode 100644 index 94946d5..0000000 --- a/config/services.yaml +++ /dev/null @@ -1,2 +0,0 @@ -imports: - - { resource: "services/**/*.yaml" } diff --git a/config/services/comparator.php b/config/services/comparator.php new file mode 100644 index 0000000..d4207d3 --- /dev/null +++ b/config/services/comparator.php @@ -0,0 +1,18 @@ +services(); + + $services->set('webgriffe_sylius_italian_invoiceable_order.address_comparator', ItalianInvoiceableAddressComparatorDecorator::class) + ->decorate('sylius.comparator.address') + ->args([ + service('.inner'), + ]) + ; +}; diff --git a/config/services/form.php b/config/services/form.php new file mode 100644 index 0000000..12180d6 --- /dev/null +++ b/config/services/form.php @@ -0,0 +1,18 @@ +services(); + + $services->set('webgriffe_sylius_italian_invoiceable_order.form.extension.italian_invoiceable_address', ItalianInvoiceableAddressTypeExtension::class) + ->tag('form.type_extension', [ + 'extended_type' => AddressType::class, + ]) + ; +}; diff --git a/config/services/modifier.php b/config/services/modifier.php new file mode 100644 index 0000000..5464f30 --- /dev/null +++ b/config/services/modifier.php @@ -0,0 +1,15 @@ +services(); + + $services->set('webgriffe_sylius_italian_invoiceable_order.modifier.address_form_values', AddressFormValuesModifier::class) + ->tag('sylius_shop.modifier.address_form_values') + ; +}; diff --git a/config/services/services.yaml b/config/services/services.yaml deleted file mode 100644 index 7ea3265..0000000 --- a/config/services/services.yaml +++ /dev/null @@ -1,31 +0,0 @@ -parameters: - app.taxation.eu_zone_code: 'EU' - -services: - webgriffe_sylius_italian_invoiceable_order.form.extension.italian_invoiceable_address: - class: Webgriffe\SyliusItalianInvoiceableOrderPlugin\Form\Extension\ItalianInvoiceableAddressTypeExtension - tags: - - { name: form.type_extension, extended_type: Sylius\Bundle\AddressingBundle\Form\Type\AddressType } - - webgriffe_sylius_italian_invoiceable_order.address_comparator: - class: Webgriffe\SyliusItalianInvoiceableOrderPlugin\Comparator\ItalianInvoiceableAddressComparatorDecorator - decorates: sylius.comparator.address - arguments: - - '@webgriffe_sylius_italian_invoiceable_order.address_comparator.inner' - - app.taxation.italian_tax_calculation_strategy: - class: Webgriffe\SyliusItalianInvoiceableOrderPlugin\Model\ItalianTaxCalculationStrategy - arguments: - - 'italian_tax_calculation_strategy' - - [ - '@sylius.applicator.taxation.order_item_units', - '@sylius.applicator.taxation.order_shipment' - ] - - '%app.taxation.eu_zone_code%' - tags: - - { name: sylius.taxation.calculation_strategy, type: italian_tax_calculation_strategy, label: 'Italian tax calculation' } - - webgriffe_sylius_italian_invoiceable_order.modifier.address_form_values: - class: Webgriffe\SyliusItalianInvoiceableOrderPlugin\Modifier\AddressFormValuesModifier - tags: - - { name: sylius_shop.modifier.address_form_values } diff --git a/config/services/strategy.php b/config/services/strategy.php new file mode 100644 index 0000000..497b712 --- /dev/null +++ b/config/services/strategy.php @@ -0,0 +1,26 @@ +services(); + + $services->set('app.taxation.italian_tax_calculation_strategy', ItalianTaxCalculationStrategy::class) + ->args([ + 'italian_tax_calculation_strategy', + [ + service('sylius.applicator.taxation.order_item_units'), + service('sylius.applicator.taxation.order_shipment'), + ], + param('app.taxation.eu_zone_code'), + ]) + ->tag('sylius.taxation.calculation_strategy', [ + 'type' => 'italian_tax_calculation_strategy', + 'label' => 'Italian tax calculation', + ]) + ; +}; diff --git a/config/services/validator.php b/config/services/validator.php new file mode 100644 index 0000000..226f4fc --- /dev/null +++ b/config/services/validator.php @@ -0,0 +1,13 @@ +services(); + + $services->set('webgriffe.sylius_elasticsearch_plugin.validator.request', RequestValidator::class); +}; diff --git a/config/twig_hooks/.gitignore b/config/twig_hooks/.gitignore deleted file mode 100644 index e69de29..0000000 diff --git a/src/Comparator/ItalianInvoiceableAddressComparatorDecorator.php b/src/Comparator/ItalianInvoiceableAddressComparatorDecorator.php index 15930cc..8d0cb37 100644 --- a/src/Comparator/ItalianInvoiceableAddressComparatorDecorator.php +++ b/src/Comparator/ItalianInvoiceableAddressComparatorDecorator.php @@ -10,8 +10,9 @@ final class ItalianInvoiceableAddressComparatorDecorator implements AddressComparatorInterface { - public function __construct(private AddressComparatorInterface $defaultAddressComparator) - { + public function __construct( + private AddressComparatorInterface $defaultAddressComparator, + ) { } #[\Override] diff --git a/src/DependencyInjection/WebgriffeSyliusItalianInvoiceableOrderExtension.php b/src/DependencyInjection/WebgriffeSyliusItalianInvoiceableOrderExtension.php index 0cb99ee..87b84e0 100644 --- a/src/DependencyInjection/WebgriffeSyliusItalianInvoiceableOrderExtension.php +++ b/src/DependencyInjection/WebgriffeSyliusItalianInvoiceableOrderExtension.php @@ -9,7 +9,7 @@ use Symfony\Component\Config\FileLocator; use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\DependencyInjection\Extension\PrependExtensionInterface; -use Symfony\Component\DependencyInjection\Loader\YamlFileLoader; +use Symfony\Component\DependencyInjection\Loader\PhpFileLoader; final class WebgriffeSyliusItalianInvoiceableOrderExtension extends AbstractResourceExtension implements PrependExtensionInterface { @@ -18,9 +18,9 @@ final class WebgriffeSyliusItalianInvoiceableOrderExtension extends AbstractReso #[\Override] public function load(array $configs, ContainerBuilder $container): void { - $loader = new YamlFileLoader($container, new FileLocator(__DIR__ . '/../../config')); + $loader = new PhpFileLoader($container, new FileLocator(__DIR__ . '/../../config')); - $loader->load('services.yaml'); + $loader->load('services.php'); } #[\Override] From 2ccb1cf5fd86fd5595dcc59484a072f95e109b97 Mon Sep 17 00:00:00 2001 From: Lorenzo Ruozzi Date: Tue, 10 Feb 2026 14:28:56 +0100 Subject: [PATCH 03/10] Fix Psalm --- psalm.xml | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/psalm.xml b/psalm.xml index 5611b5f..09bb495 100644 --- a/psalm.xml +++ b/psalm.xml @@ -5,7 +5,6 @@ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="https://getpsalm.org/schema/config" xsi:schemaLocation="https://getpsalm.org/schema/config vendor/vimeo/psalm/config.xsd" - phpVersion="8.4" > @@ -13,10 +12,14 @@ - - - var/cache/dev/Sylius_TestApplication_KernelDevDebugContainer.xml - var/cache/test/Sylius_TestApplication_KernelTestDebugContainer.xml - - + + + + + + + + + + From 0ea25d3ea377c3cbe964fd1c14af1da5db497dcb Mon Sep 17 00:00:00 2001 From: Lorenzo Ruozzi Date: Tue, 10 Feb 2026 14:37:27 +0100 Subject: [PATCH 04/10] Temp fix for CI --- composer.json | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/composer.json b/composer.json index f6a668b..3a56077 100644 --- a/composer.json +++ b/composer.json @@ -30,6 +30,7 @@ "friends-of-behat/suite-settings-extension": "^1.1", "friends-of-behat/symfony-extension": "^2.6", "friends-of-behat/variadic-extension": "^1.6", + "payum/payum-bundle": "2.6.*", "phpspec/phpspec": "^8.0", "phpstan/extension-installer": "^1.0", "phpstan/phpstan": "^1.12", @@ -44,13 +45,13 @@ "sylius-labs/suite-tags-extension": "~0.2", "sylius/sylius-rector": "^2.0", "sylius/test-application": "^2.0.0@alpha", - "symfony/browser-kit": "^6.4 || ^7.1", - "symfony/debug-bundle": "^6.4 || ^7.1", - "symfony/dotenv": "^6.4 || ^7.1", - "symfony/http-client": "^6.4 || ^7.1", - "symfony/intl": "^6.4 || ^7.1", - "symfony/runtime": "^6.4 || ^7.1", - "symfony/web-profiler-bundle": "^6.4 || ^7.1", + "symfony/browser-kit": "^6.4 || ^7.4", + "symfony/debug-bundle": "^6.4 || ^7.4", + "symfony/dotenv": "^6.4 || ^7.4", + "symfony/http-client": "^6.4 || ^7.4", + "symfony/intl": "^6.4 || ^7.4", + "symfony/runtime": "^6.4 || ^7.4", + "symfony/web-profiler-bundle": "^6.4 || ^7.4", "symfony/webpack-encore-bundle": "^2.2", "vimeo/psalm": "^6.13" }, From 2b98b57cbbdd8d2e325618743b5e304724b287cd Mon Sep 17 00:00:00 2001 From: Lorenzo Ruozzi Date: Tue, 10 Feb 2026 14:56:47 +0100 Subject: [PATCH 05/10] Rename class and service --- UPGRADE.md | 7 +++++++ config/services/{strategy.php => taxation.php} | 9 +++------ .../ItalianTaxCalculationStrategy.php | 3 ++- 3 files changed, 12 insertions(+), 7 deletions(-) create mode 100644 UPGRADE.md rename config/services/{strategy.php => taxation.php} (64%) rename src/{Model => Taxation}/ItalianTaxCalculationStrategy.php (95%) diff --git a/UPGRADE.md b/UPGRADE.md new file mode 100644 index 0000000..ed2c0e7 --- /dev/null +++ b/UPGRADE.md @@ -0,0 +1,7 @@ +# Upgrade plugin guide + +## Upgrade from version 1.x to 2.x + +- The service `app.taxation.italian_tax_calculation_strategy` has been renamed to `webgriffe_sylius_italian_invoiceable_order.strategy.taxation.tax_calculation.italian_tax_calculation_strategy`. +- The class `Webgriffe\SyliusItalianInvoiceableOrderPlugin\Model\ItalianTaxCalculationStrategy` has been moved to `Webgriffe\SyliusItalianInvoiceableOrderPlugin\Taxation\ItalianTaxCalculationStrategy`. +- diff --git a/config/services/strategy.php b/config/services/taxation.php similarity index 64% rename from config/services/strategy.php rename to config/services/taxation.php index 497b712..20fac86 100644 --- a/config/services/strategy.php +++ b/config/services/taxation.php @@ -4,18 +4,15 @@ namespace Symfony\Component\DependencyInjection\Loader\Configurator; -use Webgriffe\SyliusItalianInvoiceableOrderPlugin\Model\ItalianTaxCalculationStrategy; +use Webgriffe\SyliusItalianInvoiceableOrderPlugin\Taxation\ItalianTaxCalculationStrategy; return static function (ContainerConfigurator $containerConfigurator) { $services = $containerConfigurator->services(); - $services->set('app.taxation.italian_tax_calculation_strategy', ItalianTaxCalculationStrategy::class) + $services->set('webgriffe_sylius_italian_invoiceable_order.strategy.taxation.tax_calculation.italian_tax_calculation_strategy', ItalianTaxCalculationStrategy::class) ->args([ 'italian_tax_calculation_strategy', - [ - service('sylius.applicator.taxation.order_item_units'), - service('sylius.applicator.taxation.order_shipment'), - ], + tagged_iterator('sylius.taxation.item_units.applicator'), param('app.taxation.eu_zone_code'), ]) ->tag('sylius.taxation.calculation_strategy', [ diff --git a/src/Model/ItalianTaxCalculationStrategy.php b/src/Taxation/ItalianTaxCalculationStrategy.php similarity index 95% rename from src/Model/ItalianTaxCalculationStrategy.php rename to src/Taxation/ItalianTaxCalculationStrategy.php index e71e33e..c6f6dcd 100644 --- a/src/Model/ItalianTaxCalculationStrategy.php +++ b/src/Taxation/ItalianTaxCalculationStrategy.php @@ -2,13 +2,14 @@ declare(strict_types=1); -namespace Webgriffe\SyliusItalianInvoiceableOrderPlugin\Model; +namespace Webgriffe\SyliusItalianInvoiceableOrderPlugin\Taxation; use Sylius\Component\Addressing\Model\ZoneInterface; use Sylius\Component\Core\Model\ChannelInterface; use Sylius\Component\Core\Model\OrderInterface; use Sylius\Component\Core\Taxation\Applicator\OrderTaxesApplicatorInterface; use Sylius\Component\Core\Taxation\Strategy\TaxCalculationStrategyInterface; +use Webgriffe\SyliusItalianInvoiceableOrderPlugin\Model\ItalianInvoiceableAddressInterface; use Webmozart\Assert\Assert; final class ItalianTaxCalculationStrategy implements TaxCalculationStrategyInterface From d0a8e2ac5ae219bdfd86df1078ce1e5cf0c9de8b Mon Sep 17 00:00:00 2001 From: Lorenzo Ruozzi Date: Tue, 10 Feb 2026 15:11:26 +0100 Subject: [PATCH 06/10] Replace VatNumber validator with new one (#21) --- README.md | 50 ++++++------ UPGRADE.md | 4 +- composer.json | 1 - config/services/validator.php | 12 ++- config/services/vies.php | 13 ++++ psalm.xml | 3 +- .../Constraints/EuropeanVatNumber.php | 35 +++++++++ .../EuropeanVatNumberValidator.php | 64 +++++++++++++++ .../config/validation/Address.xml | 78 ++++++++++++------- translations/messages+intl-icu.de.yaml | 19 +++++ translations/messages+intl-icu.en.yaml | 36 ++++----- translations/messages+intl-icu.es.yaml | 19 +++++ translations/messages+intl-icu.fr.yaml | 19 +++++ translations/messages+intl-icu.it.yaml | 36 ++++----- translations/validators+intl-icu.de.yaml | 23 ++++++ translations/validators+intl-icu.en.yaml | 1 + translations/validators+intl-icu.es.yaml | 23 ++++++ translations/validators+intl-icu.fr.yaml | 23 ++++++ translations/validators+intl-icu.it.yaml | 1 + 19 files changed, 365 insertions(+), 95 deletions(-) create mode 100644 config/services/vies.php create mode 100644 src/Validator/Constraints/EuropeanVatNumber.php create mode 100644 src/Validator/Constraints/EuropeanVatNumberValidator.php create mode 100644 translations/messages+intl-icu.de.yaml create mode 100644 translations/messages+intl-icu.es.yaml create mode 100644 translations/messages+intl-icu.fr.yaml create mode 100644 translations/validators+intl-icu.de.yaml create mode 100644 translations/validators+intl-icu.es.yaml create mode 100644 translations/validators+intl-icu.fr.yaml diff --git a/README.md b/README.md index 6486e95..bbe74ef 100644 --- a/README.md +++ b/README.md @@ -11,20 +11,6 @@ ## Installation -0. This plugin requires the [MyOnlineStore/ViesBundle](https://github.com/MyOnlineStore/ViesBundle) but this is not actually compatible with Symfony 7, there is an open PR: https://github.com/MyOnlineStore/ViesBundle/pull/18 - - Thus, you have to run the following command to require a fork of the bundle which is compatible with Symfony 7: - - ```bash - composer config repositories.sandwich/vies-bundle git https://github.com/mmenozzi/ViesBundle.git - ``` - - and you have to run this command too to allow "dev" versions of the bundle (we need the "dev-patch-1" version): - - ```bash - composer config minimum-stability dev - ``` - 1. Require the plugin: ```bash @@ -44,7 +30,7 @@ - { resource: "@WebgriffeSyliusItalianInvoiceableOrderPlugin/config/config.yaml" } ``` -3. By default, the parameter `app.taxation.eu_zone_code` is set to "EU", as it must be the code of a zone representing the EU. This is used to determine if an order is invoiced to a company within the EU or not. Please change this parameter according to your Sylius's zone configuration if needed: +4. By default, the parameter `app.taxation.eu_zone_code` is set to "EU", as it must be the code of a zone representing the EU. This is used to determine if an order is invoiced to a company within the EU or not. Please change this parameter according to your Sylius's zone configuration if needed: ```yaml # config/services.yaml @@ -52,11 +38,11 @@ app.taxation.eu_zone_code: 'EU' # Change it if needed ``` -4. Your `Address` entity must implement the `Webgriffe\SyliusItalianInvoiceableOrderPlugin\Model\ItalianInvoiceableAddressInterface` and the `Symfony\Component\Validator\GroupSequenceProviderInterface`. You can use the `Webgriffe\SyliusItalianInvoiceableOrderPlugin\Model\ItalianInvoiceableAddressTrait` as implementation for both interfaces. +5. Your `Address` entity must implement the `Webgriffe\SyliusItalianInvoiceableOrderPlugin\Model\ItalianInvoiceableAddressInterface` and the `Symfony\Component\Validator\GroupSequenceProviderInterface`. You can use the `Webgriffe\SyliusItalianInvoiceableOrderPlugin\Model\ItalianInvoiceableAddressTrait` as implementation for both interfaces. -5. Your `Order` entity must implement the `Webgriffe\SyliusItalianInvoiceableOrderPlugin\Model\ItalianInvoiceableOrderInterface`. You can use the `Webgriffe\SyliusItalianInvoiceableOrderPlugin\Model\ItalianInvoiceableOrderTrait` as default implementation for the interface. +6. Your `Order` entity must implement the `Webgriffe\SyliusItalianInvoiceableOrderPlugin\Model\ItalianInvoiceableOrderInterface`. You can use the `Webgriffe\SyliusItalianInvoiceableOrderPlugin\Model\ItalianInvoiceableOrderTrait` as default implementation for the interface. -6. You need to import the `Address` and `Order` validator configuration into your project by copying the configuration files provided by this plugin: +7. You need to import the `Address` and `Order` validator configuration into your project by copying the configuration files provided by this plugin: ```bash mkdir -p config/validator/ @@ -77,12 +63,21 @@ ```bash sed -i '' 's/Tests\\Webgriffe\\SyliusItalianInvoiceableOrderPlugin/App/g' config/validator/Address.xml config/validator/Order.xml ``` + + If you already have some validator file for these entities you have to merge the configuration manually. + + *NB* Please, note that currently these validation rules are applied in strict mode. This means that if the VIES + service is not available for some reason, the validation of the VAT number will fail. This could occur frequently on + specific countries like Germany or France due + to this problem: https://viesapi.eu/vies-problems-with-verifying-companies-from-germany-de/. + If you want to avoid this strict behavior you can change the `strict` option of the + `Webgriffe\SyliusItalianInvoiceableOrderPlugin\Validator\Constraints\EuropeanVatNumber` constraint to `false` in the + validation configuration file. This way, if the VIES service is not available, the VAT number will be considered + valid and the checkout will not be blocked. - If you alread have some validator file for these entities you have to merge the configuration manually. - -7. Configure Sylius to use the `Italian tax calculation` tax calculation strategy. +8. Configure Sylius to use the `Italian tax calculation` tax calculation strategy. -8. To properly enable group sequence validation of your Address entity you must set the `Default` validation group instead of the `sylius` validation group: +9. To properly enable group sequence validation of your Address entity you must set the `Default` validation group instead of the `sylius` validation group: ```yaml # config/parameters.yaml @@ -93,28 +88,27 @@ For more information see [here](https://symfony.com/doc/current/validation/sequence_provider.html). -9. Run migration +10. Run migration ```bash - bin/console cache:clear bin/console doctrine:migrations:migrate ``` -10. Add invoiceable fields to the address show template for admin. To do so you have to override this template: +11. Add invoiceable fields to the address show template for admin. To do so you have to override this template: ```bash vendor/sylius/sylius/src/Sylius/Bundle/AdminBundle/templates/shared/helper/address.html.twig ``` - + by copying directly our implementation provided in the plugin: ```bash mkdir -p templates/bundles/SyliusAdminBundle/shared/helper/ cp vendor/webgriffe/sylius-italian-invoiceable-order-plugin/tests/TestApplication/templates/bundles/SyliusAdminBundle/shared/helper/address.html.twig templates/bundles/SyliusAdminBundle/shared/helper/address.html.twig ``` - + or by copying the original template and adding the invoiceable fields by yourself. In this case your template should look like the following: - + ```twig {% macro address(address) %}
diff --git a/UPGRADE.md b/UPGRADE.md index ed2c0e7..aa63d12 100644 --- a/UPGRADE.md +++ b/UPGRADE.md @@ -4,4 +4,6 @@ - The service `app.taxation.italian_tax_calculation_strategy` has been renamed to `webgriffe_sylius_italian_invoiceable_order.strategy.taxation.tax_calculation.italian_tax_calculation_strategy`. - The class `Webgriffe\SyliusItalianInvoiceableOrderPlugin\Model\ItalianTaxCalculationStrategy` has been moved to `Webgriffe\SyliusItalianInvoiceableOrderPlugin\Taxation\ItalianTaxCalculationStrategy`. -- +- The package `sandwich/vies-bundle` has been removed. +- The constraint `Symfony\Component\Validator\Constraints\Sandwich\ViesBundle\Validator\Constraint\VatNumber` has been replaced with `Webgriffe\SyliusItalianInvoiceableOrderPlugin\Validator\Constraints\EuropeanVatNumber`. Please update your validation rules accordingly with search and replace. + Please, note also that now is available a new strict option that allows you to block the checkout step if the VIES service is not available. You can enable it by setting the `strict` option to `true` in your validation rules. diff --git a/composer.json b/composer.json index 3a56077..a998234 100644 --- a/composer.json +++ b/composer.json @@ -11,7 +11,6 @@ "require": { "php": "^8.2", "dragonbe/vies": "^2.3.2", - "sandwich/vies-bundle": "dev-patch-1", "sylius/sylius": "^2.2", "webmozart/assert": "^1.9" }, diff --git a/config/services/validator.php b/config/services/validator.php index 226f4fc..09422ba 100644 --- a/config/services/validator.php +++ b/config/services/validator.php @@ -4,10 +4,18 @@ namespace Symfony\Component\DependencyInjection\Loader\Configurator; -use Webgriffe\SyliusElasticsearchPlugin\Validator\RequestValidator; +use Webgriffe\SyliusItalianInvoiceableOrderPlugin\Validator\Constraints\EuropeanVatNumberValidator; return static function (ContainerConfigurator $containerConfigurator) { $services = $containerConfigurator->services(); - $services->set('webgriffe.sylius_elasticsearch_plugin.validator.request', RequestValidator::class); + $services->set('webgriffe_sylius_italian_invoiceable_order.validator.european_vat_number', EuropeanVatNumberValidator::class) + ->args([ + service('webgriffe_sylius_italian_invoiceable_order.vies'), + service('logger'), + ]) + ->tag('validator.constraint_validator', [ + 'alias' => 'webgriffe_sylius_italian_invoiceable_order.european_vat_number_validator', + ]) + ; }; diff --git a/config/services/vies.php b/config/services/vies.php new file mode 100644 index 0000000..2c12afc --- /dev/null +++ b/config/services/vies.php @@ -0,0 +1,13 @@ +services(); + + $services->set('webgriffe_sylius_italian_invoiceable_order.vies', Vies::class); +}; diff --git a/psalm.xml b/psalm.xml index 09bb495..fe41ae9 100644 --- a/psalm.xml +++ b/psalm.xml @@ -17,8 +17,9 @@ - + + diff --git a/src/Validator/Constraints/EuropeanVatNumber.php b/src/Validator/Constraints/EuropeanVatNumber.php new file mode 100644 index 0000000..786dd55 --- /dev/null +++ b/src/Validator/Constraints/EuropeanVatNumber.php @@ -0,0 +1,35 @@ +strict; + } + + public function getFormat(): string + { + return $this->format; + } + + #[\Override] + public function validatedBy(): string + { + return 'webgriffe_sylius_italian_invoiceable_order.european_vat_number_validator'; + } +} diff --git a/src/Validator/Constraints/EuropeanVatNumberValidator.php b/src/Validator/Constraints/EuropeanVatNumberValidator.php new file mode 100644 index 0000000..5776feb --- /dev/null +++ b/src/Validator/Constraints/EuropeanVatNumberValidator.php @@ -0,0 +1,64 @@ +viesApi->getHeartBeat()->isAlive()) { + if ($constraint->isStrict()) { + $this->context->addViolation('webgriffe_sylius_italian_invoiceable_order.address.european_vat_number.vies_not_alive'); + } + + return; + } + + $format = $constraint->getFormat(); + + try { + $isValidEuropeanVatNumber = $this->viesApi->validateVat( + $format, + str_replace($format, '', $value), + )->isValid(); + } catch (ViesServiceException|ViesException $exception) { + $this->logger->warning($exception->getMessage()); + if ($constraint->isStrict()) { + $this->context->addViolation('webgriffe_sylius_italian_invoiceable_order.address.european_vat_number.vies_not_alive'); + } + + return; + } + if ($isValidEuropeanVatNumber) { + return; + } + + $this->context->addViolation($constraint->message, ['%format%' => $format]); + } +} diff --git a/tests/TestApplication/config/validation/Address.xml b/tests/TestApplication/config/validation/Address.xml index a3a48f2..3ee14d3 100644 --- a/tests/TestApplication/config/validation/Address.xml +++ b/tests/TestApplication/config/validation/Address.xml @@ -62,107 +62,122 @@ company-SK - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + @@ -173,79 +188,90 @@ company-IT - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + diff --git a/translations/messages+intl-icu.de.yaml b/translations/messages+intl-icu.de.yaml new file mode 100644 index 0000000..30dd10f --- /dev/null +++ b/translations/messages+intl-icu.de.yaml @@ -0,0 +1,19 @@ +webgriffe_sylius_italian_invoiceable_order: + form: + address: + billing_recipient_type: + label: 'Privatperson oder Unternehmen' + company: 'Unternehmen' + individual: 'Privatperson' + tax_code: + label: 'Steuernummer' + vat_number: + label: 'Umsatzsteuer-Identifikationsnummer' + sdi_code: + label: 'SDI-Code' + pec_address: + label: 'PEC-Adresse' + ui: + address: + tax_code_short: 'St.-Nr.' + vat_number_short: 'USt-IdNr.' diff --git a/translations/messages+intl-icu.en.yaml b/translations/messages+intl-icu.en.yaml index 70f465c..22428b4 100644 --- a/translations/messages+intl-icu.en.yaml +++ b/translations/messages+intl-icu.en.yaml @@ -1,19 +1,19 @@ webgriffe_sylius_italian_invoiceable_order: - form: - address: - billing_recipient_type: - label: 'Individual or Company' - company: 'Company' - individual: 'Individual' - tax_code: - label: 'Tax code' - vat_number: - label: 'VAT number' - sdi_code: - label: 'SDI code' - pec_address: - label: 'PEC address' - ui: - address: - tax_code_short: 'Tax Code' - vat_number_short: 'VAT No' + form: + address: + billing_recipient_type: + label: 'Individual or Company' + company: 'Company' + individual: 'Individual' + tax_code: + label: 'Tax code' + vat_number: + label: 'VAT number' + sdi_code: + label: 'SDI code' + pec_address: + label: 'PEC address' + ui: + address: + tax_code_short: 'Tax Code' + vat_number_short: 'VAT No' diff --git a/translations/messages+intl-icu.es.yaml b/translations/messages+intl-icu.es.yaml new file mode 100644 index 0000000..484cc94 --- /dev/null +++ b/translations/messages+intl-icu.es.yaml @@ -0,0 +1,19 @@ +webgriffe_sylius_italian_invoiceable_order: + form: + address: + billing_recipient_type: + label: 'Particular o empresa' + company: 'Empresa' + individual: 'Particular' + tax_code: + label: 'Código fiscal' + vat_number: + label: 'Número de IVA' + sdi_code: + label: 'Código SDI' + pec_address: + label: 'Dirección PEC' + ui: + address: + tax_code_short: 'Cód. fiscal' + vat_number_short: 'IVA' diff --git a/translations/messages+intl-icu.fr.yaml b/translations/messages+intl-icu.fr.yaml new file mode 100644 index 0000000..90361af --- /dev/null +++ b/translations/messages+intl-icu.fr.yaml @@ -0,0 +1,19 @@ +webgriffe_sylius_italian_invoiceable_order: + form: + address: + billing_recipient_type: + label: 'Particulier ou entreprise' + company: 'Entreprise' + individual: 'Particulier' + tax_code: + label: 'Code fiscal' + vat_number: + label: 'Numéro de TVA' + sdi_code: + label: 'Code SDI' + pec_address: + label: 'Adresse PEC' + ui: + address: + tax_code_short: 'Code fiscal' + vat_number_short: 'TVA' diff --git a/translations/messages+intl-icu.it.yaml b/translations/messages+intl-icu.it.yaml index 879d06b..b30ea05 100644 --- a/translations/messages+intl-icu.it.yaml +++ b/translations/messages+intl-icu.it.yaml @@ -1,19 +1,19 @@ webgriffe_sylius_italian_invoiceable_order: - form: - address: - billing_recipient_type: - label: 'Privato o Azienda' - company: 'Azienda' - individual: 'Privato' - tax_code: - label: 'Codice Fiscale' - vat_number: - label: 'Partita IVA' - sdi_code: - label: 'Codice destinatario SDI' - pec_address: - label: 'Indirizzo PEC' - ui: - address: - tax_code_short: 'CF' - vat_number_short: 'P.IVA' + form: + address: + billing_recipient_type: + label: 'Privato o Azienda' + company: 'Azienda' + individual: 'Privato' + tax_code: + label: 'Codice Fiscale' + vat_number: + label: 'Partita IVA' + sdi_code: + label: 'Codice destinatario SDI' + pec_address: + label: 'Indirizzo PEC' + ui: + address: + tax_code_short: 'CF' + vat_number_short: 'P.IVA' diff --git a/translations/validators+intl-icu.de.yaml b/translations/validators+intl-icu.de.yaml new file mode 100644 index 0000000..0ce0496 --- /dev/null +++ b/translations/validators+intl-icu.de.yaml @@ -0,0 +1,23 @@ +webgriffe_sylius_italian_invoiceable_order: + address: + company: + not_blank: 'Der Firmenname darf nicht leer sein.' + italian_tax_code: + valid: 'Bitte geben Sie eine gültige italienische Steuernummer ein.' + not_blank: 'Die Steuernummer darf nicht leer sein.' + italian_vat_number: + valid: 'Bitte geben Sie eine gültige italienische Umsatzsteuer-Identifikationsnummer ein.' + not_blank: 'Die Umsatzsteuer-Identifikationsnummer darf nicht leer sein.' + european_vat_number: + valid: 'Bitte geben Sie eine gültige europäische Umsatzsteuer-Identifikationsnummer ein.' + vies_not_alive: 'Der VIES-Dienst ist derzeit nicht verfügbar. Bitte versuchen Sie es später erneut.' + italian_sdi_code: + valid: 'Bitte geben Sie einen gültigen SDI-Code ein.' + not_blank: 'Der SDI-Code darf nicht leer sein.' + pec_address: + valid: 'Bitte geben Sie eine gültige PEC-Adresse ein.' + pec_or_sdi_required: 'Mindestens eines der beiden Felder, PEC-Adresse oder SDI-Code, ist erforderlich.' + order: + billing_recipient_type: + not_blank: 'Für die Rechnungsadresse dieser Bestellung muss ein Rechnungsempfängertyp (Unternehmen oder Privatperson) angegeben werden. Bitte kehren Sie zum Adressierungsschritt im Checkout zurück und wählen Sie einen Rechnungsempfängertyp für die Rechnungsadresse aus.' + choice: 'Der Rechnungsempfängertyp muss einer der folgenden sein: {{ choices }}.' diff --git a/translations/validators+intl-icu.en.yaml b/translations/validators+intl-icu.en.yaml index 38c6b4c..55d9d97 100644 --- a/translations/validators+intl-icu.en.yaml +++ b/translations/validators+intl-icu.en.yaml @@ -10,6 +10,7 @@ webgriffe_sylius_italian_invoiceable_order: not_blank: 'VAT number should not be blank.' european_vat_number: valid: 'Please enter a valid european VAT number.' + vies_not_alive: 'The VIES service is not alive at the moment. Please, try again later.' italian_sdi_code: valid: 'Please enter a valid SDI code.' not_blank: 'SDI code should not be blank.' diff --git a/translations/validators+intl-icu.es.yaml b/translations/validators+intl-icu.es.yaml new file mode 100644 index 0000000..b66aacc --- /dev/null +++ b/translations/validators+intl-icu.es.yaml @@ -0,0 +1,23 @@ +webgriffe_sylius_italian_invoiceable_order: + address: + company: + not_blank: 'El nombre de la empresa no debe estar vacío.' + italian_tax_code: + valid: 'Por favor, introduzca un código fiscal italiano válido.' + not_blank: 'El código fiscal no debe estar vacío.' + italian_vat_number: + valid: 'Por favor, introduzca un número de IVA italiano válido.' + not_blank: 'El número de IVA no debe estar vacío.' + european_vat_number: + valid: 'Por favor, introduzca un número de IVA europeo válido.' + vies_not_alive: 'El servicio VIES no está disponible en este momento. Por favor, inténtelo de nuevo más tarde.' + italian_sdi_code: + valid: 'Por favor, introduzca un código SDI válido.' + not_blank: 'El código SDI no debe estar vacío.' + pec_address: + valid: 'Por favor, introduzca una dirección PEC válida.' + pec_or_sdi_required: 'Se requiere al menos uno de los dos campos: dirección PEC o código SDI.' + order: + billing_recipient_type: + not_blank: 'Debe especificarse un tipo de destinatario de facturación (empresa o particular) para la dirección de facturación de este pedido. Por favor, vuelva al paso de introducción de direcciones durante el proceso de compra y seleccione un tipo de destinatario para la dirección de facturación.' + choice: 'El tipo de destinatario de facturación debe ser uno de los siguientes: {{ choices }}.' diff --git a/translations/validators+intl-icu.fr.yaml b/translations/validators+intl-icu.fr.yaml new file mode 100644 index 0000000..f35dcf9 --- /dev/null +++ b/translations/validators+intl-icu.fr.yaml @@ -0,0 +1,23 @@ +webgriffe_sylius_italian_invoiceable_order: + address: + company: + not_blank: 'Le nom de l’entreprise ne doit pas être vide.' + italian_tax_code: + valid: 'Veuillez saisir un code fiscal italien valide.' + not_blank: 'Le code fiscal ne doit pas être vide.' + italian_vat_number: + valid: 'Veuillez saisir un numéro de TVA italien valide.' + not_blank: 'Le numéro de TVA ne doit pas être vide.' + european_vat_number: + valid: 'Veuillez saisir un numéro de TVA européen valide.' + vies_not_alive: 'Le service VIES est actuellement indisponible. Veuillez réessayer plus tard.' + italian_sdi_code: + valid: 'Veuillez saisir un code SDI valide.' + not_blank: 'Le code SDI ne doit pas être vide.' + pec_address: + valid: 'Veuillez saisir une adresse PEC valide.' + pec_or_sdi_required: 'Au moins l’un des deux champs, adresse PEC ou code SDI, est requis.' + order: + billing_recipient_type: + not_blank: 'Un type de destinataire de facturation (entreprise ou particulier) doit être spécifié pour l’adresse de facturation de cette commande. Veuillez revenir à l’étape de saisie des adresses lors du paiement et indiquer un type de destinataire pour l’adresse de facturation.' + choice: 'Le type de destinataire de facturation doit être l’un des suivants : {{ choices }}.' diff --git a/translations/validators+intl-icu.it.yaml b/translations/validators+intl-icu.it.yaml index e1177e8..38bf1f4 100644 --- a/translations/validators+intl-icu.it.yaml +++ b/translations/validators+intl-icu.it.yaml @@ -10,6 +10,7 @@ webgriffe_sylius_italian_invoiceable_order: not_blank: 'La partita IVA non dovrebbe essere vuota.' european_vat_number: valid: 'Per favore, inserisci una partita IVA europea valida.' + vies_not_alive: 'Il servizio VIES non è disponibile al momento. Per favore, riprova più tardi.' italian_sdi_code: valid: 'Per favore, inserisci un codice destinatario SDI valido.' not_blank: 'Il codice destinatario SDI non dovrebbe essere vuoto.' From e43708caed9ca61e20429103243290e7f8752520 Mon Sep 17 00:00:00 2001 From: Lorenzo Ruozzi Date: Tue, 10 Feb 2026 15:27:57 +0100 Subject: [PATCH 07/10] Remove spec tests --- composer.json | 3 --- 1 file changed, 3 deletions(-) diff --git a/composer.json b/composer.json index a998234..be02230 100644 --- a/composer.json +++ b/composer.json @@ -30,7 +30,6 @@ "friends-of-behat/symfony-extension": "^2.6", "friends-of-behat/variadic-extension": "^1.6", "payum/payum-bundle": "2.6.*", - "phpspec/phpspec": "^8.0", "phpstan/extension-installer": "^1.0", "phpstan/phpstan": "^1.12", "phpstan/phpstan-doctrine": "^1.3", @@ -116,13 +115,11 @@ "ecs": "ecs check src/ tests/Behat/", "phpstan": "phpstan analyse -c phpstan.neon -l max src/", "phpunit": "phpunit", - "phpspec": "phpspec run", "behat": "behat --strict -vvv --no-interaction || behat --strict -vvv --no-interaction --rerun", "suite": [ "@ecs", "@phpstan", "@phpunit", - "@phpspec", "@behat" ], "auto-scripts": { From ab9729076fec1cbe64e84ce52e6cf6a366333ee2 Mon Sep 17 00:00:00 2001 From: Lorenzo Ruozzi Date: Tue, 10 Feb 2026 15:32:35 +0100 Subject: [PATCH 08/10] Fix tests (#21) --- composer.json | 6 - ...able_address_saved_in_address_book.feature | 70 ++++---- ...ng_correct_taxes_based_on_customer.feature | 160 +++++++++--------- .../ItalianTaxCalculationStrategy.php | 30 +--- .../EuropeanVatNumberValidator.php | 3 + .../Checkout/CheckoutAddressingContext.php | 3 + tests/Behat/Resources/services.xml | 4 + .../InMemoryEuropeanVatNumberValidator.php | 32 ++++ 8 files changed, 166 insertions(+), 142 deletions(-) create mode 100644 tests/Behat/Service/InMemoryEuropeanVatNumberValidator.php diff --git a/composer.json b/composer.json index be02230..9682583 100644 --- a/composer.json +++ b/composer.json @@ -81,12 +81,6 @@ } } }, - "repositories": { - "sandwich/vies-bundle": { - "type": "git", - "url": "https://github.com/mmenozzi/ViesBundle.git" - } - }, "autoload": { "psr-4": { "Webgriffe\\SyliusItalianInvoiceableOrderPlugin\\": "src/" diff --git a/features/checkout/invoiceable_address_book/having_new_invoiceable_address_saved_in_address_book.feature b/features/checkout/invoiceable_address_book/having_new_invoiceable_address_saved_in_address_book.feature index 67d6c9b..fa03e34 100644 --- a/features/checkout/invoiceable_address_book/having_new_invoiceable_address_saved_in_address_book.feature +++ b/features/checkout/invoiceable_address_book/having_new_invoiceable_address_saved_in_address_book.feature @@ -1,40 +1,40 @@ @invoiceable_address_book Feature: Having new invoiceable addresses saved in the address book after checkout - In order to ease my address management - As a Customer - I want new invoiceable addresses provided during checkout to be saved in my address book + In order to ease my address management + As a Customer + I want new invoiceable addresses provided during checkout to be saved in my address book - Background: - Given the store operates on a single channel in "Italy" - And the store has a product "Lannister Coat" priced at "$19.99" - And the store ships everywhere for free - And the store allows paying with "Cash on Delivery" - And I am a logged in customer - And I added product "Lannister Coat" to the cart + Background: + Given the store operates on a single channel in "Italy" + And the store has a product "Lannister Coat" priced at "$19.99" + And the store ships everywhere for free + And the store allows paying with "Cash on Delivery" + And I am a logged in customer + And I added product "Lannister Coat" to the cart - @ui - Scenario: Invoiceable address already existent in my book don't get saved again - Given I have an address for the company "GoT SpA" - "Jon Snow" - "Viale Italia", "42100", "Reggio Emilia" - "Italy" - And this address has also all the invoiceable information valid for an italian company - And I am at the checkout addressing step - When I specify the billing address for the company "GoT SpA" - "Jon Snow" - "Viale Italia", "42100", "Reggio Emilia" - "Italy" - And I specify the same invoiceable information of the address I have in my address book - And I complete the addressing step - And I proceed with "Free" shipping method and "Cash on Delivery" payment - And I confirm my order - And I should see the thank you page - Then I should have a single address in my address book + @ui + Scenario: Invoiceable address already existent in my book don't get saved again + Given I have an address for the company "GoT SpA" - "Jon Snow" - "Viale Italia", "42100", "Reggio Emilia" - "Italy" + And this address has also all the invoiceable information valid for an italian company + And I am at the checkout addressing step + When I specify the billing address for the company "GoT SpA" - "Jon Snow" - "Viale Italia", "42100", "Reggio Emilia" - "Italy" + And I specify the same invoiceable information of the address I have in my address book + And I complete the addressing step + And I proceed with "Free" shipping method and "Cash on Delivery" payment + And I confirm my order + And I should see the thank you page + Then I should have a single address in my address book - @ui - Scenario: Different invoiceable address information provided during checkout are saved in my book as new address - Given I have an address for the company "GoT SpA" - "Jon Snow" - "Viale Italia", "42100", "Reggio Emilia" - "Italy" - And this address has also all the invoiceable information valid for an italian company - And I am at the checkout addressing step - When I specify the billing address for the company "GoT SpA" - "Jon Snow" - "Viale Italia", "42100", "Reggio Emilia" - "Italy" - And I specify the same invoiceable information of the address I have in my address book - But I specify a different SDI code from that of the address I have in the address book - And I complete the addressing step - And I proceed with "Free" shipping method and "Cash on Delivery" payment - And I confirm my order - And I should see the thank you page - Then I should have 2 addresses in my address book + @ui + Scenario: Different invoiceable address information provided during checkout are saved in my book as new address + Given I have an address for the company "GoT SpA" - "Jon Snow" - "Viale Italia", "42100", "Reggio Emilia" - "Italy" + And this address has also all the invoiceable information valid for an italian company + And I am at the checkout addressing step + When I specify the billing address for the company "GoT SpA" - "Jon Snow" - "Viale Italia", "42100", "Reggio Emilia" - "Italy" + And I specify the same invoiceable information of the address I have in my address book + But I specify a different SDI code from that of the address I have in the address book + And I complete the addressing step + And I proceed with "Free" shipping method and "Cash on Delivery" payment + And I confirm my order + And I should see the thank you page + Then I should have 2 addresses in my address book diff --git a/features/checkout/tax_calculation/applying_correct_taxes_based_on_customer.feature b/features/checkout/tax_calculation/applying_correct_taxes_based_on_customer.feature index 6ba0a52..814721f 100644 --- a/features/checkout/tax_calculation/applying_correct_taxes_based_on_customer.feature +++ b/features/checkout/tax_calculation/applying_correct_taxes_based_on_customer.feature @@ -1,89 +1,89 @@ @applying_taxes Feature: Apply correct taxes based on order address - In order to pay proper amount when buying goods - As a Customer or Visitor - I want to have correct taxes applied to my order + In order to pay proper amount when buying goods + As a Customer or Visitor + I want to have correct taxes applied to my order - Background: - Given the store operates on a single channel worldwide - And the store uses the "Italian tax calculation strategy" tax calculation strategy - And there is a tax zone "EU" containing all European Union countries - And there is a tax zone "Extra EU" containing all countries outside the European Union - And there is a shipping zone "Global" containing all countries of the world - And the store ships everywhere for Free - And the store allows paying Offline - And the store has "IVA 22%" tax rate of 22% for "IVA Ordinaria" within the "EU" zone - And the store has a product "PHP T-Shirt" priced at "$100.00" - And it belongs to "IVA Ordinaria" tax category + Background: + Given the store operates on a single channel worldwide + And the store uses the "Italian tax calculation strategy" tax calculation strategy + And there is a tax zone "EU" containing all European Union countries + And there is a tax zone "Extra EU" containing all countries outside the European Union + And there is a shipping zone "Global" containing all countries of the world + And the store ships everywhere for Free + And the store allows paying Offline + And the store has "IVA 22%" tax rate of 22% for "IVA Ordinaria" within the "EU" zone + And the store has a product "PHP T-Shirt" priced at "$100.00" + And it belongs to "IVA Ordinaria" tax category - @ui - Scenario: Paying taxes while ordering as an italian individual - Given I added product "PHP T-Shirt" to the cart - And I am at the checkout addressing step - And I specify the email as "italian-individual@email.com" - And I specify a valid italian individual billing address - And I complete the addressing step - And I proceed with "Free" shipping method and "Offline" payment - Then I should be on the checkout complete step - And my order total should be "$122.00" - And my tax total should be "$22.00" + @ui + Scenario: Paying taxes while ordering as an italian individual + Given I added product "PHP T-Shirt" to the cart + And I am at the checkout addressing step + And I specify the email as "italian-individual@email.com" + And I specify a valid italian individual billing address + And I complete the addressing step + And I proceed with "Free" shipping method and "Offline" payment + Then I should be on the checkout complete step + And my order total should be "$122.00" + And my tax total should be "$22.00" - @ui - Scenario: Paying taxes while ordering as an italian company - Given I added product "PHP T-Shirt" to the cart - And I am at the checkout addressing step - And I specify the email as "italian-company@email.com" - And I specify a valid italian company billing address - And I complete the addressing step - And I proceed with "Free" shipping method and "Offline" payment - Then I should be on the checkout complete step - And my order total should be "$122.00" - And my tax total should be "$22.00" + @ui + Scenario: Paying taxes while ordering as an italian company + Given I added product "PHP T-Shirt" to the cart + And I am at the checkout addressing step + And I specify the email as "italian-company@email.com" + And I specify a valid italian company billing address + And I complete the addressing step + And I proceed with "Free" shipping method and "Offline" payment + Then I should be on the checkout complete step + And my order total should be "$122.00" + And my tax total should be "$22.00" - @ui - Scenario: Paying taxes while ordering as an EU individual - Given I added product "PHP T-Shirt" to the cart - And I am at the checkout addressing step - And I specify the email as "german-individual@email.com" - And I specify a valid german individual billing address - And I complete the addressing step - And I proceed with "Free" shipping method and "Offline" payment - Then I should be on the checkout complete step - And my order total should be "$122.00" - And my tax total should be "$22.00" + @ui + Scenario: Paying taxes while ordering as an EU individual + Given I added product "PHP T-Shirt" to the cart + And I am at the checkout addressing step + And I specify the email as "german-individual@email.com" + And I specify a valid german individual billing address + And I complete the addressing step + And I proceed with "Free" shipping method and "Offline" payment + Then I should be on the checkout complete step + And my order total should be "$122.00" + And my tax total should be "$22.00" - @ui - Scenario: Not paying taxes while ordering as an EU company - Given I added product "PHP T-Shirt" to the cart - And I am at the checkout addressing step - And I specify the email as "german-company@email.com" - And I specify a valid german company billing address - And I complete the addressing step - And I proceed with "Free" shipping method and "Offline" payment - Then I should be on the checkout complete step - And my order total should be "$100.00" - And my tax total should be "$0.00" + @ui + Scenario: Not paying taxes while ordering as an EU company + Given I added product "PHP T-Shirt" to the cart + And I am at the checkout addressing step + And I specify the email as "german-company@email.com" + And I specify a valid german company billing address + And I complete the addressing step + And I proceed with "Free" shipping method and "Offline" payment + Then I should be on the checkout complete step + And my order total should be "$100.00" + And my tax total should be "$0.00" - @ui - Scenario: Not paying taxes while ordering as an extra EU individual - Given I added product "PHP T-Shirt" to the cart - And I am at the checkout addressing step - And I specify the email as "usa-individual@email.com" - And I specify a valid US individual billing address - And I complete the addressing step - And I proceed with "Free" shipping method and "Offline" payment - Then I should be on the checkout complete step - And my order total should be "$100.00" - And my tax total should be "$0.00" + @ui + Scenario: Not paying taxes while ordering as an extra EU individual + Given I added product "PHP T-Shirt" to the cart + And I am at the checkout addressing step + And I specify the email as "usa-individual@email.com" + And I specify a valid US individual billing address + And I complete the addressing step + And I proceed with "Free" shipping method and "Offline" payment + Then I should be on the checkout complete step + And my order total should be "$100.00" + And my tax total should be "$0.00" - @ui - Scenario: Not paying taxes while ordering as an extra EU company - Given I added product "PHP T-Shirt" to the cart - And I am at the checkout addressing step - And I specify the email as "usa-company@email.com" - And I specify a valid US company billing address - And I complete the addressing step - And I proceed with "Free" shipping method and "Offline" payment - Then I should be on the checkout complete step - And my order total should be "$100.00" - And my tax total should be "$0.00" + @ui + Scenario: Not paying taxes while ordering as an extra EU company + Given I added product "PHP T-Shirt" to the cart + And I am at the checkout addressing step + And I specify the email as "usa-company@email.com" + And I specify a valid US company billing address + And I complete the addressing step + And I proceed with "Free" shipping method and "Offline" payment + Then I should be on the checkout complete step + And my order total should be "$100.00" + And my tax total should be "$0.00" diff --git a/src/Taxation/ItalianTaxCalculationStrategy.php b/src/Taxation/ItalianTaxCalculationStrategy.php index c6f6dcd..cf53db0 100644 --- a/src/Taxation/ItalianTaxCalculationStrategy.php +++ b/src/Taxation/ItalianTaxCalculationStrategy.php @@ -14,23 +14,20 @@ final class ItalianTaxCalculationStrategy implements TaxCalculationStrategyInterface { - private string $type; - - /** @var OrderTaxesApplicatorInterface[] */ - private array $applicators; - - private string $euTaxZoneCode; + /** @var iterable */ + private iterable $applicators; /** - * @param OrderTaxesApplicatorInterface[] $applicators + * @param iterable|iterable $applicators */ - public function __construct(string $type, array $applicators, string $euTaxZoneCode) - { - $this->assertApplicatorsHaveCorrectType($applicators); + public function __construct( + private string $type, + iterable $applicators, + private string $euTaxZoneCode, + ) { + Assert::allIsInstanceOf($applicators, OrderTaxesApplicatorInterface::class); - $this->type = $type; $this->applicators = $applicators; - $this->euTaxZoneCode = $euTaxZoneCode; } #[\Override] @@ -62,15 +59,6 @@ public function supports(OrderInterface $order, ZoneInterface $zone): bool return $channel->getTaxCalculationStrategy() === $this->type; } - private function assertApplicatorsHaveCorrectType(array $applicators): void - { - Assert::allIsInstanceOf( - $applicators, - OrderTaxesApplicatorInterface::class, - 'Order taxes applicator should have type "%2$s". Got: %s', - ); - } - private function shouldSkipTaxesApplication(OrderInterface $order, ZoneInterface $zone): bool { if ($this->euTaxZoneCode === '') { diff --git a/src/Validator/Constraints/EuropeanVatNumberValidator.php b/src/Validator/Constraints/EuropeanVatNumberValidator.php index 5776feb..40bca88 100644 --- a/src/Validator/Constraints/EuropeanVatNumberValidator.php +++ b/src/Validator/Constraints/EuropeanVatNumberValidator.php @@ -16,6 +16,9 @@ */ final class EuropeanVatNumberValidator extends ConstraintValidator { + /** + * @psalm-suppress PossiblyUnusedMethod + */ public function __construct( private readonly Vies $viesApi, private readonly LoggerInterface $logger, diff --git a/tests/Behat/Context/Ui/Shop/Checkout/CheckoutAddressingContext.php b/tests/Behat/Context/Ui/Shop/Checkout/CheckoutAddressingContext.php index ea67f4d..d6ce374 100644 --- a/tests/Behat/Context/Ui/Shop/Checkout/CheckoutAddressingContext.php +++ b/tests/Behat/Context/Ui/Shop/Checkout/CheckoutAddressingContext.php @@ -11,6 +11,7 @@ use Sylius\Behat\Service\SharedStorageInterface; use Sylius\Component\Core\Model\AddressInterface; use Tests\Webgriffe\SyliusItalianInvoiceableOrderPlugin\Behat\Page\Shop\Checkout\AddressPageInterface; +use Tests\Webgriffe\SyliusItalianInvoiceableOrderPlugin\Behat\Service\InMemoryEuropeanVatNumberValidator; use Webgriffe\SyliusItalianInvoiceableOrderPlugin\Model\ItalianInvoiceableAddressInterface; use Webmozart\Assert\Assert; @@ -249,6 +250,7 @@ public function iShouldBeNotifiedThatTheBillingCompanyNameIsRequired(): void */ public function iSpecifyAnInvalidVatNumberForAGermanCompany(): void { + InMemoryEuropeanVatNumberValidator::$isValid = false; $this->addressPage->specifyBillingVatNumber('DE123456789'); } @@ -257,6 +259,7 @@ public function iSpecifyAnInvalidVatNumberForAGermanCompany(): void */ public function iSpecifyAValidBillingVatNumberForAGermanCompany(): void { + InMemoryEuropeanVatNumberValidator::$isValid = true; // This is the real german company Hetzner (https://www.hetzner.com/) VAT number $this->addressPage->specifyBillingVatNumber('DE812871812'); } diff --git a/tests/Behat/Resources/services.xml b/tests/Behat/Resources/services.xml index e433b38..203c17c 100644 --- a/tests/Behat/Resources/services.xml +++ b/tests/Behat/Resources/services.xml @@ -68,5 +68,9 @@ %locale% + + + + diff --git a/tests/Behat/Service/InMemoryEuropeanVatNumberValidator.php b/tests/Behat/Service/InMemoryEuropeanVatNumberValidator.php new file mode 100644 index 0000000..43d5376 --- /dev/null +++ b/tests/Behat/Service/InMemoryEuropeanVatNumberValidator.php @@ -0,0 +1,32 @@ +getFormat(); + $this->context->addViolation($constraint->message, ['%format%' => $format]); + } +} From 92876513f1c8ddc2018a46e092cfc9e1d7153638 Mon Sep 17 00:00:00 2001 From: Lorenzo Ruozzi Date: Tue, 10 Feb 2026 16:01:19 +0100 Subject: [PATCH 09/10] Replace yaml with php files --- .github/CODEOWNERS | 1 + README.md | 2 +- UPGRADE.md | 1 + config/config.php | 13 ++++ config/config.yaml | 6 -- config/packages/sylius_admin_twig_hooks.php | 32 ++++++++ config/packages/sylius_shop_twig_hooks.php | 34 +++++++++ config/twig_hooks/admin/order/update.yaml | 16 ---- config/twig_hooks/shop/address.yaml | 10 --- config/twig_hooks/shop/form/address.yaml | 9 --- src/Migrations/.gitkeep | 0 tests/Behat/Resources/services.php | 9 +++ tests/Behat/Resources/services.xml | 76 ------------------- tests/Behat/Resources/services/others.php | 34 +++++++++ tests/Behat/Resources/services/pages.php | 22 ++++++ tests/Behat/Resources/services/setup.php | 41 ++++++++++ tests/Behat/Resources/services/transform.php | 19 +++++ tests/Behat/Resources/services/ui.php | 27 +++++++ tests/TestApplication/config/config.yaml | 2 +- .../TestApplication/config/services_test.php | 2 +- tests/TestApplication/src/Entity/.gitignore | 0 21 files changed, 236 insertions(+), 120 deletions(-) create mode 100644 .github/CODEOWNERS create mode 100644 config/config.php delete mode 100644 config/config.yaml create mode 100644 config/packages/sylius_admin_twig_hooks.php create mode 100644 config/packages/sylius_shop_twig_hooks.php delete mode 100644 config/twig_hooks/admin/order/update.yaml delete mode 100644 config/twig_hooks/shop/address.yaml delete mode 100644 config/twig_hooks/shop/form/address.yaml delete mode 100644 src/Migrations/.gitkeep create mode 100644 tests/Behat/Resources/services.php delete mode 100644 tests/Behat/Resources/services.xml create mode 100644 tests/Behat/Resources/services/others.php create mode 100644 tests/Behat/Resources/services/pages.php create mode 100644 tests/Behat/Resources/services/setup.php create mode 100644 tests/Behat/Resources/services/transform.php create mode 100644 tests/Behat/Resources/services/ui.php delete mode 100644 tests/TestApplication/src/Entity/.gitignore diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS new file mode 100644 index 0000000..3abb1fb --- /dev/null +++ b/.github/CODEOWNERS @@ -0,0 +1 @@ +* @webgriffe/wg-devs diff --git a/README.md b/README.md index bbe74ef..62bfc5a 100644 --- a/README.md +++ b/README.md @@ -27,7 +27,7 @@ 3. Add the plugin's configs by creating the `config/packages/webgriffe_sylius_italian_invoiceable_order_plugin.yaml` file with the following content: ```yaml imports: - - { resource: "@WebgriffeSyliusItalianInvoiceableOrderPlugin/config/config.yaml" } + - { resource: "@WebgriffeSyliusItalianInvoiceableOrderPlugin/config/config.php" } ``` 4. By default, the parameter `app.taxation.eu_zone_code` is set to "EU", as it must be the code of a zone representing the EU. This is used to determine if an order is invoiced to a company within the EU or not. Please change this parameter according to your Sylius's zone configuration if needed: diff --git a/UPGRADE.md b/UPGRADE.md index aa63d12..021f7c3 100644 --- a/UPGRADE.md +++ b/UPGRADE.md @@ -7,3 +7,4 @@ - The package `sandwich/vies-bundle` has been removed. - The constraint `Symfony\Component\Validator\Constraints\Sandwich\ViesBundle\Validator\Constraint\VatNumber` has been replaced with `Webgriffe\SyliusItalianInvoiceableOrderPlugin\Validator\Constraints\EuropeanVatNumber`. Please update your validation rules accordingly with search and replace. Please, note also that now is available a new strict option that allows you to block the checkout step if the VIES service is not available. You can enable it by setting the `strict` option to `true` in your validation rules. +- The file `@WebgriffeSyliusItalianInvoiceableOrderPlugin/config/config.yaml` has been renamed to `@WebgriffeSyliusItalianInvoiceableOrderPlugin/config/config.php`. diff --git a/config/config.php b/config/config.php new file mode 100644 index 0000000..e243979 --- /dev/null +++ b/config/config.php @@ -0,0 +1,13 @@ +parameters(); + $parameters->set('sylius.form.type.address.validation_groups', [ 'Default' ]); + $parameters->set('app.taxation.eu_zone_code', 'EU'); + + $containerConfigurator->import('packages/*.php'); +}; diff --git a/config/config.yaml b/config/config.yaml deleted file mode 100644 index 513c04b..0000000 --- a/config/config.yaml +++ /dev/null @@ -1,6 +0,0 @@ -imports: - - { resource: 'twig_hooks/**/*.yaml' } - -parameters: - sylius.form.type.address.validation_groups: [ 'Default' ] - app.taxation.eu_zone_code: 'EU' diff --git a/config/packages/sylius_admin_twig_hooks.php b/config/packages/sylius_admin_twig_hooks.php new file mode 100644 index 0000000..fbf10cc --- /dev/null +++ b/config/packages/sylius_admin_twig_hooks.php @@ -0,0 +1,32 @@ +extension('sylius_twig_hooks', [ + 'hooks' => [ + 'sylius_admin.order.update.content.form.billing_address' => [ + 'billingRecipientType' => [ + 'template' => '@WebgriffeSyliusItalianInvoiceableOrderPlugin/admin/shared/form/address/billingRecipientType.html.twig', + 'priority' => 1000, + ], + 'invoiceableBillingData' => [ + 'template' => '@WebgriffeSyliusItalianInvoiceableOrderPlugin/admin/shared/form/address/invoiceableBillingData.html.twig', + 'priority' => 650, + ], + ], + 'sylius_admin.order.update.content.form.shipping_address' => [ + 'billingRecipientType' => [ + 'template' => '@WebgriffeSyliusItalianInvoiceableOrderPlugin/admin/shared/form/address/billingRecipientType.html.twig', + 'priority' => 1000, + ], + 'invoiceableBillingData' => [ + 'template' => '@WebgriffeSyliusItalianInvoiceableOrderPlugin/admin/shared/form/address/invoiceableBillingData.html.twig', + 'priority' => 650, + ], + ], + ], + ]); +}; diff --git a/config/packages/sylius_shop_twig_hooks.php b/config/packages/sylius_shop_twig_hooks.php new file mode 100644 index 0000000..dff8eda --- /dev/null +++ b/config/packages/sylius_shop_twig_hooks.php @@ -0,0 +1,34 @@ +extension('sylius_twig_hooks', [ + 'hooks' => [ + 'sylius_shop.shared.address' => [ + 'company' => [ + 'enabled' => false, + ], + 'name' => [ + 'enabled' => false, + ], + 'billingAddressInfo' => [ + 'template' => '@WebgriffeSyliusItalianInvoiceableOrderPlugin/shop/shared/address/billingAddressInfo.html.twig', + 'priority' => 1000, + ], + ], + 'sylius_shop.shared.form.address' => [ + 'billingRecipientType' => [ + 'template' => '@WebgriffeSyliusItalianInvoiceableOrderPlugin/shop/shared/form/address/billingRecipientType.html.twig', + 'priority' => 1000, + ], + 'invoiceableBillingData' => [ + 'template' => '@WebgriffeSyliusItalianInvoiceableOrderPlugin/shop/shared/form/address/invoiceableBillingData.html.twig', + 'priority' => 650, + ], + ], + ], + ]); +}; diff --git a/config/twig_hooks/admin/order/update.yaml b/config/twig_hooks/admin/order/update.yaml deleted file mode 100644 index eef9861..0000000 --- a/config/twig_hooks/admin/order/update.yaml +++ /dev/null @@ -1,16 +0,0 @@ -sylius_twig_hooks: - hooks: - 'sylius_admin.order.update.content.form.billing_address': - billingRecipientType: - template: '@WebgriffeSyliusItalianInvoiceableOrderPlugin/admin/shared/form/address/billingRecipientType.html.twig' - priority: 1000 - invoiceableBillingData: - template: '@WebgriffeSyliusItalianInvoiceableOrderPlugin/admin/shared/form/address/invoiceableBillingData.html.twig' - priority: 650 - 'sylius_admin.order.update.content.form.shipping_address': - billingRecipientType: - template: '@WebgriffeSyliusItalianInvoiceableOrderPlugin/admin/shared/form/address/billingRecipientType.html.twig' - priority: 1000 - invoiceableBillingData: - template: '@WebgriffeSyliusItalianInvoiceableOrderPlugin/admin/shared/form/address/invoiceableBillingData.html.twig' - priority: 650 diff --git a/config/twig_hooks/shop/address.yaml b/config/twig_hooks/shop/address.yaml deleted file mode 100644 index 27ff383..0000000 --- a/config/twig_hooks/shop/address.yaml +++ /dev/null @@ -1,10 +0,0 @@ -sylius_twig_hooks: - hooks: - 'sylius_shop.shared.address': - company: - enabled: false - name: - enabled: false - billingAddressInfo: - template: '@WebgriffeSyliusItalianInvoiceableOrderPlugin/shop/shared/address/billingAddressInfo.html.twig' - priority: 1000 diff --git a/config/twig_hooks/shop/form/address.yaml b/config/twig_hooks/shop/form/address.yaml deleted file mode 100644 index 3b45e65..0000000 --- a/config/twig_hooks/shop/form/address.yaml +++ /dev/null @@ -1,9 +0,0 @@ -sylius_twig_hooks: - hooks: - 'sylius_shop.shared.form.address': - billingRecipientType: - template: '@WebgriffeSyliusItalianInvoiceableOrderPlugin/shop/shared/form/address/billingRecipientType.html.twig' - priority: 1000 - invoiceableBillingData: - template: '@WebgriffeSyliusItalianInvoiceableOrderPlugin/shop/shared/form/address/invoiceableBillingData.html.twig' - priority: 650 diff --git a/src/Migrations/.gitkeep b/src/Migrations/.gitkeep deleted file mode 100644 index e69de29..0000000 diff --git a/tests/Behat/Resources/services.php b/tests/Behat/Resources/services.php new file mode 100644 index 0000000..8cc3ee1 --- /dev/null +++ b/tests/Behat/Resources/services.php @@ -0,0 +1,9 @@ +import('services/*.php'); +}; diff --git a/tests/Behat/Resources/services.xml b/tests/Behat/Resources/services.xml deleted file mode 100644 index 203c17c..0000000 --- a/tests/Behat/Resources/services.xml +++ /dev/null @@ -1,76 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - %locale% - - - - - - - diff --git a/tests/Behat/Resources/services/others.php b/tests/Behat/Resources/services/others.php new file mode 100644 index 0000000..f807274 --- /dev/null +++ b/tests/Behat/Resources/services/others.php @@ -0,0 +1,34 @@ +services(); + + $services->set('webgriffe_sylius_italian_invoiceable_order.behat.factory.default_italy_channel', DefaultItalyChannelFactory::class) + ->args([ + service('sylius.repository.channel'), + service('sylius.repository.country'), + service('sylius.repository.currency'), + service('sylius.repository.locale'), + service('sylius.repository.zone'), + service('sylius.factory.channel'), + service('sylius.factory.country'), + service('sylius.factory.currency'), + service('sylius.factory.locale'), + service('sylius.factory.zone'), + param('locale'), + ]) + ; + + $services->set('webgriffe_sylius_italian_invoiceable_order.validator.european_vat_number', InMemoryEuropeanVatNumberValidator::class) + ->tag('validator.constraint_validator', [ + 'alias' => 'webgriffe_sylius_italian_invoiceable_order.european_vat_number_validator', + ]) + ; +}; diff --git a/tests/Behat/Resources/services/pages.php b/tests/Behat/Resources/services/pages.php new file mode 100644 index 0000000..55b3550 --- /dev/null +++ b/tests/Behat/Resources/services/pages.php @@ -0,0 +1,22 @@ +services(); + + $services->set('webgriffe_sylius_italian_invoiceable_order.behat.page.shop.checkout.address', AddressPage::class) + ->parent('sylius.behat.page.shop.checkout.address') + ->public() + ; + + $services->set('webgriffe_sylius_italian_invoiceable_order.behat.page.shop.checkout.complete', CompletePage::class) + ->parent('sylius.behat.page.shop.checkout.complete') + ->public() + ; +}; diff --git a/tests/Behat/Resources/services/setup.php b/tests/Behat/Resources/services/setup.php new file mode 100644 index 0000000..1b217fe --- /dev/null +++ b/tests/Behat/Resources/services/setup.php @@ -0,0 +1,41 @@ +services(); + + $services->set('webgriffe_sylius_italian_invoiceable_order.behat.context.setup.channel', ChannelContext::class) + ->args([ + service('sylius.behat.factory.default_channel'), + service('webgriffe_sylius_italian_invoiceable_order.behat.factory.default_italy_channel'), + service('sylius.behat.shared_storage'), + service('sylius.factory.country'), + service('sylius.repository.channel'), + service('sylius.repository.country'), + ]) + ->public() + ; + + $services->set('webgriffe_sylius_italian_invoiceable_order.behat.context.setup.invoiceable_address', InvoiceableAddressContext::class) + ->args([ + service('sylius.behat.shared_storage'), + service('sylius.manager.customer'), + ]) + ->public() + ; + + $services->set('webgriffe_sylius_italian_invoiceable_order.behat.context.setup.zone', ZoneContext::class) + ->args([ + service('sylius.factory.zone'), + service('sylius.repository.zone'), + ]) + ->public() + ; +}; diff --git a/tests/Behat/Resources/services/transform.php b/tests/Behat/Resources/services/transform.php new file mode 100644 index 0000000..83c2fb8 --- /dev/null +++ b/tests/Behat/Resources/services/transform.php @@ -0,0 +1,19 @@ +services(); + + $services->set('webgriffe_sylius_italian_invoiceable_order.behat.context.transform.address', AddressContext::class) + ->public() + ->args([ + service('sylius.fixture.example_factory.address'), + service('sylius.converter.country_name'), + ]) + ; +}; diff --git a/tests/Behat/Resources/services/ui.php b/tests/Behat/Resources/services/ui.php new file mode 100644 index 0000000..3a925c9 --- /dev/null +++ b/tests/Behat/Resources/services/ui.php @@ -0,0 +1,27 @@ +services(); + + $services->set('webgriffe_sylius_italian_invoiceable_order.behat.context.ui.shop.checkout.addressing', CheckoutAddressingContext::class) + ->args([ + service('webgriffe_sylius_italian_invoiceable_order.behat.page.shop.checkout.address'), + service('sylius.behat.shared_storage'), + ]) + ->public() + ; + + $services->set('webgriffe_sylius_italian_invoiceable_order.behat.context.ui.shop.checkout.complete', CheckoutCompleteContext::class) + ->args([ + service('webgriffe_sylius_italian_invoiceable_order.behat.page.shop.checkout.complete'), + ]) + ->public() + ; +}; diff --git a/tests/TestApplication/config/config.yaml b/tests/TestApplication/config/config.yaml index b0ba11c..3ce0fff 100644 --- a/tests/TestApplication/config/config.yaml +++ b/tests/TestApplication/config/config.yaml @@ -1,5 +1,5 @@ imports: - - { resource: "@WebgriffeSyliusItalianInvoiceableOrderPlugin/config/config.yaml" } + - { resource: "@WebgriffeSyliusItalianInvoiceableOrderPlugin/config/config.php" } - { resource: "services_test.php" } twig: diff --git a/tests/TestApplication/config/services_test.php b/tests/TestApplication/config/services_test.php index 43f52f5..dd99681 100644 --- a/tests/TestApplication/config/services_test.php +++ b/tests/TestApplication/config/services_test.php @@ -7,6 +7,6 @@ return function (ContainerConfigurator $container) { if (str_starts_with($container->env(), 'test')) { $container->import('../../../vendor/sylius/sylius/src/Sylius/Behat/Resources/config/services.xml'); - $container->import('@WebgriffeSyliusItalianInvoiceableOrderPlugin/tests/Behat/Resources/services.xml'); + $container->import('@WebgriffeSyliusItalianInvoiceableOrderPlugin/tests/Behat/Resources/services.php'); } }; diff --git a/tests/TestApplication/src/Entity/.gitignore b/tests/TestApplication/src/Entity/.gitignore deleted file mode 100644 index e69de29..0000000 From 0a9c63b76a5a7d25d13c4b22e0f2cb7ca65b67bf Mon Sep 17 00:00:00 2001 From: Lorenzo Ruozzi Date: Tue, 10 Feb 2026 16:22:26 +0100 Subject: [PATCH 10/10] Rename parameter --- README.md | 4 ++-- UPGRADE.md | 1 + config/config.php | 2 +- config/services/taxation.php | 2 +- 4 files changed, 5 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 62bfc5a..887b7dc 100644 --- a/README.md +++ b/README.md @@ -30,12 +30,12 @@ - { resource: "@WebgriffeSyliusItalianInvoiceableOrderPlugin/config/config.php" } ``` -4. By default, the parameter `app.taxation.eu_zone_code` is set to "EU", as it must be the code of a zone representing the EU. This is used to determine if an order is invoiced to a company within the EU or not. Please change this parameter according to your Sylius's zone configuration if needed: +4. By default, the parameter `webgriffe_sylius_italian_invoiceable_order.taxation.eu_zone_code` is set to "EU", as it must be the code of a zone representing the EU. This is used to determine if an order is invoiced to a company within the EU or not. Please change this parameter according to your Sylius's zone configuration if needed: ```yaml # config/services.yaml parameters: - app.taxation.eu_zone_code: 'EU' # Change it if needed + webgriffe_sylius_italian_invoiceable_order.taxation.eu_zone_code: 'EU' # Change it if needed ``` 5. Your `Address` entity must implement the `Webgriffe\SyliusItalianInvoiceableOrderPlugin\Model\ItalianInvoiceableAddressInterface` and the `Symfony\Component\Validator\GroupSequenceProviderInterface`. You can use the `Webgriffe\SyliusItalianInvoiceableOrderPlugin\Model\ItalianInvoiceableAddressTrait` as implementation for both interfaces. diff --git a/UPGRADE.md b/UPGRADE.md index 021f7c3..961f1fe 100644 --- a/UPGRADE.md +++ b/UPGRADE.md @@ -8,3 +8,4 @@ - The constraint `Symfony\Component\Validator\Constraints\Sandwich\ViesBundle\Validator\Constraint\VatNumber` has been replaced with `Webgriffe\SyliusItalianInvoiceableOrderPlugin\Validator\Constraints\EuropeanVatNumber`. Please update your validation rules accordingly with search and replace. Please, note also that now is available a new strict option that allows you to block the checkout step if the VIES service is not available. You can enable it by setting the `strict` option to `true` in your validation rules. - The file `@WebgriffeSyliusItalianInvoiceableOrderPlugin/config/config.yaml` has been renamed to `@WebgriffeSyliusItalianInvoiceableOrderPlugin/config/config.php`. +- The parameter `app.taxation.eu_zone_code` has been renamed to `webgriffe_sylius_italian_invoiceable_order.taxation.eu_zone_code`. diff --git a/config/config.php b/config/config.php index e243979..599190b 100644 --- a/config/config.php +++ b/config/config.php @@ -7,7 +7,7 @@ return static function (ContainerConfigurator $containerConfigurator) { $parameters = $containerConfigurator->parameters(); $parameters->set('sylius.form.type.address.validation_groups', [ 'Default' ]); - $parameters->set('app.taxation.eu_zone_code', 'EU'); + $parameters->set('webgriffe_sylius_italian_invoiceable_order.taxation.eu_zone_code', 'EU'); $containerConfigurator->import('packages/*.php'); }; diff --git a/config/services/taxation.php b/config/services/taxation.php index 20fac86..7d0ccbf 100644 --- a/config/services/taxation.php +++ b/config/services/taxation.php @@ -13,7 +13,7 @@ ->args([ 'italian_tax_calculation_strategy', tagged_iterator('sylius.taxation.item_units.applicator'), - param('app.taxation.eu_zone_code'), + param('webgriffe_sylius_italian_invoiceable_order.taxation.eu_zone_code'), ]) ->tag('sylius.taxation.calculation_strategy', [ 'type' => 'italian_tax_calculation_strategy',