Skip to content

Commit 5bd3adb

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

2 files changed

Lines changed: 268 additions & 0 deletions

File tree

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
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 Open Software License (OSL 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/OSL-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+
* DISCLAIMER
17+
*
18+
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
19+
* versions in the future. If you wish to customize PrestaShop for your
20+
* needs please refer to https://devdocs.prestashop.com/ for more information.
21+
*
22+
* @author PrestaShop SA and Contributors <contact@prestashop.com>
23+
* @copyright Since 2007 PrestaShop SA and Contributors
24+
* @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
25+
*/
26+
27+
namespace PrestaShop\Module\APIResources\ApiPlatform\Resources\Discount;
28+
29+
use ApiPlatform\Metadata\ApiProperty;
30+
use ApiPlatform\Metadata\ApiResource;
31+
use PrestaShop\PrestaShop\Core\Domain\Discount\Query\GetDiscountForEditing;
32+
use PrestaShop\PrestaShop\Core\Domain\Discount\Command\AddDiscountCommand;
33+
use PrestaShop\PrestaShop\Core\Domain\Discount\Exception\DiscountNotFoundException;
34+
use PrestaShop\PrestaShop\Core\Domain\Discount\Exception\DiscountConstraintException;
35+
use PrestaShopBundle\ApiPlatform\Metadata\CQRSGet;
36+
use PrestaShopBundle\ApiPlatform\Metadata\CQRSCreate;
37+
use Symfony\Component\HttpFoundation\Response;
38+
39+
#[ApiResource(
40+
operations: [
41+
new CQRSGet(
42+
uriTemplate: '/discount/{discountId}',
43+
requirements: ['discountId' => '\d+'],
44+
CQRSQuery: GetDiscountForEditing::class,
45+
scopes: ['discount_read']
46+
),
47+
new CQRSCreate(
48+
uriTemplate: '/discount',
49+
CQRSCommand: AddDiscountCommand::class,
50+
validationContext: ['groups' => ['Default', 'Create']],
51+
scopes: ['discount_write'],
52+
CQRSCommandMapping: [
53+
'[names]' => '[localizedNames]',
54+
],
55+
),
56+
],
57+
exceptionToStatus: [
58+
DiscountNotFoundException::class => Response::HTTP_NOT_FOUND,
59+
DiscountConstraintException::class => Response::HTTP_UNPROCESSABLE_ENTITY,
60+
],
61+
)]
62+
class Discount
63+
{
64+
#[ApiProperty(identifier: true)]
65+
public int $discountId;
66+
#[Assert\NotBlank(groups: ['Create'])]
67+
public array $names;
68+
public int $priority;
69+
public bool $active;
70+
public string $validFrom;
71+
public string $validTo;
72+
public int $totalQuantity;
73+
public int $quantityPerUser;
74+
public string $description;
75+
public string $code;
76+
public int $customerId;
77+
public bool $highlightInCart;
78+
public bool $allowPartialUse;
79+
#[Assert\NotBlank(groups: ['Create'])]
80+
public string $type;
81+
public float $percentDiscount;
82+
public float $amountDiscount;
83+
public int $currencyId;
84+
public bool $isTaxIncluded;
85+
public int $productId;
86+
public array $combinations;
87+
public int $reductionProduct;
88+
}
Lines changed: 180 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,180 @@
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 Open Software License (OSL 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/OSL-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+
* DISCLAIMER
17+
*
18+
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
19+
* versions in the future. If you wish to customize PrestaShop for your
20+
* needs please refer to https://devdocs.prestashop.com/ for more information.
21+
*
22+
* @author PrestaShop SA and Contributors <contact@prestashop.com>
23+
* @copyright Since 2007 PrestaShop SA and Contributors
24+
* @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
25+
*/
26+
27+
declare(strict_types=1);
28+
29+
namespace PsApiResourcesTest\Integration\ApiPlatform;
30+
31+
use PrestaShop\PrestaShop\Core\Domain\Discount\Query\GetDiscountForEditing;
32+
use PrestaShop\PrestaShop\Core\Domain\Discount\Command\AddDiscountCommand;
33+
use PrestaShop\PrestaShop\Core\Domain\Discount\ValueObject\DiscountType;
34+
use Tests\Resources\Resetter\LanguageResetter;
35+
use Tests\Resources\Resetter\DiscountResetter;
36+
use Tests\Resources\ResourceResetter;
37+
38+
class DiscountEndpointTest extends ApiTestCase
39+
{
40+
public static function setUpBeforeClass(): void
41+
{
42+
parent::setUpBeforeClass();
43+
(new ResourceResetter())->backupTestModules();
44+
DiscountResetter::resetProducts();
45+
LanguageResetter::resetLanguages();
46+
self::addLanguageByLocale('fr-FR');
47+
self::createApiClient(['discount_write', 'discount_read']);
48+
}
49+
50+
public static function tearDownAfterClass(): void
51+
{
52+
parent::tearDownAfterClass();
53+
DiscountResetter::resetProducts();
54+
LanguageResetter::resetLanguages();
55+
// Reset modules folder that are removed with the FR language
56+
(new ResourceResetter())->resetTestModules();
57+
}
58+
59+
/**
60+
* @depends testAddDiscount
61+
*
62+
* @param int $discountId
63+
* @return int
64+
*/
65+
public function testGetDiscount(int $discountId): int
66+
{
67+
// skip test if class does not exist
68+
if (!class_exists(GetDiscountForEditing::class)) {
69+
$this->markTestSkipped('GetDiscountForEditing class does not exist');
70+
}
71+
72+
$bearerToken = $this->getBearerToken(['discount_read']);
73+
$response = static::createClient()->request('GET', '/discount/' . $discountId, [
74+
'auth_bearer' => $bearerToken,
75+
]);
76+
self::assertResponseStatusCodeSame(200);
77+
78+
$decodedResponse = json_decode($response->getContent(), true);
79+
$this->assertNotFalse($decodedResponse);
80+
$this->assertEquals(
81+
[
82+
],
83+
$decodedResponse
84+
);
85+
86+
return $discountId;
87+
}
88+
89+
90+
/**
91+
* @dataProvider discountTypesDataProvider
92+
*
93+
* @param string $type
94+
* @param array $names
95+
* @return int
96+
*/
97+
public function testAddDiscount(string $type, array $names): int
98+
{
99+
// skip test if class does not exist
100+
if (!class_exists(AddDiscountCommand::class)) {
101+
$this->markTestSkipped('AddDiscountCommand class does not exist');
102+
}
103+
104+
$bearerToken = $this->getBearerToken(['product_write']);
105+
$response = static::createClient()->request('POST', '/discount', [
106+
'auth_bearer' => $bearerToken,
107+
'json' => [
108+
'type' => $type,
109+
'names' => $names,
110+
],
111+
]);
112+
self::assertResponseStatusCodeSame(201);
113+
114+
$decodedResponse = json_decode($response->getContent(), true);
115+
$this->assertNotFalse($decodedResponse);
116+
$this->assertArrayHasKey('productId', $decodedResponse);
117+
$discountId = $decodedResponse['discountId'];
118+
$this->assertEquals(
119+
[
120+
],
121+
$decodedResponse
122+
);
123+
124+
return $discountId;
125+
}
126+
127+
public function discountTypesDataProvider(): array
128+
{
129+
return [
130+
[
131+
DiscountType::CART_LEVEL,
132+
[
133+
'en-US' => 'new cart level discount',
134+
'fr-FR' => 'nouveau discount panier',
135+
],
136+
],
137+
[
138+
DiscountType::PRODUCT_LEVEL,
139+
[
140+
'en-US' => 'new product level discount',
141+
'fr-FR' => 'nouveau discount produit',
142+
],
143+
],
144+
[
145+
DiscountType::FREE_GIFT,
146+
[
147+
'en-US' => 'new free gift discount',
148+
'fr-FR' => 'nouveau discount produit offert',
149+
],
150+
],
151+
[
152+
DiscountType::FREE_SHIPPING,
153+
[
154+
'en-US' => 'new free shipping discount',
155+
'fr-FR' => 'nouveau discount frais de port offert',
156+
],
157+
],
158+
[
159+
DiscountType::ORDER_LEVEL,
160+
[
161+
'en-US' => 'new order level discount',
162+
'fr-FR' => 'nouveau discount commande',
163+
],
164+
],
165+
];
166+
}
167+
168+
public function getProtectedEndpoints(): iterable
169+
{
170+
yield 'get endpoint' => [
171+
'GET',
172+
'/discount/1',
173+
];
174+
175+
yield 'create endpoint' => [
176+
'POST',
177+
'/discount',
178+
];
179+
}
180+
}

0 commit comments

Comments
 (0)