Completed
Pull Request — master (#179)
by
unknown
08:15
created

PartnerClient::getModelOffers()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 15
Code Lines 10

Duplication

Lines 15
Ratio 100 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
cc 1
eloc 10
nc 1
nop 4
dl 15
loc 15
rs 9.4285
c 0
b 0
f 0
ccs 0
cts 0
cp 0
crap 2
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 10
     */
145
    protected $serviceDomain = 'api.partner.market.yandex.ru';
146 10
147 10
    /**
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 12
     */
154
    public function getServiceUrl($resource = '')
155 12
    {
156 12
        return $this->serviceScheme . '://' . $this->serviceDomain . '/'
157
        . $this->version . '/' . $resource;
158
    }
159
160
    /**
161 1
     * @param string $token access token
162
     */
163 1
    public function __construct($token = '')
164 1
    {
165
        $this->setAccessToken($token);
166
    }
167
168
    /**
169 1
     * @param string $clientId
170
     */
171 1
    public function setClientId($clientId)
172 1
    {
173
        $this->clientId = $clientId;
174
    }
175
176
    /**
177 1
     * @param string $login
178
     */
179 1
    public function setLogin($login)
180 1
    {
181
        $this->login = $login;
182
    }
183
184
    /**
185 1
     * @param string $campaignId
186
     */
187 1
    public function setCampaignId($campaignId)
188
    {
189
        $this->campaignId = $campaignId;
190
    }
191
192
    /**
193 1
     * @return string
194
     */
195 1
    public function getCampaignId()
196
    {
197
        return $this->campaignId;
198
    }
199
200
    /**
201 1
     * @return string
202
     */
203 1
    public function getClientId()
204
    {
205
        return $this->clientId;
206
    }
207
208
    /**
209
     * @return string
210
     */
211
    public function getLogin()
212
    {
213
        return $this->login;
214
    }
215
216
    /**
217
     * Sends a request
218
     *
219 5
     * @param string              $method  HTTP method
220
     * @param string|UriInterface $uri     URI object or string.
221
     * @param array               $options Request options to apply.
222 5
     *
223 5
     * @return Response
224 4
     *
225 4
     * @throws ForbiddenException
226 4
     * @throws UnauthorizedException
227
     * @throws PartnerRequestException
228 4
     */
229 4 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 4
    {
231 4
        try {
232 1
            $response = $this->getClient()->request($method, $uri, $options);
233 1
        } catch (ClientException $ex) {
234 4
            $result = $ex->getResponse();
235
            $code = $result->getStatusCode();
236 4
            $message = $result->getReasonPhrase();
237 1
238
            $body = $result->getBody();
239
            if ($body) {
240 3
                $jsonBody = json_decode($body);
241 2
                if ($jsonBody && isset($jsonBody->error) && isset($jsonBody->error->message)) {
242
                    $message = $jsonBody->error->message;
243
                }
244 1
            }
245 1
246
            if ($code === 403) {
247 1
                throw new ForbiddenException($message);
248
            }
249
250 1
            if ($code === 401) {
251
                throw new UnauthorizedException($message);
252
            }
253
254
            throw new PartnerRequestException(
255
                'Service responded with error code: "' . $code . '" and message: "' . $message . '"',
256
                $code
257
            );
258
        }
259
260 1
        return $response;
261
    }
262 1
263 1
    /**
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
    public function getAccessToken()
271
    {
272
        return 'oauth_token=' . parent::getAccessToken() . ', oauth_client_id=' . $this->getClientId()
273
        . ', oauth_login=' . $this->getLogin();
274
    }
275
276
    /**
277 1
     * Get User Campaigns
278
     *
279 1
     * Returns the user to the list of campaigns Yandex.market.
280
     * The list coincides with the list of campaigns
281 1
     * that are displayed in the partner interface Yandex.Market on page "My shops."
282
     *
283 1
     * @see http://api.yandex.ru/market/partner/doc/dg/reference/get-campaigns.xml
284
     *
285 1
     * @return Campaigns
286 1
     */
287
    public function getCampaigns()
288
    {
289
        $resource = 'campaigns.json';
290
291
        $response = $this->sendRequest('GET', $this->getServiceUrl($resource));
292
293
        $decodedResponseBody = $this->getDecodedBody($response->getBody());
294
295
        $getCampaignsResponse = new GetCampaignsResponse($decodedResponseBody);
296
        return $getCampaignsResponse->getCampaigns();
297
    }
298
299
300
    /**
301
     * Get information about orders by campaign id
302
     *
303 1
     * @param array $params
304
     *
305 1
     * Returns information on the requested orders.
306 1
     * Available filtering by date ordering and order status.
307
     * The maximum range of dates in a single request for a resource - 30 days.
308 1
     *
309
     * @see http://api.yandex.ru/market/partner/doc/dg/reference/get-campaigns-id-orders.xml
310 1
     *
311
     * @return GetOrdersResponse
312 1
     */
313
    public function getOrdersResponse($params = [])
314
    {
315
        $resource = 'campaigns/' . $this->campaignId . '/orders.json';
316
        $resource .= '?' . http_build_query($params);
317
318
        $response = $this->sendRequest('GET', $this->getServiceUrl($resource));
319
320
        $decodedResponseBody = $this->getDecodedBody($response->getBody());
321
322 1
        return new GetOrdersResponse($decodedResponseBody);
323
    }
324 1
325
326
    /**
327
     * Get only orders data without pagination
328
     *
329
     * @param array $params
330
     * @return null|Orders
331
     */
332
    public function getOrders($params = [])
333
    {
334
        return $this->getOrdersResponse($params)->getOrders();
335
    }
336 6
337
338 6
    /**
339
     * Get order info
340 6
     *
341
     * @param int $orderId
342 2
     * @return Order
343
     *
344 2
     * @link http://api.yandex.ru/market/partner/doc/dg/reference/get-campaigns-id-orders-id.xml
345 2
     */
346
    public function getOrder($orderId)
347
    {
348
        $resource = 'campaigns/' . $this->campaignId . '/orders/' . $orderId . '.json';
349
350
        $response = $this->sendRequest('GET', $this->getServiceUrl($resource));
351
352
        $decodedResponseBody = $this->getDecodedBody($response->getBody());
353
354
        $getOrderResponse = new GetOrderResponse($decodedResponseBody);
355
        return $getOrderResponse->getOrder();
356
    }
357
358
359 1
    /**
360
     * Send changed status to Yandex.Market
361 1
     *
362
     * @param int $orderId
363
     * @param string $status
364
     * @param null|string $subStatus
365
     * @return Order
366 1
     *
367 1
     * @link http://api.yandex.ru/market/partner/doc/dg/reference/put-campaigns-id-orders-id-status.xml
368 1
     */
369 1
    public function setOrderStatus($orderId, $status, $subStatus = null)
370 1
    {
371
        $resource = 'campaigns/' . $this->campaignId . '/orders/' . $orderId . '/status.json';
372 1
373 1
        $data = [
374 1
            "order" => [
375
                "status" => $status
376
            ]
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
            $data['order']['substatus'] = $subStatus;
380 1
        }
381
382 1
        $response = $this->sendRequest(
383 1
            'PUT',
384
            $this->getServiceUrl($resource),
385
            [
386
                'json' => $data
387
            ]
388
        );
389
390
        $decodedResponseBody = $this->getDecodedBody($response->getBody());
391
392
        $updateOrderStatusResponse = new UpdateOrderStatusResponse($decodedResponseBody);
393
        return $updateOrderStatusResponse->getOrder();
394
    }
395
396
397
    /**
398
     * Update changed delivery parameters
399 1
     *
400
     * @param int $orderId
401 1
     * @param Delivery $delivery
402
     * @return Order
403 1
     *
404 1
     * Example:
405 1
     * 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 1
     */
409 1
    public function updateDelivery($orderId, Delivery $delivery)
410 1
    {
411 1
        $resource = 'campaigns/' . $this->campaignId . '/orders/' . $orderId . '/delivery.json';
412
413 1
        $response = $this->sendRequest(
414
            'PUT',
415 1
            $this->getServiceUrl($resource),
416 1
            [
417
                'json' => [
418
                    'delivery' => $delivery->toArray()
419
                ]
420
            ]
421
        );
422
423
        $decodedResponseBody = $this->getDecodedBody($response->getBody());
424
425
        $updateOrderDeliveryResponse = new UpdateOrderDeliveryResponse($decodedResponseBody);
426
        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
        return array_filter($params, function($param) {
438
            return !empty($param);
439
        });
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
    public function getModel($modelId, $regionId, $currency = null)
453
    {
454
        $resource = sprintf('models/%s.%s', $modelId, self::DECODE_TYPE_DEFAULT);
455
        $queryParams = $this->filterParams([
456
            'regionId' => $regionId,
457
            'currency' => $currency,
458
        ]);
459
460
        $response = $this->sendRequest('GET', $this->getServiceUrl($resource), ['query' => $queryParams]);
461
        $decodedResponseBody = $this->getDecodedBody($response->getBody());
462
        $marketModelsResponse = new GetMarketModelsResponse($decodedResponseBody);
463
464
        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
    public function findModels($searchQuery, $regionId, $page = null, $pageSize = null, $currency = null)
480
    {
481
        $resource = sprintf('models.%s', self::DECODE_TYPE_DEFAULT);
482
        $queryParams = $this->filterParams([
483
            'query' => $searchQuery,
484
            'regionId' => $regionId,
485
            'page' => $page,
486
            'pageSize' => $pageSize,
487
            'currency' => $currency,
488
        ]);
489
490
        $response = $this->sendRequest('GET', $this->getServiceUrl($resource), ['query' => $queryParams]);
491
        $decodedResponseBody = $this->getDecodedBody($response->getBody());
492
493
        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 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
        $resource = sprintf('models.%s', self::DECODE_TYPE_DEFAULT);
509
        $queryParams = $this->filterParams([
510
            'regionId' => $regionId,
511
            'currency' => $currency,
512
        ]);
513
514
        $response = $this->sendRequest('POST', $this->getServiceUrl($resource), [
515
            'query' => $queryParams,
516
            'json' => [
517
                'models' => $modelIds
518
            ],
519
        ]);
520
        $decodedResponseBody = $this->getDecodedBody($response->getBody());
521
        $marketModelsResponse = new GetMarketModelsResponse($decodedResponseBody);
522
523
        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 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
        $resource = sprintf('models/%s/offers.%s', $modelId, self::DECODE_TYPE_DEFAULT);
540
        $queryParams = $this->filterParams([
541
            'regionId' => $regionId,
542
            'currency' => $currency,
543
            'orderByPrice' => $orderByPrice,
544
        ]);
545
546
        $response = $this->sendRequest('GET', $this->getServiceUrl($resource), ['query' => $queryParams]);
547
        $decodedResponseBody = $this->getDecodedBody($response->getBody());
548
        $marketModelsResponse = new GetMarketModelsResponse($decodedResponseBody);
549
550
        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 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
        $resource = sprintf('models/offers.%s', self::DECODE_TYPE_DEFAULT);
566
        $queryParams = $this->filterParams([
567
            'regionId' => $regionId,
568
            'currency' => $currency,
569
        ]);
570
571
        $response = $this->sendRequest('POST', $this->getServiceUrl($resource), [
572
            'query' => $queryParams,
573
            'json' => [
574
                'models' => $modelIds
575
            ],
576
        ]);
577
        $decodedResponseBody = $this->getDecodedBody($response->getBody());
578
        $marketModelsResponse = new GetMarketModelsResponse($decodedResponseBody);
579
580
        return $marketModelsResponse->getModels();
581
    }
582
}
583