Skip to content

Commit f129134

Browse files
committed
chore(api) add discount enpoint
1 parent 6049c52 commit f129134

File tree

2 files changed

+273
-0
lines changed

2 files changed

+273
-0
lines changed
Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
<?php
2+
/**
3+
* Copyright since 2007 PrestaShop SA and Contributors
4+
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
5+
*
6+
* NOTICE OF LICENSE
7+
*
8+
* This source file is subject to the Academic Free License version 3.0
9+
* that is bundled with this package in the file LICENSE.md.
10+
* It is also available through the world-wide-web at this URL:
11+
* https://opensource.org/licenses/AFL-3.0
12+
* If you did not receive a copy of the license and are unable to
13+
* obtain it through the world-wide-web, please send an email
14+
* to license@prestashop.com so we can send you a copy immediately.
15+
*
16+
* @author PrestaShop SA and Contributors <contact@prestashop.com>
17+
* @copyright Since 2007 PrestaShop SA and Contributors
18+
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0
19+
*/
20+
21+
namespace PrestaShop\Module\APIResources\ApiPlatform\Resources\Discount;
22+
23+
use ApiPlatform\Metadata\ApiProperty;
24+
use ApiPlatform\Metadata\ApiResource;
25+
use PrestaShop\Decimal\DecimalNumber;
26+
use PrestaShop\PrestaShop\Core\Domain\Discount\Command\AddDiscountCommand;
27+
use PrestaShop\PrestaShop\Core\Domain\Discount\Exception\DiscountConstraintException;
28+
use PrestaShop\PrestaShop\Core\Domain\Discount\Exception\DiscountNotFoundException;
29+
use PrestaShop\PrestaShop\Core\Domain\Discount\Query\GetDiscountForEditing;
30+
use PrestaShopBundle\ApiPlatform\Metadata\CQRSCreate;
31+
use PrestaShopBundle\ApiPlatform\Metadata\CQRSGet;
32+
use PrestaShopBundle\ApiPlatform\Metadata\LocalizedValue;
33+
use Symfony\Component\HttpFoundation\Response;
34+
35+
#[ApiResource(
36+
operations: [
37+
new CQRSGet(
38+
uriTemplate: '/discount/{discountId}',
39+
requirements: ['discountId' => '\d+'],
40+
CQRSQuery: GetDiscountForEditing::class,
41+
scopes: ['discount_read']
42+
),
43+
new CQRSCreate(
44+
uriTemplate: '/discount',
45+
validationContext: ['groups' => ['Default', 'Create']],
46+
CQRSCommand: AddDiscountCommand::class,
47+
CQRSQuery: GetDiscountForEditing::class,
48+
scopes: ['discount_write'],
49+
CQRSCommandMapping: [
50+
'[names]' => '[localizedNames]',
51+
],
52+
),
53+
],
54+
exceptionToStatus: [
55+
DiscountNotFoundException::class => Response::HTTP_NOT_FOUND,
56+
DiscountConstraintException::class => Response::HTTP_UNPROCESSABLE_ENTITY,
57+
],
58+
)]
59+
class Discount
60+
{
61+
#[ApiProperty(identifier: true)]
62+
public int $discountId;
63+
#[Assert\NotBlank(groups: ['Create'])]
64+
#[LocalizedValue]
65+
public array $names;
66+
public int $priority;
67+
public bool $active;
68+
public \DateTimeImmutable $validFrom;
69+
public \DateTimeImmutable $validTo;
70+
public int $totalQuantity;
71+
public int $quantityPerUser;
72+
public string $description;
73+
public string $code;
74+
public int $customerId;
75+
public bool $highlightInCart;
76+
public bool $allowPartialUse;
77+
#[Assert\NotBlank(groups: ['Create'])]
78+
public string $type;
79+
public ?DecimalNumber $percentDiscount;
80+
public ?DecimalNumber $amountDiscount;
81+
public int $currencyId;
82+
public bool $isTaxIncluded;
83+
public int $productId;
84+
public array $combinations;
85+
public int $reductionProduct;
86+
}
Lines changed: 187 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,187 @@
1+
<?php
2+
/**
3+
* Copyright since 2007 PrestaShop SA and Contributors
4+
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
5+
*
6+
* NOTICE OF LICENSE
7+
*
8+
* This source file is subject to the Academic Free License version 3.0
9+
* that is bundled with this package in the file LICENSE.md.
10+
* It is also available through the world-wide-web at this URL:
11+
* https://opensource.org/licenses/AFL-3.0
12+
* If you did not receive a copy of the license and are unable to
13+
* obtain it through the world-wide-web, please send an email
14+
* to license@prestashop.com so we can send you a copy immediately.
15+
*
16+
* @author PrestaShop SA and Contributors <contact@prestashop.com>
17+
* @copyright Since 2007 PrestaShop SA and Contributors
18+
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0
19+
*/
20+
21+
declare(strict_types=1);
22+
23+
namespace PsApiResourcesTest\Integration\ApiPlatform;
24+
25+
use PrestaShop\PrestaShop\Core\Domain\Discount\Command\AddDiscountCommand;
26+
use PrestaShop\PrestaShop\Core\Domain\Discount\Query\GetDiscountForEditing;
27+
use Tests\Resources\Resetter\LanguageResetter;
28+
29+
class DiscountEndpointTest extends ApiTestCase
30+
{
31+
public const CART_LEVEL = 'cart_level';
32+
public const PRODUCT_LEVEL = 'product_level';
33+
public const FREE_GIFT = 'free_gift';
34+
public const FREE_SHIPPING = 'free_shipping';
35+
public const ORDER_LEVEL = 'order_level';
36+
37+
public static function setUpBeforeClass(): void
38+
{
39+
parent::setUpBeforeClass();
40+
41+
LanguageResetter::resetLanguages();
42+
self::addLanguageByLocale('fr-FR');
43+
self::createApiClient(['discount_write', 'discount_read']);
44+
}
45+
46+
public static function tearDownAfterClass(): void
47+
{
48+
parent::tearDownAfterClass();
49+
50+
LanguageResetter::resetLanguages();
51+
}
52+
53+
/**
54+
* @dataProvider discountTypesDataProvider
55+
*
56+
* @param string $type
57+
* @param array $names
58+
*
59+
* @return int
60+
*/
61+
public function testAddDiscount(string $type, array $names, ?array $data): int
62+
{
63+
// skip test if class does not exist
64+
if (!class_exists(AddDiscountCommand::class)) {
65+
$this->markTestSkipped('AddDiscountCommand class does not exist');
66+
}
67+
68+
$bearerToken = $this->getBearerToken(['discount_write']);
69+
$json = [
70+
'type' => $type,
71+
'names' => $names,
72+
];
73+
if ($data !== null) {
74+
$json = array_merge($json, $data);
75+
}
76+
$response = static::createClient()->request('POST', '/discount', [
77+
'auth_bearer' => $bearerToken,
78+
'json' => $json,
79+
]);
80+
self::assertResponseStatusCodeSame(201);
81+
82+
$decodedResponse = json_decode($response->getContent(), true);
83+
$this->assertNotFalse($decodedResponse);
84+
$this->assertArrayHasKey('discountId', $decodedResponse);
85+
$discountId = $decodedResponse['discountId'];
86+
$this->assertArrayHasKey(
87+
'type',
88+
$decodedResponse
89+
);
90+
$this->assertEquals($type, $decodedResponse['type']);
91+
92+
return $discountId;
93+
}
94+
95+
public function discountTypesDataProvider(): array
96+
{
97+
return [
98+
[
99+
self::CART_LEVEL,
100+
[
101+
'en-US' => 'new cart level discount',
102+
'fr-FR' => 'nouveau discount panier',
103+
],
104+
null,
105+
],
106+
[
107+
self::PRODUCT_LEVEL,
108+
[
109+
'en-US' => 'new product level discount',
110+
'fr-FR' => 'nouveau discount produit',
111+
],
112+
[
113+
'reductionProduct' => -1,
114+
'percentDiscount' => 20.0,
115+
],
116+
],
117+
[
118+
self::FREE_GIFT,
119+
[
120+
'en-US' => 'new free gift discount',
121+
'fr-FR' => 'nouveau discount produit offert',
122+
],
123+
[
124+
'productId' => 1,
125+
],
126+
],
127+
[
128+
self::FREE_SHIPPING,
129+
[
130+
'en-US' => 'new free shipping discount',
131+
'fr-FR' => 'nouveau discount frais de port offert',
132+
],
133+
null,
134+
],
135+
[
136+
self::ORDER_LEVEL,
137+
[
138+
'en-US' => 'new order level discount',
139+
'fr-FR' => 'nouveau discount commande',
140+
],
141+
null,
142+
],
143+
];
144+
}
145+
146+
/**
147+
* @depends testAddDiscount
148+
*
149+
* @return int
150+
*/
151+
public function testGetDiscount(): void
152+
{
153+
// skip test if class does not exist
154+
if (!class_exists(GetDiscountForEditing::class)) {
155+
$this->markTestSkipped('GetDiscountForEditing class does not exist');
156+
}
157+
158+
$bearerToken = $this->getBearerToken(['discount_read']);
159+
$response = static::createClient()->request('GET', '/discount/1', [
160+
'auth_bearer' => $bearerToken,
161+
]);
162+
self::assertResponseStatusCodeSame(200);
163+
164+
$decodedResponse = json_decode($response->getContent(), true);
165+
166+
$this->assertNotFalse($decodedResponse);
167+
$this->assertArrayHasKey('discountId', $decodedResponse);
168+
$this->assertArrayHasKey(
169+
'type',
170+
$decodedResponse
171+
);
172+
$this->assertEquals('cart_level', $decodedResponse['type']);
173+
}
174+
175+
public function getProtectedEndpoints(): iterable
176+
{
177+
yield 'get endpoint' => [
178+
'GET',
179+
'/discount/1',
180+
];
181+
182+
yield 'create endpoint' => [
183+
'POST',
184+
'/discount',
185+
];
186+
}
187+
}

0 commit comments

Comments
 (0)