Passed
Push — trunk ( 2ef630...41af6c )
by Christian
10:02 queued 15s
created

CartException::invalidCart()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 12
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 8
nc 2
nop 1
dl 0
loc 12
rs 10
c 0
b 0
f 0
1
<?php declare(strict_types=1);
2
3
namespace Shopware\Core\Checkout\Cart;
4
5
use Shopware\Core\Checkout\Cart\Error\ErrorCollection;
6
use Shopware\Core\Checkout\Cart\Exception\CartTokenNotFoundException;
7
use Shopware\Core\Checkout\Cart\Exception\CustomerNotLoggedInException;
8
use Shopware\Core\Checkout\Cart\Exception\InvalidCartException;
9
use Shopware\Core\Checkout\Customer\Exception\AddressNotFoundException;
10
use Shopware\Core\Framework\HttpException;
11
use Shopware\Core\Framework\Log\Package;
12
use Shopware\Core\Framework\ShopwareHttpException;
13
use Symfony\Component\HttpFoundation\Response;
14
15
#[Package('checkout')]
16
class CartException extends HttpException
17
{
18
    public const DESERIALIZE_FAILED_CODE = 'CHECKOUT__CART_DESERIALIZE_FAILED';
19
    public const TOKEN_NOT_FOUND_CODE = 'CHECKOUT__CART_TOKEN_NOT_FOUND';
20
    public const CUSTOMER_NOT_LOGGED_IN_CODE = 'CHECKOUT__CUSTOMER_NOT_LOGGED_IN';
21
    public const INSUFFICIENT_PERMISSION_CODE = 'CHECKOUT__INSUFFICIENT_PERMISSION';
22
    public const CART_DELIVERY_NOT_FOUND_CODE = 'CHECKOUT__CART_DELIVERY_POSITION_NOT_FOUND';
23
    public const CART_INVALID_CODE = 'CHECKOUT__CART_INVALID';
24
    public const CART_INVALID_LINE_ITEM_PAYLOAD_CODE = 'CHECKOUT__CART_INVALID_LINE_ITEM_PAYLOAD';
25
    public const CART_INVALID_LINE_ITEM_QUANTITY_CODE = 'CHECKOUT__CART_INVALID_LINE_ITEM_QUANTITY';
26
    public const CART_PAYMENT_INVALID_ORDER_STORED_CODE = 'CHECKOUT__CART_INVALID_PAYMENT_ORDER_STORED';
27
    public const CART_LINE_ITEM_NOT_FOUND_CODE = 'CHECKOUT__CART_LINE_ITEM_NOT_FOUND';
28
    public const CART_LINE_ITEM_NOT_REMOVABLE_CODE = 'CHECKOUT__CART_LINE_ITEM_NOT_REMOVABLE';
29
    public const CART_LINE_ITEM_NOT_STACKABLE_CODE = 'CHECKOUT__CART_LINE_ITEM_NOT_STACKABLE';
30
    public const CART_LINE_ITEM_TYPE_NOT_SUPPORTED_CODE = 'CHECKOUT__CART_LINE_ITEM_TYPE_NOT_SUPPORTED';
31
    public const CART_MISSING_LINE_ITEM_PRICE_CODE = 'CHECKOUT__CART_MISSING_LINE_ITEM_PRICE';
32
    public const CART_INVALID_PRICE_DEFINITION_CODE = 'CHECKOUT__CART_MISSING_PRICE_DEFINITION';
33
    public const CART_MIXED_LINE_ITEM_TYPE_CODE = 'CHECKOUT__CART_MIXED_LINE_ITEM_TYPE';
34
    public const CART_PAYLOAD_KEY_NOT_FOUND_CODE = 'CHECKOUT__CART_PAYLOAD_KEY_NOT_FOUND';
35
    public const CART_MISSING_DEFAULT_PRICE_COLLECTION_FOR_DISCOUNT_CODE = 'CHECKOUT__CART_MISSING_DEFAULT_PRICE_COLLECTION_FOR_DISCOUNT';
36
    public const CART_ABSOLUTE_DISCOUNT_MISSING_PRICE_COLLECTION_CODE = 'CHECKOUT__CART_ABSOLUTE_DISCOUNT_MISSING_PRICE_COLLECTION';
37
    public const CART_DISCOUNT_TYPE_NOT_SUPPORTED_CODE = 'CHECKOUT__CART_DISCOUNT_TYPE_NOT_SUPPORTED';
38
    public const CART_INVALID_PERCENTAGE_DISCOUNT_CODE = 'CHECKOUT__CART_INVALID_PERCENTAGE_DISCOUNT';
39
    public const CART_MISSING_DEFAULT_PRICE_COLLECTION_FOR_SURCHARGE_CODE = 'CHECKOUT__CART_MISSING_DEFAULT_PRICE_COLLECTION_FOR_SURCHARGE';
40
    public const CART_ABSOLUTE_SURCHARGE_MISSING_PRICE_COLLECTION_CODE = 'CHECKOUT__CART_ABSOLUTE_SURCHARGE_MISSING_PRICE_COLLECTION';
41
    public const CART_SURCHARGE_TYPE_NOT_SUPPORTED_CODE = 'CHECKOUT__CART_SURCHARGE_TYPE_NOT_SUPPORTED';
42
    public const CART_INVALID_PERCENTAGE_SURCHARGE_CODE = 'CHECKOUT__CART_INVALID_PERCENTAGE_SURCHARGE';
43
    public const CART_MISSING_BEHAVIOR_CODE = 'CHECKOUT__CART_MISSING_BEHAVIOR';
44
    public const TAX_ID_NOT_FOUND = 'CHECKOUT__TAX_ID_NOT_FOUND';
45
    public const TAX_ID_PARAMETER_IS_MISSING = 'CHECKOUT__TAX_ID_PARAMETER_IS_MISSING';
46
    public const PRICE_PARAMETER_IS_MISSING = 'CHECKOUT__PRICE_PARAMETER_IS_MISSING';
47
    public const PRICES_PARAMETER_IS_MISSING = 'CHECKOUT__PRICES_PARAMETER_IS_MISSING';
48
49
    public static function deserializeFailed(): self
50
    {
51
        return new self(
52
            Response::HTTP_BAD_REQUEST,
53
            self::DESERIALIZE_FAILED_CODE,
54
            'Failed to deserialize cart.'
55
        );
56
    }
57
58
    public static function tokenNotFound(string $token): self
59
    {
60
        return new CartTokenNotFoundException(Response::HTTP_NOT_FOUND, self::TOKEN_NOT_FOUND_CODE, 'Cart with token {{ token }} not found.', ['token' => $token]);
61
    }
62
63
    public static function customerNotLoggedIn(): self
64
    {
65
        return new CustomerNotLoggedInException(
66
            Response::HTTP_FORBIDDEN,
67
            self::CUSTOMER_NOT_LOGGED_IN_CODE,
68
            'Customer is not logged in.'
69
        );
70
    }
71
72
    public static function insufficientPermission(): self
73
    {
74
        return new self(
75
            Response::HTTP_FORBIDDEN,
76
            self::INSUFFICIENT_PERMISSION_CODE,
77
            'Insufficient permission.'
78
        );
79
    }
80
81
    public static function invalidPaymentButOrderStored(string $orderId): self
82
    {
83
        return new self(
84
            Response::HTTP_NOT_FOUND,
85
            self::CART_PAYMENT_INVALID_ORDER_STORED_CODE,
86
            'Order payment failed but order was stored with id {{ orderId }}.',
87
            ['orderId' => $orderId]
88
        );
89
    }
90
91
    /**
92
     * @return CartException|InvalidCartException
93
     */
94
    public static function invalidCart(ErrorCollection $errors)
95
    {
96
        $message = [];
97
        foreach ($errors as $error) {
98
            $message[] = $error->getId() . ': ' . $error->getMessage();
99
        }
100
101
        return new InvalidCartException(
102
            Response::HTTP_INTERNAL_SERVER_ERROR,
103
            self::CART_INVALID_CODE,
104
            'The cart is invalid, got {{ errorCount }} error(s): {{ errors }}',
105
            ['errorCount' => $errors->count(), 'errors' => implode(\PHP_EOL, $message)]
106
        );
107
    }
108
109
    public static function invalidChildQuantity(int $childQuantity, int $parentQuantity): self
110
    {
111
        return new self(
112
            Response::HTTP_BAD_REQUEST,
113
            self::CART_INVALID_LINE_ITEM_QUANTITY_CODE,
114
            'The quantity of a child "{{ childQuantity }}" must be a multiple of the parent quantity "{{ parentQuantity }}"',
115
            ['childQuantity' => $childQuantity, 'parentQuantity' => $parentQuantity]
116
        );
117
    }
118
119
    public static function invalidPayload(string $key, string $id): CartException
120
    {
121
        return new self(
122
            Response::HTTP_BAD_REQUEST,
123
            self::CART_INVALID_LINE_ITEM_PAYLOAD_CODE,
124
            'Unable to save payload with key `{{ key }}` on line item `{{ id }}`. Only scalar data types are allowed.',
125
            ['key' => $key, 'id' => $id]
126
        );
127
    }
128
129
    public static function invalidQuantity(int $quantity): self
130
    {
131
        return new self(
132
            Response::HTTP_BAD_REQUEST,
133
            self::CART_INVALID_LINE_ITEM_QUANTITY_CODE,
134
            'The quantity must be a positive integer. Given: "{{ quantity }}"',
135
            ['quantity' => $quantity]
136
        );
137
    }
138
139
    public static function deliveryNotFound(string $id): self
140
    {
141
        return new self(
142
            Response::HTTP_NOT_FOUND,
143
            self::CART_DELIVERY_NOT_FOUND_CODE,
144
            'Delivery with identifier {{ id }} not found.',
145
            ['id' => $id]
146
        );
147
    }
148
149
    public static function lineItemNotFound(string $id): self
150
    {
151
        return new self(
152
            Response::HTTP_NOT_FOUND,
153
            self::CART_LINE_ITEM_NOT_FOUND_CODE,
154
            'Line item with identifier {{ id }} not found.',
155
            ['id' => $id]
156
        );
157
    }
158
159
    public static function lineItemNotRemovable(string $id): self
160
    {
161
        return new self(
162
            Response::HTTP_BAD_REQUEST,
163
            self::CART_LINE_ITEM_NOT_REMOVABLE_CODE,
164
            'Line item with identifier {{ id }} is not removable.',
165
            ['id' => $id]
166
        );
167
    }
168
169
    public static function lineItemNotStackable(string $id): self
170
    {
171
        return new self(
172
            Response::HTTP_BAD_REQUEST,
173
            self::CART_LINE_ITEM_NOT_STACKABLE_CODE,
174
            'Line item with identifier "{{ id }}" is not stackable and the quantity cannot be changed.',
175
            ['id' => $id]
176
        );
177
    }
178
179
    public static function lineItemTypeNotSupported(string $type): self
180
    {
181
        return new self(
182
            Response::HTTP_BAD_REQUEST,
183
            self::CART_LINE_ITEM_TYPE_NOT_SUPPORTED_CODE,
184
            'Line item type "{{ type }}" is not supported.',
185
            ['type' => $type]
186
        );
187
    }
188
189
    public static function missingLineItemPrice(string $id): self
190
    {
191
        return new self(
192
            Response::HTTP_BAD_REQUEST,
193
            self::CART_MISSING_LINE_ITEM_PRICE_CODE,
194
            'Line item with identifier {{ id }} has no price.',
195
            ['id' => $id]
196
        );
197
    }
198
199
    public static function invalidPriceDefinition(): self
200
    {
201
        return new self(
202
            Response::HTTP_CONFLICT,
203
            self::CART_INVALID_PRICE_DEFINITION_CODE,
204
            'Provided price definition is invalid.'
205
        );
206
    }
207
208
    public static function mixedLineItemType(string $id, string $type): self
209
    {
210
        return new self(
211
            Response::HTTP_CONFLICT,
212
            self::CART_MIXED_LINE_ITEM_TYPE_CODE,
213
            'Line item with id {{ id }} already exists with different type {{ type }}.',
214
            ['id' => $id, 'type' => $type]
215
        );
216
    }
217
218
    public static function payloadKeyNotFound(string $key, string $lineItemId): self
219
    {
220
        return new self(
221
            Response::HTTP_BAD_REQUEST,
222
            self::CART_PAYLOAD_KEY_NOT_FOUND_CODE,
223
            'Payload key "{{ key }}" in line item "{{ id }}" not found.',
224
            ['key' => $key, 'id' => $lineItemId]
225
        );
226
    }
227
228
    public static function invalidPercentageDiscount(string $key): self
229
    {
230
        return new self(
231
            Response::HTTP_CONFLICT,
232
            self::CART_INVALID_PERCENTAGE_DISCOUNT_CODE,
233
            'Percentage discount {{ key }} requires a provided float value',
234
            ['key' => $key]
235
        );
236
    }
237
238
    public static function discountTypeNotSupported(string $key, string $type): self
239
    {
240
        return new self(
241
            Response::HTTP_CONFLICT,
242
            self::CART_DISCOUNT_TYPE_NOT_SUPPORTED_CODE,
243
            'Discount type "{{ type }}" is not supported for discount {{ key }}',
244
            ['key' => $key, 'type' => $type]
245
        );
246
    }
247
248
    public static function absoluteDiscountMissingPriceCollection(string $key): self
249
    {
250
        return new self(
251
            Response::HTTP_CONFLICT,
252
            self::CART_ABSOLUTE_DISCOUNT_MISSING_PRICE_COLLECTION_CODE,
253
            'Absolute discount {{ key }} requires a provided price collection. Use services.price(...) to create a price',
254
            ['key' => $key]
255
        );
256
    }
257
258
    public static function missingDefaultPriceCollectionForDiscount(string $key): self
259
    {
260
        return new self(
261
            Response::HTTP_CONFLICT,
262
            self::CART_MISSING_DEFAULT_PRICE_COLLECTION_FOR_DISCOUNT_CODE,
263
            'Absolute discount {{ key }} requires a defined currency price for the default currency. Use services.price(...) to create a compatible price object',
264
            ['key' => $key]
265
        );
266
    }
267
268
    public static function invalidPercentageSurcharge(string $key): self
269
    {
270
        return new self(
271
            Response::HTTP_CONFLICT,
272
            self::CART_INVALID_PERCENTAGE_SURCHARGE_CODE,
273
            'Percentage surcharge {{ key }} requires a provided float value',
274
            ['key' => $key]
275
        );
276
    }
277
278
    public static function surchargeTypeNotSupported(string $key, string $type): self
279
    {
280
        return new self(
281
            Response::HTTP_CONFLICT,
282
            self::CART_SURCHARGE_TYPE_NOT_SUPPORTED_CODE,
283
            'Surcharge type "{{ type }}" is not supported for surcharge {{ key }}',
284
            ['key' => $key, 'type' => $type]
285
        );
286
    }
287
288
    public static function absoluteSurchargeMissingPriceCollection(string $key): self
289
    {
290
        return new self(
291
            Response::HTTP_CONFLICT,
292
            self::CART_ABSOLUTE_SURCHARGE_MISSING_PRICE_COLLECTION_CODE,
293
            'Absolute surcharge {{ key }} requires a provided price collection. Use services.price(...) to create a price',
294
            ['key' => $key]
295
        );
296
    }
297
298
    public static function missingDefaultPriceCollectionForSurcharge(string $key): self
299
    {
300
        return new self(
301
            Response::HTTP_CONFLICT,
302
            self::CART_MISSING_DEFAULT_PRICE_COLLECTION_FOR_SURCHARGE_CODE,
303
            'Absolute surcharge {{ key }} requires a defined currency price for the default currency. Use services.price(...) to create a compatible price object',
304
            ['key' => $key]
305
        );
306
    }
307
308
    public static function missingCartBehavior(): self
309
    {
310
        return new self(
311
            Response::HTTP_BAD_REQUEST,
312
            self::CART_MISSING_BEHAVIOR_CODE,
313
            'Cart instance of the cart facade were never calculated. Please call calculate() before using the cart facade.'
314
        );
315
    }
316
317
    public static function taxRuleNotFound(string $taxId): self
318
    {
319
        return new self(
320
            Response::HTTP_NOT_FOUND,
321
            self::TAX_ID_NOT_FOUND,
322
            'Tax rule with id "{{ taxId }}" not found.',
323
            ['taxId' => $taxId]
324
        );
325
    }
326
327
    public static function taxIdParameterIsMissing(): self
328
    {
329
        return new self(
330
            Response::HTTP_BAD_REQUEST,
331
            self::TAX_ID_PARAMETER_IS_MISSING,
332
            'Parameter "taxId" is missing.',
333
        );
334
    }
335
336
    public static function priceParameterIsMissing(): self
337
    {
338
        return new self(
339
            Response::HTTP_BAD_REQUEST,
340
            self::PRICE_PARAMETER_IS_MISSING,
341
            'Parameter "price" is missing.',
342
        );
343
    }
344
345
    public static function pricesParameterIsMissing(): self
346
    {
347
        return new self(
348
            Response::HTTP_BAD_REQUEST,
349
            self::PRICES_PARAMETER_IS_MISSING,
350
            'Parameter "prices" is missing.',
351
        );
352
    }
353
354
    public static function addressNotFound(string $id): ShopwareHttpException
355
    {
356
        return new AddressNotFoundException($id);
357
    }
358
}
359