1
0
mirror of synced 2024-11-21 21:06:07 +03:00

Support for /api/v5/loyalty/loyalties/{id} and `/api/v5/loyalty/account/{id}

closes #108
This commit is contained in:
Pavel 2021-08-17 18:33:15 +03:00 committed by GitHub
parent cfa975db17
commit 7d3ae80fe7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 348 additions and 13 deletions

View File

@ -33,6 +33,8 @@ use RetailCrm\Api\Model\Entity\Customers\CustomerTag;
use RetailCrm\Api\Model\Entity\CustomersCorporate\CustomerCorporate;
use RetailCrm\Api\Component\Serializer\Template\CustomSerialization;
use RetailCrm\Api\Component\Serializer\Type\PropertyTypeMixed;
use RetailCrm\Api\Model\Entity\CustomersCorporate\SerializedRelationAbstractCustomer;
use RetailCrm\Api\Model\Entity\Orders\SerializedRelationCustomer;
use RuntimeException;
use Symfony\Component\Filesystem\Filesystem;
@ -267,6 +269,20 @@ class SerializerGenerator
new PreferredReducer(),
new TakeBestReducer(),
]);
$serializedRelationAbstract = $this->metadataBuilder->build(
SerializedRelationAbstractCustomer::class,
[
new PreferredReducer(),
new TakeBestReducer(),
]
);
$serializedRelation = $this->metadataBuilder->build(
SerializedRelationCustomer::class,
[
new PreferredReducer(),
new TakeBestReducer(),
]
);
$customerCode = $this->generateCodeForClass(
$customerMetadata,
$apiVersion,
@ -281,8 +297,29 @@ class SerializerGenerator
$arrayPath,
$modelPath
);
$serializedRelationAbstractCode = $this->generateCodeForClass(
$serializedRelationAbstract,
$apiVersion,
$serializerGroups,
$arrayPath,
$modelPath
);
$serializedRelationCode = $this->generateCodeForClass(
$serializedRelation,
$apiVersion,
$serializerGroups,
$arrayPath,
$modelPath
);
return $this->customTemplating->renderCustomerInterface($arrayPath, $modelPath, $customerCode, $corporateCode);
return $this->customTemplating->renderCustomerInterface(
$arrayPath,
$modelPath,
$customerCode,
$corporateCode,
$serializedRelationAbstractCode,
$serializedRelationCode
);
}
/**

View File

@ -28,6 +28,10 @@ if ({{modelPath}} instanceof \RetailCrm\Api\Model\Entity\Customers\Customer) {
{{customerCode}}
} elseif ({{modelPath}} instanceof \RetailCrm\Api\Model\Entity\CustomersCorporate\CustomerCorporate) {
{{corporateCode}}
} elseif ({{modelPath}} instanceof \RetailCrm\Api\Model\Entity\CustomersCorporate\SerializedRelationAbstractCustomer) {
{{serializedRelationAbstractCode}}
} elseif ({{modelPath}} instanceof \RetailCrm\Api\Model\Entity\Orders\SerializedRelationCustomer) {
{{serializedRelationCode}}
}
if (0 === \count($jsonData{{jsonPath}})) {
@ -40,6 +44,8 @@ EOT;
* @param string $modelPath
* @param string $customerCode
* @param string $corporateCode
* @param string $relationAbstractCode
* @param string $relationCode
*
* @return string
* @throws \Twig\Error\LoaderError
@ -49,13 +55,17 @@ EOT;
string $jsonPath,
string $modelPath,
string $customerCode,
string $corporateCode
string $corporateCode,
string $relationAbstractCode,
string $relationCode
): string {
return $this->render(self::TMPL_CUSTOMER_INTERFACE, [
'jsonPath' => $jsonPath,
'modelPath' => $modelPath,
'customerCode' => $customerCode,
'corporateCode' => $corporateCode,
'serializedRelationAbstractCode' => $relationAbstractCode,
'serializedRelationCode' => $relationCode,
]);
}
}

View File

@ -74,4 +74,12 @@ class SerializedEntityCustomer
* @JMS\SerializedName("patronymic")
*/
public $patronymic;
/**
* @var array<string, mixed>
*
* @JMS\Type("array")
* @JMS\SerializedName("customFields")
*/
public $customFields;
}

View File

@ -10,6 +10,7 @@
namespace RetailCrm\Api\Model\Entity\CustomersCorporate;
use RetailCrm\Api\Component\Serializer\Annotation as JMS;
use RetailCrm\Api\Interfaces\Orders\CustomerInterface;
/**
* Class SerializedRelationAbstractCustomer
@ -17,7 +18,7 @@ use RetailCrm\Api\Component\Serializer\Annotation as JMS;
* @category SerializedRelationAbstractCustomer
* @package RetailCrm\Api\Model\Entity\CustomersCorporate
*/
class SerializedRelationAbstractCustomer
class SerializedRelationAbstractCustomer implements CustomerInterface
{
/**
* @var int
@ -68,7 +69,7 @@ class SerializedRelationAbstractCustomer
*/
public static function withId(int $id): self
{
$customer = new self();
$customer = new self();
$customer->id = $id;
return $customer;
@ -84,9 +85,9 @@ class SerializedRelationAbstractCustomer
*/
public static function withExternalId(string $externalId, string $site): self
{
$customer = new self();
$customer = new self();
$customer->externalId = $externalId;
$customer->site = $site;
$customer->site = $site;
return $customer;
}

View File

@ -131,4 +131,20 @@ class LoyaltyAccount
* @JMS\SerializedName("level")
*/
public $level;
/**
* @var string
*
* @JMS\Type("string")
* @JMS\SerializedName("status")
*/
public $status;
/**
* @var \RetailCrm\Api\Model\Entity\Loyalty\Loyalty
*
* @JMS\Type("RetailCrm\Api\Model\Entity\Loyalty\Loyalty")
* @JMS\SerializedName("loyalty")
*/
public $loyalty;
}

View File

@ -10,7 +10,6 @@
namespace RetailCrm\Api\Model\Entity\Orders;
use RetailCrm\Api\Component\Serializer\Annotation as JMS;
use RetailCrm\Api\Interfaces\Orders\CustomerInterface;
use RetailCrm\Api\Model\Entity\CustomersCorporate\SerializedRelationAbstractCustomer;
/**
@ -19,7 +18,7 @@ use RetailCrm\Api\Model\Entity\CustomersCorporate\SerializedRelationAbstractCust
* @category SerializedRelationCustomer
* @package RetailCrm\Api\Model\Entity\Orders
*/
class SerializedRelationCustomer extends SerializedRelationAbstractCustomer implements CustomerInterface
class SerializedRelationCustomer extends SerializedRelationAbstractCustomer
{
/**
* @var string
@ -47,8 +46,8 @@ class SerializedRelationCustomer extends SerializedRelationAbstractCustomer impl
*/
public static function withIdAndType(int $id, string $type): self
{
$customer = new self();
$customer->id = $id;
$customer = new self();
$customer->id = $id;
$customer->type = $type;
return $customer;
@ -65,10 +64,10 @@ class SerializedRelationCustomer extends SerializedRelationAbstractCustomer impl
*/
public static function withExternalIdAndType(string $externalId, string $type, string $site): self
{
$customer = new self();
$customer = new self();
$customer->externalId = $externalId;
$customer->type = $type;
$customer->site = $site;
$customer->type = $type;
$customer->site = $site;
return $customer;
}

View File

@ -0,0 +1,30 @@
<?php
/**
* PHP version 7.3
*
* @category LoyaltyAccountResponse
* @package RetailCrm\Api\Model\Response\Loyalty
*/
namespace RetailCrm\Api\Model\Response\Loyalty;
use RetailCrm\Api\Component\Serializer\Annotation as JMS;
use RetailCrm\Api\Model\Response\SuccessResponse;
/**
* Class LoyaltyAccountResponse
*
* @category LoyaltyAccountResponse
* @package RetailCrm\Api\Model\Response\Loyalty
*/
class LoyaltyAccountResponse extends SuccessResponse
{
/**
* @var \RetailCrm\Api\Model\Entity\Loyalty\LoyaltyAccount
*
* @JMS\Type("RetailCrm\Api\Model\Entity\Loyalty\LoyaltyAccount")
* @JMS\SerializedName("loyaltyAccount")
*/
public $loyaltyAccount;
}

View File

@ -0,0 +1,38 @@
<?php
/**
* PHP 7.3
*
* @category LoyaltyResponse
* @package RetailCrm\Api\Model\Response\Loyalty
*/
namespace RetailCrm\Api\Model\Response\Loyalty;
use RetailCrm\Api\Component\Serializer\Annotation as JMS;
use RetailCrm\Api\Model\Response\SuccessResponse;
/**
* Class LoyaltyResponse
*
* @category LoyaltyResponse
* @package RetailCrm\Api\Model\Response\Loyalty
*/
class LoyaltyResponse extends SuccessResponse
{
/**
* @var \RetailCrm\Api\Model\Entity\Loyalty\Loyalty
*
* @JMS\Type("RetailCrm\Api\Model\Entity\Loyalty\Loyalty")
* @JMS\SerializedName("loyalty")
*/
public $loyalty;
/**
* @var array<string, mixed>
*
* @JMS\Type("array")
* @JMS\SerializedName("requiredFields")
*/
public $requiredFields;
}

View File

@ -20,10 +20,12 @@ use RetailCrm\Api\Model\Request\Loyalty\LoyaltyCalculateRequest;
use RetailCrm\Api\Model\Response\Loyalty\LoyaltiesResponse;
use RetailCrm\Api\Model\Response\Loyalty\LoyaltyAccountActivateResponse;
use RetailCrm\Api\Model\Response\Loyalty\LoyaltyAccountCreateResponse;
use RetailCrm\Api\Model\Response\Loyalty\LoyaltyAccountResponse;
use RetailCrm\Api\Model\Response\Loyalty\LoyaltyAccountsResponse;
use RetailCrm\Api\Model\Response\Loyalty\LoyaltyBonusCreditResponse;
use RetailCrm\Api\Model\Response\Loyalty\LoyaltyBonusOperationsResponse;
use RetailCrm\Api\Model\Response\Loyalty\LoyaltyCalculateResponse;
use RetailCrm\Api\Model\Response\Loyalty\LoyaltyResponse;
/**
* Class Loyalty
@ -406,6 +408,60 @@ class Loyalty extends AbstractApiResourceGroup
return $response;
}
/**
* Makes GET "/api/v5/loyalty/account/{id}" request.
*
* Example:
* ```php
* use RetailCrm\Api\Factory\SimpleClientFactory;
* use RetailCrm\Api\Interfaces\ApiExceptionInterface;
*
* $client = SimpleClientFactory::createClient('https://test.retailcrm.pro', 'apiKey');
*
* try {
* $response = $client->loyalty->accountGet(1);
* } catch (ApiExceptionInterface $exception) {
* echo sprintf(
* 'Error from RetailCRM API (status code: %d): %s',
* $exception->getStatusCode(),
* $exception->getMessage()
* );
*
* if (count($exception->getErrorResponse()->errors) > 0) {
* echo PHP_EOL . 'Errors: ' . implode(', ', $exception->getErrorResponse()->errors);
* }
*
* return;
* }
*
* echo 'Current loyalty account balance: ' . $response->loyaltyAccount->amount . ' bonuses.';
* ```
*
* @param int $id
*
* @return \RetailCrm\Api\Model\Response\Loyalty\LoyaltyAccountResponse
* @throws \RetailCrm\Api\Exception\Api\AccountDoesNotExistException
* @throws \RetailCrm\Api\Exception\Api\ApiErrorException
* @throws \RetailCrm\Api\Exception\Api\MissingCredentialsException
* @throws \RetailCrm\Api\Exception\Api\MissingParameterException
* @throws \RetailCrm\Api\Exception\Api\ValidationException
* @throws \RetailCrm\Api\Exception\Client\HandlerException
* @throws \RetailCrm\Api\Exception\Client\HttpClientException
* @throws \RetailCrm\Api\Interfaces\ApiExceptionInterface
* @throws \RetailCrm\Api\Interfaces\ClientExceptionInterface
*/
public function accountGet(int $id): LoyaltyAccountResponse
{
/** @var LoyaltyAccountResponse $response */
$response = $this->sendRequest(
RequestMethod::GET,
'loyalty/account/' . $id,
null,
LoyaltyAccountResponse::class
);
return $response;
}
/**
* Makes POST "/api/v5/loyalty/calculate" request.
*
@ -546,4 +602,58 @@ class Loyalty extends AbstractApiResourceGroup
);
return $response;
}
/**
* Makes GET "/api/v5/loyalty/loyalties/{id}" request.
*
* Example:
* ```php
* use RetailCrm\Api\Factory\SimpleClientFactory;
* use RetailCrm\Api\Interfaces\ApiExceptionInterface;
*
* $client = SimpleClientFactory::createClient('https://test.retailcrm.pro', 'apiKey');
*
* try {
* $response = $client->loyalty->get(1);
* } catch (ApiExceptionInterface $exception) {
* echo sprintf(
* 'Error from RetailCRM API (status code: %d): %s',
* $exception->getStatusCode(),
* $exception->getMessage()
* );
*
* if (count($exception->getErrorResponse()->errors) > 0) {
* echo PHP_EOL . 'Errors: ' . implode(', ', $exception->getErrorResponse()->errors);
* }
*
* return;
* }
*
* echo 'Loyalty program name: ' . $response->loyalty->name;
* ```
*
* @param int $id
*
* @return \RetailCrm\Api\Model\Response\Loyalty\LoyaltyResponse
* @throws \RetailCrm\Api\Exception\Api\AccountDoesNotExistException
* @throws \RetailCrm\Api\Exception\Api\ApiErrorException
* @throws \RetailCrm\Api\Exception\Api\MissingCredentialsException
* @throws \RetailCrm\Api\Exception\Api\MissingParameterException
* @throws \RetailCrm\Api\Exception\Api\ValidationException
* @throws \RetailCrm\Api\Exception\Client\HandlerException
* @throws \RetailCrm\Api\Exception\Client\HttpClientException
* @throws \RetailCrm\Api\Interfaces\ApiExceptionInterface
* @throws \RetailCrm\Api\Interfaces\ClientExceptionInterface
*/
public function get(int $id): LoyaltyResponse
{
/** @var LoyaltyResponse $response */
$response = $this->sendRequest(
RequestMethod::GET,
'loyalty/loyalties/' . $id,
null,
LoyaltyResponse::class
);
return $response;
}
}

View File

@ -595,6 +595,55 @@ EOF;
self::assertModelEqualsToResponse($json, $response);
}
public function testAccountGet(): void
{
$json = <<<'EOF'
{
"success": true,
"loyaltyAccount": {
"active": false,
"id": 168,
"loyalty": {
"id": 1
},
"customer": {
"id": 5260,
"externalId": "5",
"site": "bitrix-test",
"customFields": {
"galkatrue": true
},
"firstName": "admincd"
},
"phoneNumber": "89226234577",
"amount": 0,
"ordersSum": 0,
"nextLevelSum": 10000,
"level": {
"type": "discount",
"id": 21,
"name": "Скидочный",
"privilegeSize": 20,
"privilegeSizePromo": 30
},
"createdAt": "2021-06-21 14:35:55",
"status": "not_confirmed",
"customFields": []
}
}
EOF;
$mock = static::createApiMockBuilder('loyalty/account/168');
$mock->matchMethod(RequestMethod::GET)
->reply(200)
->withBody($json);
$client = TestClientFactory::createClient($mock->getClient());
$response = $client->loyalty->accountGet(168);
self::assertModelEqualsToResponse($json, $response);
}
public function testCalculate(): void
{
$json = <<<'EOF'
@ -731,4 +780,34 @@ EOF;
self::assertModelEqualsToResponse($json, $response);
}
public function testLoyaltiesGet(): void
{
$json = <<<'EOF'
{
"success": true,
"loyalty": {
"active": true,
"blocked": false,
"id": 4,
"name": "Битрикс новый",
"confirmSmsCharge": false,
"confirmSmsRegistration": false,
"createdAt": "2021-03-17 18:08:02",
"activatedAt": "2021-03-17 18:09:43"
},
"requiredFields": []
}
EOF;
$mock = static::createApiMockBuilder('loyalty/loyalties/4');
$mock->matchMethod(RequestMethod::GET)
->reply(200)
->withBody($json);
$client = TestClientFactory::createClient($mock->getClient());
$response = $client->loyalty->get(4);
self::assertModelEqualsToResponse($json, $response);
}
}

View File

@ -11,6 +11,7 @@ namespace RetailCrm\Tests\ResourceGroup;
use DateInterval;
use DateTime;
use Psr\Http\Message\RequestInterface;
use RetailCrm\Api\Enum\ByIdentifier;
use RetailCrm\Api\Enum\CombineTechnique;
use RetailCrm\Api\Enum\CountryCodeIso3166;
@ -958,6 +959,12 @@ EOF;
$mock = static::createApiMockBuilder('orders/create');
$mock->matchMethod(RequestMethod::POST)
->matchBody(static::encodeForm($request))
->matchCallback(static function (RequestInterface $request) {
$data = [];
parse_str((string) $request->getBody(), $data);
return false !== strpos($data['order'] ?? '', '"customer":{"id":4924}');
})
->reply(200)
->withBody($json);