Passed
Push — 6.5.0.0 ( 27ba79...b0de28 )
by Christian
10:05 queued 12s
created

OrderActionTrait   A

Complexity

Total Complexity 10

Size/Duplication

Total Lines 262
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
eloc 164
dl 0
loc 262
rs 10
c 0
b 0
f 0
wmc 10

9 Methods

Rating   Name   Duplication   Size   Complexity  
A prepareProductTest() 0 17 1
A cancelOrder() 0 8 1
A createCustomerAndLogin() 0 7 1
A login() 0 19 1
A submitOrder() 0 23 1
A prepareCustomer() 0 31 1
A createCustomField() 0 34 1
B createOrder() 0 70 1
A getStateId() 0 14 2
1
<?php declare(strict_types=1);
2
3
namespace Shopware\Core\Content\Test\Flow;
4
5
use Doctrine\DBAL\Connection;
6
use Shopware\Core\Checkout\Cart\LineItem\LineItem;
7
use Shopware\Core\Checkout\Cart\Price\Struct\CalculatedPrice;
8
use Shopware\Core\Checkout\Cart\Price\Struct\CartPrice;
9
use Shopware\Core\Checkout\Cart\Price\Struct\QuantityPriceDefinition;
10
use Shopware\Core\Checkout\Cart\Tax\Struct\CalculatedTaxCollection;
11
use Shopware\Core\Checkout\Cart\Tax\Struct\TaxRuleCollection;
12
use Shopware\Core\Content\Product\Aggregate\ProductVisibility\ProductVisibilityDefinition;
13
use Shopware\Core\Defaults;
14
use Shopware\Core\Framework\Context;
15
use Shopware\Core\Framework\DataAbstractionLayer\EntityRepository;
16
use Shopware\Core\Framework\DataAbstractionLayer\Pricing\CashRoundingConfig;
17
use Shopware\Core\Framework\Log\Package;
18
use Shopware\Core\Framework\Test\TestCaseBase\CountryAddToSalesChannelTestBehaviour;
19
use Shopware\Core\Framework\Test\TestCaseBase\IntegrationTestBehaviour;
20
use Shopware\Core\Framework\Test\TestCaseBase\SalesChannelApiTestBehaviour;
21
use Shopware\Core\Framework\Test\TestDataCollection;
22
use Shopware\Core\Framework\Uuid\Uuid;
23
use Shopware\Core\PlatformRequest;
24
use Shopware\Core\System\CustomField\CustomFieldTypes;
25
use Shopware\Core\Test\TestDefaults;
26
use Symfony\Bundle\FrameworkBundle\KernelBrowser;
27
28
#[Package('business-ops')]
29
trait OrderActionTrait
30
{
31
    use IntegrationTestBehaviour;
32
    use SalesChannelApiTestBehaviour;
33
    use CountryAddToSalesChannelTestBehaviour;
34
35
    private KernelBrowser $browser;
36
37
    private TestDataCollection $ids;
38
39
    private ?EntityRepository $customerRepository = null;
40
41
    private function createCustomerAndLogin(?string $email = null, ?string $password = null): void
42
    {
43
        $email ??= Uuid::randomHex() . '@example.com';
44
        $password ??= 'shopware';
45
        $this->prepareCustomer($password, $email);
46
47
        $this->login($email, $password);
48
    }
49
50
    /**
51
     * @param array<string, mixed> $additionalData
52
     */
53
    private function prepareCustomer(string $password, ?string $email = null, array $additionalData = []): void
54
    {
55
        static::assertNotNull($this->customerRepository);
56
57
        $this->customerRepository->create([
0 ignored issues
show
Bug introduced by
The method create() does not exist on null. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

57
        $this->customerRepository->/** @scrutinizer ignore-call */ 
58
                                   create([

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
58
            array_merge([
59
                'id' => $this->ids->create('customer'),
60
                'salesChannelId' => $this->ids->get('sales-channel'),
61
                'defaultShippingAddress' => [
62
                    'id' => $this->ids->create('address'),
63
                    'firstName' => 'Max',
64
                    'lastName' => 'Mustermann',
65
                    'street' => 'Musterstraße 1',
66
                    'city' => 'Schöppingen',
67
                    'zipcode' => '12345',
68
                    'salutationId' => $this->getValidSalutationId(),
69
                    'countryId' => $this->getValidCountryId($this->ids->get('sales-channel')),
70
                ],
71
                'defaultBillingAddressId' => $this->ids->get('address'),
72
                'defaultPaymentMethodId' => $this->getValidPaymentMethodId(),
73
                'groupId' => TestDefaults::FALLBACK_CUSTOMER_GROUP,
74
                'email' => $email,
75
                'password' => $password,
76
                'firstName' => 'Max',
77
                'lastName' => 'Mustermann',
78
                'salutationId' => $this->getValidSalutationId(),
79
                'customerNumber' => '12345',
80
                'vatIds' => ['DE123456789'],
81
                'company' => 'Test',
82
            ], $additionalData),
83
        ], Context::createDefaultContext());
84
    }
85
86
    private function login(?string $email = null, ?string $password = null): void
87
    {
88
        $this->browser
89
            ->request(
90
                'POST',
91
                '/store-api/account/login',
92
                [
93
                    'email' => $email,
94
                    'password' => $password,
95
                ]
96
            );
97
98
        $response = $this->browser->getResponse();
99
100
        // After login successfully, the context token will be set in the header
101
        $contextToken = $response->headers->get(PlatformRequest::HEADER_CONTEXT_TOKEN) ?? '';
102
        static::assertNotEmpty($contextToken);
103
104
        $this->browser->setServerParameter('HTTP_SW_CONTEXT_TOKEN', $contextToken);
105
    }
106
107
    private function prepareProductTest(): void
108
    {
109
        $this->getContainer()->get('product.repository')->create([
110
            [
111
                'id' => $this->ids->create('p1'),
112
                'productNumber' => $this->ids->get('p1'),
113
                'stock' => 10,
114
                'name' => 'Test',
115
                'price' => [['currencyId' => Defaults::CURRENCY, 'gross' => 10, 'net' => 9, 'linked' => false]],
116
                'manufacturer' => ['id' => $this->ids->create('manufacturerId'), 'name' => 'test'],
117
                'tax' => ['id' => $this->ids->create('tax'), 'taxRate' => 17, 'name' => 'with id'],
118
                'active' => true,
119
                'visibilities' => [
120
                    ['salesChannelId' => $this->ids->get('sales-channel'), 'visibility' => ProductVisibilityDefinition::VISIBILITY_ALL],
121
                ],
122
            ],
123
        ], Context::createDefaultContext());
124
    }
125
126
    private function submitOrder(): void
127
    {
128
        $this->browser
129
            ->request(
130
                'POST',
131
                '/store-api/checkout/cart/line-item',
132
                [
133
                    'items' => [
134
                        [
135
                            'id' => $this->ids->get('p1'),
136
                            'type' => 'product',
137
                            'referencedId' => $this->ids->get('p1'),
138
                        ],
139
                    ],
140
                ]
141
            );
142
143
        $this->browser
144
            ->request(
145
                'POST',
146
                '/store-api/checkout/order',
147
                [
148
                    'affiliateCode' => 'test affiliate code',
149
                ]
150
            );
151
    }
152
153
    private function cancelOrder(): void
154
    {
155
        $this->browser
156
            ->request(
157
                'POST',
158
                '/store-api/order/state/cancel',
159
                [
160
                    'orderId' => $this->ids->get('order'),
161
                ]
162
            );
163
    }
164
165
    /**
166
     * @param array<string, mixed> $additionalData
167
     */
168
    private function createOrder(string $customerId, array $additionalData = []): void
169
    {
170
        $this->getContainer()->get('order.repository')->create([
171
            array_merge([
172
                'id' => $this->ids->create('order'),
173
                'itemRounding' => json_decode(json_encode(new CashRoundingConfig(2, 0.01, true), \JSON_THROW_ON_ERROR), true, 512, \JSON_THROW_ON_ERROR),
174
                'totalRounding' => json_decode(json_encode(new CashRoundingConfig(2, 0.01, true), \JSON_THROW_ON_ERROR), true, 512, \JSON_THROW_ON_ERROR),
175
                'orderDateTime' => (new \DateTimeImmutable())->format(Defaults::STORAGE_DATE_TIME_FORMAT),
176
                'price' => new CartPrice(10, 10, 10, new CalculatedTaxCollection(), new TaxRuleCollection(), CartPrice::TAX_STATE_NET),
177
                'shippingCosts' => new CalculatedPrice(10, 10, new CalculatedTaxCollection(), new TaxRuleCollection()),
178
                'orderCustomer' => [
179
                    'customerId' => $customerId,
180
                    'email' => '[email protected]',
181
                    'salutationId' => $this->getValidSalutationId(),
182
                    'firstName' => 'Max',
183
                    'lastName' => 'Mustermann',
184
                ],
185
                'orderNumber' => Uuid::randomHex(),
186
                'stateId' => $this->getStateMachineState(),
187
                'paymentMethodId' => $this->getValidPaymentMethodId(),
188
                'currencyId' => Defaults::CURRENCY,
189
                'currencyFactor' => 1.0,
190
                'salesChannelId' => TestDefaults::SALES_CHANNEL,
191
                'billingAddressId' => $billingAddressId = Uuid::randomHex(),
192
                'addresses' => [
193
                    [
194
                        'id' => $billingAddressId,
195
                        'salutationId' => $this->getValidSalutationId(),
196
                        'firstName' => 'Max',
197
                        'lastName' => 'Mustermann',
198
                        'street' => 'Ebbinghoff 10',
199
                        'zipcode' => '48624',
200
                        'city' => 'Schöppingen',
201
                        'countryId' => $this->getValidCountryId(),
202
                    ],
203
                ],
204
                'lineItems' => [
205
                    [
206
                        'id' => $this->ids->create('line-item'),
207
                        'identifier' => $this->ids->create('line-item'),
208
                        'quantity' => 1,
209
                        'label' => 'label',
210
                        'type' => LineItem::CUSTOM_LINE_ITEM_TYPE,
211
                        'price' => new CalculatedPrice(200, 200, new CalculatedTaxCollection(), new TaxRuleCollection()),
212
                        'priceDefinition' => new QuantityPriceDefinition(200, new TaxRuleCollection(), 2),
213
                    ],
214
                ],
215
                'deliveries' => [
216
                    [
217
                        'id' => $this->ids->create('delivery'),
218
                        'shippingOrderAddressId' => $this->ids->create('shipping-address'),
219
                        'shippingMethodId' => $this->getAvailableShippingMethod()->getId(),
220
                        'stateId' => $this->getStateId('open', 'order_delivery.state'),
221
                        'trackingCodes' => [],
222
                        'shippingDateEarliest' => (new \DateTime())->format(Defaults::STORAGE_DATE_TIME_FORMAT),
223
                        'shippingDateLatest' => (new \DateTime())->format(Defaults::STORAGE_DATE_TIME_FORMAT),
224
                        'shippingCosts' => new CalculatedPrice(0, 0, new CalculatedTaxCollection(), new TaxRuleCollection()),
225
                        'positions' => [
226
                            [
227
                                'id' => $this->ids->create('position'),
228
                                'orderLineItemId' => $this->ids->create('line-item'),
229
                                'price' => new CalculatedPrice(200, 200, new CalculatedTaxCollection(), new TaxRuleCollection()),
230
                            ],
231
                        ],
232
                    ],
233
                ],
234
                'context' => '{}',
235
                'payload' => '{}',
236
            ], $additionalData),
237
        ], Context::createDefaultContext());
238
    }
239
240
    private function getStateId(string $state, string $machine): string
241
    {
242
        return $this->getContainer()->get(Connection::class)
243
            ->fetchOne('
244
                SELECT LOWER(HEX(state_machine_state.id))
245
                FROM state_machine_state
246
                    INNER JOIN  state_machine
247
                    ON state_machine.id = state_machine_state.state_machine_id
248
                    AND state_machine.technical_name = :machine
249
                WHERE state_machine_state.technical_name = :state
250
            ', [
251
                'state' => $state,
252
                'machine' => $machine,
253
            ]) ?: '';
254
    }
255
256
    private function createCustomField(string $name, string $entity, string $type = CustomFieldTypes::SELECT): string
257
    {
258
        $customFieldId = Uuid::randomHex();
259
        $customFieldSetId = Uuid::randomHex();
260
        $data = [
261
            'id' => $customFieldId,
262
            'name' => $name,
263
            'type' => $type,
264
            'customFieldSetId' => $customFieldSetId,
265
            'config' => [
266
                'componentName' => 'sw-field',
267
                'customFieldPosition' => 1,
268
                'customFieldType' => $type,
269
                'type' => $type,
270
                'label' => [
271
                    'en-GB' => 'lorem_ipsum',
272
                    'de-DE' => 'lorem_ipsum',
273
                ],
274
            ],
275
            'customFieldSet' => [
276
                'id' => $customFieldSetId,
277
                'name' => 'Custom Field Set',
278
                'relations' => [[
279
                    'id' => Uuid::randomHex(),
280
                    'customFieldSetId' => $customFieldSetId,
281
                    'entityName' => $entity,
282
                ]],
283
            ],
284
        ];
285
286
        $this->getContainer()->get('custom_field.repository')
287
            ->create([$data], Context::createDefaultContext());
288
289
        return $customFieldId;
290
    }
291
}
292