Skip to content

Commit d2d2f14

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

2 files changed

Lines changed: 268 additions & 0 deletions

File tree

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
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\Decimal\DecimalNumber;
32+
use PrestaShop\PrestaShop\Core\Domain\Discount\Query\GetDiscountForEditing;
33+
use PrestaShop\PrestaShop\Core\Domain\Discount\Command\AddDiscountCommand;
34+
use PrestaShop\PrestaShop\Core\Domain\Discount\Exception\DiscountNotFoundException;
35+
use PrestaShop\PrestaShop\Core\Domain\Discount\Exception\DiscountConstraintException;
36+
use PrestaShopBundle\ApiPlatform\Metadata\CQRSGet;
37+
use PrestaShopBundle\ApiPlatform\Metadata\CQRSCreate;
38+
use PrestaShopBundle\ApiPlatform\Metadata\LocalizedValue;
39+
use Symfony\Component\HttpFoundation\Response;
40+
41+
#[ApiResource(
42+
operations: [
43+
new CQRSGet(
44+
uriTemplate: '/discount/{discountId}',
45+
requirements: ['discountId' => '\d+'],
46+
CQRSQuery: GetDiscountForEditing::class,
47+
scopes: ['discount_read']
48+
),
49+
new CQRSCreate(
50+
uriTemplate: '/discount',
51+
CQRSCommand: AddDiscountCommand::class,
52+
validationContext: ['groups' => ['Default', 'Create']],
53+
scopes: ['discount_write'],
54+
CQRSQuery: GetDiscountForEditing::class,
55+
CQRSCommandMapping: [
56+
'[names]' => '[localizedNames]',
57+
],
58+
),
59+
],
60+
exceptionToStatus: [
61+
DiscountNotFoundException::class => Response::HTTP_NOT_FOUND,
62+
DiscountConstraintException::class => Response::HTTP_UNPROCESSABLE_ENTITY,
63+
],
64+
)]
65+
class Discount
66+
{
67+
#[ApiProperty(identifier: true)]
68+
public int $discountId;
69+
#[Assert\NotBlank(groups: ['Create'])]
70+
#[LocalizedValue]
71+
public array $names;
72+
public int $priority;
73+
public bool $active;
74+
public string $validFrom;
75+
public string $validTo;
76+
public int $totalQuantity;
77+
public int $quantityPerUser;
78+
public string $description;
79+
public string $code;
80+
public int $customerId;
81+
public bool $highlightInCart;
82+
public bool $allowPartialUse;
83+
#[Assert\NotBlank(groups: ['Create'])]
84+
public string $type;
85+
public ?DecimalNumber $percentDiscount;
86+
public ?DecimalNumber $amountDiscount;
87+
public int $currencyId;
88+
public bool $isTaxIncluded;
89+
public int $productId;
90+
public array $combinations;
91+
public int $reductionProduct;
92+
}
Lines changed: 176 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,176 @@
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+
44+
LanguageResetter::resetLanguages();
45+
self::addLanguageByLocale('fr-FR');
46+
self::createApiClient(['discount_write', 'discount_read']);
47+
}
48+
49+
public static function tearDownAfterClass(): void
50+
{
51+
parent::tearDownAfterClass();
52+
53+
LanguageResetter::resetLanguages();
54+
}
55+
56+
/**
57+
* @dataProvider discountTypesDataProvider
58+
*
59+
* @param string $type
60+
* @param array $names
61+
* @return int
62+
*/
63+
public function testAddDiscount(string $type, array $names): int
64+
{
65+
// skip test if class does not exist
66+
if (!class_exists(AddDiscountCommand::class)) {
67+
$this->markTestSkipped('AddDiscountCommand class does not exist');
68+
}
69+
70+
$bearerToken = $this->getBearerToken(['product_write']);
71+
$response = static::createClient()->request('POST', '/discount', [
72+
'auth_bearer' => $bearerToken,
73+
'json' => [
74+
'type' => $type,
75+
'names' => $names,
76+
],
77+
]);
78+
self::assertResponseStatusCodeSame(201);
79+
80+
$decodedResponse = json_decode($response->getContent(), true);
81+
$this->assertNotFalse($decodedResponse);
82+
$this->assertArrayHasKey('productId', $decodedResponse);
83+
$discountId = $decodedResponse['discountId'];
84+
$this->assertEquals(
85+
[
86+
],
87+
$decodedResponse
88+
);
89+
90+
return $discountId;
91+
}
92+
93+
public function discountTypesDataProvider(): array
94+
{
95+
return [
96+
[
97+
DiscountType::CART_LEVEL,
98+
[
99+
'en-US' => 'new cart level discount',
100+
'fr-FR' => 'nouveau discount panier',
101+
],
102+
],
103+
[
104+
DiscountType::PRODUCT_LEVEL,
105+
[
106+
'en-US' => 'new product level discount',
107+
'fr-FR' => 'nouveau discount produit',
108+
],
109+
],
110+
[
111+
DiscountType::FREE_GIFT,
112+
[
113+
'en-US' => 'new free gift discount',
114+
'fr-FR' => 'nouveau discount produit offert',
115+
],
116+
],
117+
[
118+
DiscountType::FREE_SHIPPING,
119+
[
120+
'en-US' => 'new free shipping discount',
121+
'fr-FR' => 'nouveau discount frais de port offert',
122+
],
123+
],
124+
[
125+
DiscountType::ORDER_LEVEL,
126+
[
127+
'en-US' => 'new order level discount',
128+
'fr-FR' => 'nouveau discount commande',
129+
],
130+
],
131+
];
132+
}
133+
134+
/**
135+
* @depends testAddDiscount
136+
*
137+
* @param int $discountId
138+
* @return int
139+
*/
140+
public function testGetDiscount(int $discountId): int
141+
{
142+
// skip test if class does not exist
143+
if (!class_exists(GetDiscountForEditing::class)) {
144+
$this->markTestSkipped('GetDiscountForEditing class does not exist');
145+
}
146+
147+
$bearerToken = $this->getBearerToken(['discount_read']);
148+
$response = static::createClient()->request('GET', '/discount/' . $discountId, [
149+
'auth_bearer' => $bearerToken,
150+
]);
151+
self::assertResponseStatusCodeSame(200);
152+
153+
$decodedResponse = json_decode($response->getContent(), true);
154+
$this->assertNotFalse($decodedResponse);
155+
$this->assertEquals(
156+
[
157+
],
158+
$decodedResponse
159+
);
160+
161+
return $discountId;
162+
}
163+
164+
public function getProtectedEndpoints(): iterable
165+
{
166+
yield 'get endpoint' => [
167+
'GET',
168+
'/discount/1',
169+
];
170+
171+
yield 'create endpoint' => [
172+
'POST',
173+
'/discount',
174+
];
175+
}
176+
}

0 commit comments

Comments
 (0)