Skip to content

Commit 47c6b6d

Browse files
committed
add vat number field to channel billing data
1 parent bcb9c10 commit 47c6b6d

20 files changed

+417
-6
lines changed

README.md

Lines changed: 37 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
[![Quality Score][ico-code-quality]][link-code-quality]
88

99
## Features
10-
* New fields for VAT number and validation status at `Address` entity
10+
* New fields for VAT number at `Address` and `ShopBillingData` entity
1111
* Configure VAT number field requirement:
1212
* Optional / Required
1313
* Required if customer filled “Company” field
@@ -62,8 +62,6 @@ cp -R vendor/gewebe/sylius-vat-plugin/templates/SyliusShopBundle/* templates/bun
6262

6363
### Extend `Address` entity
6464

65-
- If you use `annotations` mapping:
66-
6765
```php
6866
# src/Entity/Addressing/Address.php
6967
@@ -83,8 +81,7 @@ class Address extends BaseAddress implements VatNumberAddressInterface
8381
use VatNumberAwareTrait;
8482
```
8583

86-
- If you use `yaml` mapping add also:
87-
84+
If you use `yaml` mapping add also:
8885
```yaml
8986
# config/doctrine/Address.orm.yaml
9087
@@ -105,6 +102,41 @@ App\Entity\Addressing\Address:
105102
nullable: true
106103
```
107104

105+
### Extend `ShopBillingData` entity
106+
107+
```php
108+
# src/Entity/Channel/ShopBillingData.php
109+
110+
namespace App\Entity\Channel;
111+
112+
use Doctrine\ORM\Mapping as ORM;
113+
use Gewebe\SyliusVATPlugin\Entity\ShopBillingDataVatNumberAwareTrait;
114+
use Gewebe\SyliusVATPlugin\Entity\ShopBillingDataVatNumberInterface;
115+
use Sylius\Component\Core\Model\ShopBillingData as BaseShopBillingData;
116+
117+
/**
118+
* @ORM\Entity
119+
* @ORM\Table(name="sylius_shop_billing_data")
120+
*/
121+
class ShopBillingData extends BaseShopBillingData implements ShopBillingDataVatNumberInterface
122+
{
123+
use ShopBillingDataVatNumberAwareTrait;
124+
```
125+
126+
If you use `yaml` mapping add also:
127+
```yaml
128+
# config/doctrine/ShopBillingData.orm.yaml
129+
130+
App\Entity\Channel\ShopBillingData:
131+
type: entity
132+
table: sylius_shop_billing_data
133+
fields:
134+
vatNumber:
135+
type: string
136+
column: vat_number
137+
nullable: true
138+
```
139+
108140
### Update your database schema
109141

110142
```bash
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
App\Entity\Channel\ShopBillingData:
2+
type: entity
3+
table: sylius_shop_billing_data
4+
fields:
5+
vatNumber:
6+
type: string
7+
column: vat_number
8+
nullable: true

config/services/form.yml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,3 +6,8 @@ services:
66
- '%gewebe_sylius_vat_plugin.required.default%'
77
tags:
88
- { name: form.type_extension, extended_type: Sylius\Bundle\AddressingBundle\Form\Type\AddressType }
9+
10+
gewebe_sylius_vat_plugin.form.extension.shop_billing_data:
11+
class: Gewebe\SyliusVATPlugin\Form\Extension\ShopBillingDataTypeExtension
12+
tags:
13+
- { name: form.type_extension, extended_type: Sylius\Bundle\CoreBundle\Form\Type\ShopBillingDataType }
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
@channel_vat_number
2+
Feature: Editing shop billing data with vat number on channel
3+
In order to have proper shop billing data with vat number on shop-related documents
4+
As an Administrator
5+
I want to be able to edit shop billing data with vat number on a channel
6+
7+
Background:
8+
Given the store operates on a channel named "Web"
9+
And the store ships to "Austria"
10+
And channel "Web" billing data is "Joda", "Burgring 1", "1010" "Vienna", "Austria" with "123" tax ID, "ATU" VAT No.
11+
And I am logged in as an administrator
12+
13+
@ui
14+
Scenario: Editing shop billing data with vat number on channel
15+
When I want to modify a channel "Web"
16+
And I specify company as "Jodeliti"
17+
And I specify tax ID as "99-999/9999"
18+
And I specify VAT number as "ATU12345678"
19+
And I specify shop billing address as "Opernring 1", "8010" "Graz", "Austria"
20+
And I save my changes
21+
Then I should be notified that it has been successfully edited
22+
And this channel company should be "Jodeliti"
23+
And this channel tax ID should be "99-999/9999"
24+
And this channel VAT number should be "ATU12345678"
25+
And this channel shop billing address should be "Opernring 1", "8010" "Graz", "Austria"

features/checkout/seeing_tax_total_dependent_on_country_and_vat.feature

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ Feature: Seeing tax total dependent on country and vat
2626

2727
# channel
2828
And the store operates on a channel named "Web"
29-
And channel "Web" billing data is "YourShirtShop", "Rue Belliard", "1000" "Brussels", "Belgium" with "1234567890" tax ID
29+
And channel "Web" billing data is "ShirtShop", "Rue Belliard", "1000" "Brussels", "Belgium" with "123" tax ID, "BE199" VAT No.
3030
And default tax zone is "BE"
3131

3232
# taxes

spec/Entity/ShopBillingDataSpec.php

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace spec\Gewebe\SyliusVATPlugin\Entity;
6+
7+
use Gewebe\SyliusVATPlugin\Entity\ShopBillingData;
8+
use Gewebe\SyliusVATPlugin\Entity\ShopBillingDataVatNumberInterface;
9+
use PhpSpec\ObjectBehavior;
10+
11+
final class ShopBillingDataSpec extends ObjectBehavior
12+
{
13+
function it_is_address()
14+
{
15+
$this->shouldHaveType(ShopBillingData::class);
16+
}
17+
18+
function it_implements_address_interface(): void
19+
{
20+
$this->shouldImplement(ShopBillingDataVatNumberInterface::class);
21+
}
22+
23+
function it_has_vat_number(): void
24+
{
25+
$this->getVatNumber()->shouldReturn(null);
26+
$this->hasVatNumber()->shouldReturn(false);
27+
28+
$this->setVatNumber('ATU12345678');
29+
$this->getVatNumber()->shouldReturn('ATU12345678');
30+
$this->hasVatNumber()->shouldReturn(true);
31+
}
32+
}

src/Entity/ShopBillingData.php

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Gewebe\SyliusVATPlugin\Entity;
6+
7+
use Doctrine\ORM\Mapping as ORM;
8+
use Sylius\Component\Core\Model\ShopBillingData as BaseShopBillingData;
9+
10+
/**
11+
* Example ShopBillingData entity with vat number implemented as trait
12+
*
13+
* #@ORM\Entity
14+
* #@ORM\Table(name="sylius_shop_billing_data")
15+
*/
16+
class ShopBillingData extends BaseShopBillingData implements ShopBillingDataVatNumberInterface
17+
{
18+
use ShopBillingDataVatNumberAwareTrait;
19+
}
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Gewebe\SyliusVATPlugin\Entity;
6+
7+
use Doctrine\ORM\Mapping as ORM;
8+
use Symfony\Component\Serializer\Annotation\Groups;
9+
10+
/**
11+
* Trait that implements the shop billing data vat number functionality
12+
* Used in:
13+
* <li>@see ShopBillingData</li>
14+
*/
15+
trait ShopBillingDataVatNumberAwareTrait
16+
{
17+
/**
18+
* @ORM\Column(name="vat_number", type="string", nullable=true)
19+
*
20+
* @Groups({"admin:shop_billing_data:read"})
21+
*/
22+
protected ?string $vatNumber = null;
23+
24+
public function getVatNumber(): ?string
25+
{
26+
return $this->vatNumber;
27+
}
28+
29+
public function setVatNumber(?string $vatNumber): void
30+
{
31+
$this->vatNumber = $vatNumber;
32+
}
33+
34+
public function hasVatNumber(): bool
35+
{
36+
return is_string($this->vatNumber) && strlen($this->vatNumber) > 0;
37+
}
38+
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Gewebe\SyliusVATPlugin\Entity;
6+
7+
use Sylius\Component\Core\Model\ShopBillingDataInterface;
8+
9+
/**
10+
* ShopBillingData model with vat number
11+
*/
12+
interface ShopBillingDataVatNumberInterface extends ShopBillingDataInterface
13+
{
14+
public function getVatNumber(): ?string;
15+
16+
public function setVatNumber(?string $vatNumber): void;
17+
18+
public function hasVatNumber(): bool;
19+
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Gewebe\SyliusVATPlugin\Form\Extension;
6+
7+
use Sylius\Bundle\CoreBundle\Form\Type\ShopBillingDataType;
8+
use Symfony\Component\Form\AbstractTypeExtension;
9+
use Symfony\Component\Form\Extension\Core\Type\TextType;
10+
use Symfony\Component\Form\FormBuilderInterface;
11+
12+
class ShopBillingDataTypeExtension extends AbstractTypeExtension
13+
{
14+
public function buildForm(FormBuilderInterface $builder, array $options): void
15+
{
16+
$builder->add(
17+
'vatNumber',
18+
TextType::class,
19+
[
20+
'label' => 'gewebe_sylius_vat_plugin.ui.vat_number',
21+
'required' => false,
22+
],
23+
);
24+
}
25+
26+
public static function getExtendedTypes(): array
27+
{
28+
return [
29+
ShopBillingDataType::class,
30+
];
31+
}
32+
}

tests/Application/config/services.yaml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,3 +8,9 @@ sylius_addressing:
88
address:
99
classes:
1010
model: Tests\Gewebe\SyliusVATPlugin\Application\src\Entity\Addressing\Address
11+
12+
sylius_core:
13+
resources:
14+
shop_billing_data:
15+
classes:
16+
model: Tests\Gewebe\SyliusVATPlugin\Application\src\Entity\Channel\ShopBillingData

tests/Application/config/services_test.yaml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,3 +12,9 @@ sylius_addressing:
1212
address:
1313
classes:
1414
model: Tests\Gewebe\SyliusVATPlugin\Application\src\Entity\Addressing\Address
15+
16+
sylius_core:
17+
resources:
18+
shop_billing_data:
19+
classes:
20+
model: Tests\Gewebe\SyliusVATPlugin\Application\src\Entity\Channel\ShopBillingData
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Tests\Gewebe\SyliusVATPlugin\Application\src\Entity\Channel;
6+
7+
use Doctrine\ORM\Mapping as ORM;
8+
use Gewebe\SyliusVATPlugin\Entity\ShopBillingDataVatNumberAwareTrait;
9+
use Gewebe\SyliusVATPlugin\Entity\ShopBillingDataVatNumberInterface;
10+
use Sylius\Component\Core\Model\ShopBillingData as BaseShopBillingData;
11+
12+
/**
13+
* ShopBillingData entity with vat number implemented as trait
14+
*
15+
* @ORM\Entity
16+
* @ORM\Table(name="sylius_shop_billing_data")
17+
*/
18+
class ShopBillingData extends BaseShopBillingData implements ShopBillingDataVatNumberInterface
19+
{
20+
use ShopBillingDataVatNumberAwareTrait;
21+
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
<h4 class="ui top attached large header">{{ form_label(form.shopBillingData) }}</h4>
2+
<div class="ui attached segment">
3+
<div class="three fields">
4+
{{ form_row(form.shopBillingData.company) }}
5+
{{ form_row(form.shopBillingData.taxId) }}
6+
{{ form_row(form.shopBillingData.vatNumber) }}
7+
</div>
8+
<div class="two fields">
9+
{{ form_row(form.shopBillingData.countryCode) }}
10+
{{ form_row(form.shopBillingData.street) }}
11+
</div>
12+
<div class="two fields">
13+
{{ form_row(form.shopBillingData.city) }}
14+
{{ form_row(form.shopBillingData.postcode) }}
15+
</div>
16+
</div>
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Tests\Gewebe\SyliusVATPlugin\Behat\Context\Setup;
6+
7+
use Behat\Behat\Context\Context;
8+
use Doctrine\Persistence\ObjectManager;
9+
use Sylius\Component\Addressing\Model\CountryInterface;
10+
use Sylius\Component\Core\Model\ChannelInterface;
11+
use Tests\Gewebe\SyliusVATPlugin\Application\src\Entity\Channel\ShopBillingData;
12+
13+
final class ChannelContext implements Context
14+
{
15+
public function __construct(
16+
private ObjectManager $channelManager,
17+
) {
18+
}
19+
20+
/**
21+
* @Given channel :channel billing data is :company, :street, :postcode :city, :country with :taxId tax ID, :vatNumber VAT No.
22+
*/
23+
public function channelBillingDataWithVatNumberIs(
24+
ChannelInterface $channel,
25+
string $company,
26+
string $street,
27+
string $postcode,
28+
string $city,
29+
CountryInterface $country,
30+
string $taxId,
31+
string $vatNumber,
32+
): void {
33+
$shopBillingData = new ShopBillingData();
34+
$shopBillingData->setCompany($company);
35+
$shopBillingData->setStreet($street);
36+
$shopBillingData->setPostcode($postcode);
37+
$shopBillingData->setCity($city);
38+
$shopBillingData->setCountryCode($country->getCode());
39+
$shopBillingData->setTaxId($taxId);
40+
$shopBillingData->setVatNumber($vatNumber);
41+
42+
$channel->setShopBillingData($shopBillingData);
43+
44+
$this->channelManager->flush();
45+
}
46+
}

0 commit comments

Comments
 (0)