Completed
Pull Request — master (#179)
by
unknown
05:03
created

PartnerClient::getModel()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 14
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 10
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
eloc 9
nc 1
nop 3
dl 0
loc 14
ccs 10
cts 10
cp 1
crap 1
rs 9.4285
c 0
b 0
f 0
1
<?php
2
/**
3
 * Yandex PHP Library
4
 *
5
 * @copyright NIX Solutions Ltd.
6
 * @link https://github.com/nixsolutions/yandex-php-library
7
 */
8
9
/**
10
 * @namespace
11
 */
12
namespace Yandex\Market\Partner;
13
14
use Psr\Http\Message\UriInterface;
15
use Yandex\Common\AbstractServiceClient;
16
use GuzzleHttp\Psr7\Response;
17
use GuzzleHttp\Exception\ClientException;
18
use Yandex\Common\Exception\ForbiddenException;
19
use Yandex\Common\Exception\UnauthorizedException;
20
use Yandex\Market\Partner\Exception\PartnerRequestException;
21
use Yandex\Market\Partner\Models\Delivery;
22
use Yandex\Market\Partner\Models\GetCampaignsResponse;
23
use Yandex\Market\Partner\Models\GetMarketModelsResponse;
24
use Yandex\Market\Partner\Models\GetOrderResponse;
25
use Yandex\Market\Partner\Models\GetOrdersResponse;
26
use Yandex\Market\Partner\Models\MarketModel;
27
use Yandex\Market\Partner\Models\MarketModels;
28
use Yandex\Market\Partner\Models\Order;
29
use Yandex\Market\Partner\Models\Orders;
30
use Yandex\Market\Partner\Models\UpdateOrderDeliveryResponse;
31
use Yandex\Market\Partner\Models\UpdateOrderStatusResponse;
32
33
/**
34
 * Class PartnerClient
35
 *
36
 * @category Yandex
37
 * @package Market
38
 *
39
 * @author   Alexander Khaylo <[email protected]>
40
 * @created  04.11.13 12:48
41
 */
42
class PartnerClient extends AbstractServiceClient
43
{
44
45
    /**
46
     * Order is being processed
47
     */
48
    const ORDER_STATUS_PROCESSING = 'PROCESSING';
49
50
    /**
51
     * Order submitted to the delivery
52
     */
53
    const ORDER_STATUS_DELIVERY = 'DELIVERY';
54
55
    /**
56
     *  Order delivered to the point of self-delivery
57
     */
58
    const ORDER_STATUS_PICKUP = 'PICKUP';
59
60
    /**
61
     * The order is received by the buyer
62
     */
63
    const ORDER_STATUS_DELIVERED = 'DELIVERED';
64
65
    /**
66
     * Order canceled.
67
     */
68
    const ORDER_STATUS_CANCELLED = 'CANCELLED';
69
70
    //Sub-statuses for status CANCELLED
71
    // - the buyer is not finalized the reserved order on time
72
    const ORDER_SUBSTATUS_RESERVATION_EXPIRED = 'RESERVATION_EXPIRED';
73
    // - the buyer did not pay for the order ( for the type of payment PREPAID)
74
    const ORDER_SUBSTATUS_USER_NOT_PAID = 'USER_NOT_PAID';
75
    // - failed to communicate with the buyer
76
    const ORDER_SUBSTATUS_USER_UNREACHABLE = 'USER_UNREACHABLE';
77
    // - buyer canceled the order for cause
78
    const ORDER_SUBSTATUS_USER_CHANGED_MIND = 'USER_CHANGED_MIND';
79
    // - the buyer is not satisfied with the terms of delivery
80
    const ORDER_SUBSTATUS_USER_REFUSED_DELIVERY = 'USER_REFUSED_DELIVERY';
81
    // - the buyer did not fit the goods
82
    const ORDER_SUBSTATUS_USER_REFUSED_PRODUCT = 'USER_REFUSED_PRODUCT';
83
    // - shop can not fulfill the order
84
    const ORDER_SUBSTATUS_SHOP_FAILED = 'SHOP_FAILED';
85
    // - the buyer is not satisfied with the quality of the goods
86
    const ORDER_SUBSTATUS_USER_REFUSED_QUALITY = 'USER_REFUSED_QUALITY';
87
    // - buyer changes the composition of the order
88
    const ORDER_SUBSTATUS_REPLACING_ORDER = 'REPLACING_ORDER';
89
    //- store does not process orders on time
90
    const ORDER_SUBSTATUS_PROCESSING_EXPIRED = 'PROCESSING_EXPIRED';
91
92
    //Способ оплаты заказа
93
    //предоплата через Яндекс;
94
    const PAYMENT_METHOD_YANDEX = 'YANDEX';
95
    //предоплата напрямую магазину,
96
    //не принимающему предоплату через Яндекс.
97
    const PAYMENT_METHOD_SHOP_PREPAID = 'SHOP_PREPAID';
98
    // наличный расчет при получении заказа;
99
    const PAYMENT_METHOD_CASH_ON_DELIVERY = 'CASH_ON_DELIVERY';
100
    // оплата банковской картой при получении заказа.
101
    const PAYMENT_METHOD_CARD_ON_DELIVERY = 'CARD_ON_DELIVERY';
102
103
    //Типы доставки
104
    //курьерская доставка
105
    const DELIVERY_TYPE_DELIVERY = 'DELIVERY';
106
    //самовывоз
107
    const DELIVERY_TYPE_PICKUP = 'PICKUP';
108
    //почта
109
    const DELIVERY_TYPE_POST = 'POST';
110
111
    const ORDER_DECLINE_REASON_OUT_OF_DATE= 'OUT_OF_DATE';
112
113
    /**
114
     * Requested version of API
115
     * @var string
116
     */
117
    private $version = 'v2';
118
119
    /**
120
     * Application id
121
     *
122
     * @var string
123
     */
124
    protected $clientId;
125
126
    /**
127
     * User login
128
     *
129
     * @var string
130
     */
131
    protected $login;
132
133
    /**
134
     * Campaign Id
135
     *
136
     * @var string
137
     */
138
    protected $campaignId;
139
140
    /**
141
     * API domain
142
     *
143
     * @var string
144
     */
145
    protected $serviceDomain = 'api.partner.market.yandex.ru';
146
147
    /**
148
     * Get url to service resource with parameters
149
     *
150
     * @param string $resource
151
     * @see http://api.yandex.ru/market/partner/doc/dg/concepts/method-call.xml
152
     * @return string
153
     */
154 15
    public function getServiceUrl($resource = '')
155
    {
156 15
        return $this->serviceScheme . '://' . $this->serviceDomain . '/'
157 15
        . $this->version . '/' . $resource;
158
    }
159
160
    /**
161
     * @param string $token access token
162
     */
163 17
    public function __construct($token = '')
164
    {
165 17
        $this->setAccessToken($token);
166 17
    }
167
168
    /**
169
     * @param string $clientId
170
     */
171 1
    public function setClientId($clientId)
172
    {
173 1
        $this->clientId = $clientId;
174 1
    }
175
176
    /**
177
     * @param string $login
178
     */
179 1
    public function setLogin($login)
180
    {
181 1
        $this->login = $login;
182 1
    }
183
184
    /**
185
     * @param string $campaignId
186
     */
187 1
    public function setCampaignId($campaignId)
188
    {
189 1
        $this->campaignId = $campaignId;
190 1
    }
191
192
    /**
193
     * @return string
194
     */
195 1
    public function getCampaignId()
196
    {
197 1
        return $this->campaignId;
198
    }
199
200
    /**
201
     * @return string
202
     */
203 1
    public function getClientId()
204
    {
205 1
        return $this->clientId;
206
    }
207
208
    /**
209
     * @return string
210
     */
211 1
    public function getLogin()
212
    {
213 1
        return $this->login;
214
    }
215
216
    /**
217
     * Sends a request
218
     *
219
     * @param string              $method  HTTP method
220
     * @param string|UriInterface $uri     URI object or string.
221
     * @param array               $options Request options to apply.
222
     *
223
     * @return Response
224
     *
225
     * @throws ForbiddenException
226
     * @throws UnauthorizedException
227
     * @throws PartnerRequestException
228
     */
229 5 View Code Duplication
    protected function sendRequest($method, $uri, array $options = [])
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
230
    {
231
        try {
232 5
            $response = $this->getClient()->request($method, $uri, $options);
233 5
        } catch (ClientException $ex) {
234 4
            $result = $ex->getResponse();
235 4
            $code = $result->getStatusCode();
236 4
            $message = $result->getReasonPhrase();
237
238 4
            $body = $result->getBody();
239 4
            if ($body) {
240 4
                $jsonBody = json_decode($body);
241 4
                if ($jsonBody && isset($jsonBody->error) && isset($jsonBody->error->message)) {
242 1
                    $message = $jsonBody->error->message;
243 1
                }
244 4
            }
245
246 4
            if ($code === 403) {
247 1
                throw new ForbiddenException($message);
248
            }
249
250 3
            if ($code === 401) {
251 2
                throw new UnauthorizedException($message);
252
            }
253
254 1
            throw new PartnerRequestException(
255 1
                'Service responded with error code: "' . $code . '" and message: "' . $message . '"',
256
                $code
257 1
            );
258
        }
259
260 1
        return $response;
261
    }
262
263
    /**
264
     * Get OAuth data for header request
265
     *
266
     * @see http://api.yandex.ru/market/partner/doc/dg/concepts/authorization.xml
267
     *
268
     * @return string
269
     */
270 1
    public function getAccessToken()
271
    {
272 1
        return 'oauth_token=' . parent::getAccessToken() . ', oauth_client_id=' . $this->getClientId()
273 1
        . ', oauth_login=' . $this->getLogin();
274
    }
275
276
    /**
277
     * Get User Campaigns
278
     *
279
     * Returns the user to the list of campaigns Yandex.market.
280
     * The list coincides with the list of campaigns
281
     * that are displayed in the partner interface Yandex.Market on page "My shops."
282
     *
283
     * @see http://api.yandex.ru/market/partner/doc/dg/reference/get-campaigns.xml
284
     *
285
     * @return Campaigns
286
     */
287 1
    public function getCampaigns()
288
    {
289 1
        $resource = 'campaigns.json';
290
291 1
        $response = $this->sendRequest('GET', $this->getServiceUrl($resource));
292
293 1
        $decodedResponseBody = $this->getDecodedBody($response->getBody());
294
295 1
        $getCampaignsResponse = new GetCampaignsResponse($decodedResponseBody);
296 1
        return $getCampaignsResponse->getCampaigns();
297
    }
298
299
300
    /**
301
     * Get information about orders by campaign id
302
     *
303
     * @param array $params
304
     *
305
     * Returns information on the requested orders.
306
     * Available filtering by date ordering and order status.
307
     * The maximum range of dates in a single request for a resource - 30 days.
308
     *
309
     * @see http://api.yandex.ru/market/partner/doc/dg/reference/get-campaigns-id-orders.xml
310
     *
311
     * @return GetOrdersResponse
312
     */
313 1
    public function getOrdersResponse($params = [])
314
    {
315 1
        $resource = 'campaigns/' . $this->campaignId . '/orders.json';
316 1
        $resource .= '?' . http_build_query($params);
317
318 1
        $response = $this->sendRequest('GET', $this->getServiceUrl($resource));
319
320 1
        $decodedResponseBody = $this->getDecodedBody($response->getBody());
321
322 1
        return new GetOrdersResponse($decodedResponseBody);
323
    }
324
325
326
    /**
327
     * Get only orders data without pagination
328
     *
329
     * @param array $params
330
     * @return null|Orders
331
     */
332 1
    public function getOrders($params = [])
333
    {
334 1
        return $this->getOrdersResponse($params)->getOrders();
335
    }
336
337
338
    /**
339
     * Get order info
340
     *
341
     * @param int $orderId
342
     * @return Order
343
     *
344
     * @link http://api.yandex.ru/market/partner/doc/dg/reference/get-campaigns-id-orders-id.xml
345
     */
346 6
    public function getOrder($orderId)
347
    {
348 6
        $resource = 'campaigns/' . $this->campaignId . '/orders/' . $orderId . '.json';
349
350 6
        $response = $this->sendRequest('GET', $this->getServiceUrl($resource));
351
352 2
        $decodedResponseBody = $this->getDecodedBody($response->getBody());
353
354 2
        $getOrderResponse = new GetOrderResponse($decodedResponseBody);
355 2
        return $getOrderResponse->getOrder();
356
    }
357
358
359
    /**
360
     * Send changed status to Yandex.Market
361
     *
362
     * @param int $orderId
363
     * @param string $status
364
     * @param null|string $subStatus
365
     * @return Order
366
     *
367
     * @link http://api.yandex.ru/market/partner/doc/dg/reference/put-campaigns-id-orders-id-status.xml
368
     */
369 1
    public function setOrderStatus($orderId, $status, $subStatus = null)
370
    {
371 1
        $resource = 'campaigns/' . $this->campaignId . '/orders/' . $orderId . '/status.json';
372
373
        $data = [
374
            "order" => [
375
                "status" => $status
376 1
            ]
377 1
        ];
378 1
        if ($subStatus) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $subStatus of type null|string is loosely compared to true; this is ambiguous if the string can be empty. You might want to explicitly use !== null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
379 1
            $data['order']['substatus'] = $subStatus;
380 1
        }
381
382 1
        $response = $this->sendRequest(
383 1
            'PUT',
384 1
            $this->getServiceUrl($resource),
385
            [
386
                'json' => $data
387 1
            ]
388 1
        );
389
390 1
        $decodedResponseBody = $this->getDecodedBody($response->getBody());
391
392 1
        $updateOrderStatusResponse = new UpdateOrderStatusResponse($decodedResponseBody);
393 1
        return $updateOrderStatusResponse->getOrder();
394
    }
395
396
397
    /**
398
     * Update changed delivery parameters
399
     *
400
     * @param int $orderId
401
     * @param Delivery $delivery
402
     * @return Order
403
     *
404
     * Example:
405
     * PUT /v2/campaigns/10003/order/12345/delivery.json HTTP/1.1
406
     *
407
     * @link http://api.yandex.ru/market/partner/doc/dg/reference/put-campaigns-id-orders-id-delivery.xml
408
     */
409 1
    public function updateDelivery($orderId, Delivery $delivery)
410
    {
411 1
        $resource = 'campaigns/' . $this->campaignId . '/orders/' . $orderId . '/delivery.json';
412
413 1
        $response = $this->sendRequest(
414 1
            'PUT',
415 1
            $this->getServiceUrl($resource),
416
            [
417
                'json' => [
418 1
                    'delivery' => $delivery->toArray()
419 1
                ]
420 1
            ]
421 1
        );
422
423 1
        $decodedResponseBody = $this->getDecodedBody($response->getBody());
424
425 1
        $updateOrderDeliveryResponse = new UpdateOrderDeliveryResponse($decodedResponseBody);
426 1
        return $updateOrderDeliveryResponse->getOrder();
427
    }
428
429
    /**
430
     * Filter query params
431
     *
432
     * @param array $params
433
     * @return array
434
     */
435
    private function filterParams(array $params)
436
    {
437 5
        return array_filter($params, function ($param) {
438 5
            return !empty($param);
439 5
        });
440
    }
441
442
    /**
443
     * Get product model by ID
444
     *
445
     * @param int $modelId
446
     * @param int $regionId
447
     * @param string $currency
448
     * @return MarketModel
449
     *
450
     * @link https://tech.yandex.ru/market/partner/doc/dg/reference/get-models-id-docpage/
451
     */
452 1
    public function getModel($modelId, $regionId, $currency = null)
453
    {
454 1
        $resource = sprintf('models/%s.%s', $modelId, self::DECODE_TYPE_DEFAULT);
455 1
        $queryParams = $this->filterParams([
456 1
            'regionId' => $regionId,
457 1
            'currency' => $currency,
458 1
        ]);
459
460 1
        $response = $this->sendRequest('GET', $this->getServiceUrl($resource), ['query' => $queryParams]);
461 1
        $decodedResponseBody = $this->getDecodedBody($response->getBody());
462 1
        $marketModelsResponse = new GetMarketModelsResponse($decodedResponseBody);
463
464 1
        return $marketModelsResponse->getModels()->current();
465
    }
466
467
    /**
468
     * Find models by query
469
     *
470
     * @param string $searchQuery
471
     * @param int $regionId
472
     * @param int $page
473
     * @param int $pageSize
474
     * @param string $currency
475
     * @return GetMarketModelsResponse
476
     *
477
     * @link https://tech.yandex.ru/market/partner/doc/dg/reference/get-models-docpage/
478
     */
479 1
    public function findModels($searchQuery, $regionId, $page = null, $pageSize = null, $currency = null)
480
    {
481 1
        $resource = sprintf('models.%s', self::DECODE_TYPE_DEFAULT);
482 1
        $queryParams = $this->filterParams([
483 1
            'query' => $searchQuery,
484 1
            'regionId' => $regionId,
485 1
            'page' => $page,
486 1
            'pageSize' => $pageSize,
487 1
            'currency' => $currency,
488 1
        ]);
489
490 1
        $response = $this->sendRequest('GET', $this->getServiceUrl($resource), ['query' => $queryParams]);
491 1
        $decodedResponseBody = $this->getDecodedBody($response->getBody());
492
493 1
        return new GetMarketModelsResponse($decodedResponseBody);
494
    }
495
496
    /**
497
     * Get multiple models by ids
498
     *
499
     * @param array $modelIds
500
     * @param int $regionId
501
     * @param string $currency
502
     * @return MarketModels
503
     *
504
     * @link https://tech.yandex.ru/market/partner/doc/dg/reference/post-models-docpage/
505
     */
506 1 View Code Duplication
    public function getModels(array $modelIds, $regionId, $currency = null)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
507
    {
508 1
        $resource = sprintf('models.%s', self::DECODE_TYPE_DEFAULT);
509 1
        $queryParams = $this->filterParams([
510 1
            'regionId' => $regionId,
511 1
            'currency' => $currency,
512 1
        ]);
513
514 1
        $response = $this->sendRequest('POST', $this->getServiceUrl($resource), [
515 1
            'query' => $queryParams,
516
            'json' => [
517
                'models' => $modelIds
518 1
            ],
519 1
        ]);
520 1
        $decodedResponseBody = $this->getDecodedBody($response->getBody());
521 1
        $marketModelsResponse = new GetMarketModelsResponse($decodedResponseBody);
522
523 1
        return $marketModelsResponse->getModels();
524
    }
525
526
    /**
527
     * Get model offers
528
     *
529
     * @param int $modelId
530
     * @param int $regionId
531
     * @param string $currency
532
     * @param string $orderByPrice
533
     * @return MarketModel
534
     *
535
     * @link https://tech.yandex.ru/market/partner/doc/dg/reference/get-models-id-offers-docpage/
536
     */
537 1 View Code Duplication
    public function getModelOffers($modelId, $regionId, $currency = null, $orderByPrice = null)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
538
    {
539 1
        $resource = sprintf('models/%s/offers.%s', $modelId, self::DECODE_TYPE_DEFAULT);
540 1
        $queryParams = $this->filterParams([
541 1
            'regionId' => $regionId,
542 1
            'currency' => $currency,
543 1
            'orderByPrice' => $orderByPrice,
544 1
        ]);
545
546 1
        $response = $this->sendRequest('GET', $this->getServiceUrl($resource), ['query' => $queryParams]);
547 1
        $decodedResponseBody = $this->getDecodedBody($response->getBody());
548 1
        $marketModelsResponse = new GetMarketModelsResponse($decodedResponseBody);
549
550 1
        return $marketModelsResponse->getModels()->current();
551
    }
552
553
    /**
554
     * Get multiple models offers
555
     *
556
     * @param array $modelIds
557
     * @param int $regionId
558
     * @param string $currency
559
     * @return MarketModels
560
     *
561
     * @link https://tech.yandex.ru/market/partner/doc/dg/reference/post-models-offers-docpage/
562
     */
563 1 View Code Duplication
    public function getModelsOffers(array $modelIds, $regionId, $currency = null)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
564
    {
565 1
        $resource = sprintf('models/offers.%s', self::DECODE_TYPE_DEFAULT);
566 1
        $queryParams = $this->filterParams([
567 1
            'regionId' => $regionId,
568 1
            'currency' => $currency,
569 1
        ]);
570
571 1
        $response = $this->sendRequest('POST', $this->getServiceUrl($resource), [
572 1
            'query' => $queryParams,
573
            'json' => [
574
                'models' => $modelIds
575 1
            ],
576 1
        ]);
577 1
        $decodedResponseBody = $this->getDecodedBody($response->getBody());
578 1
        $marketModelsResponse = new GetMarketModelsResponse($decodedResponseBody);
579
580 1
        return $marketModelsResponse->getModels();
581
    }
582
}
583