Completed
Push — master ( 3d8e2d...b3f37b )
by Danila
02:44
created

createOrder()   A

Complexity

Conditions 3
Paths 2

Size

Total Lines 19
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 19
rs 9.4285
c 0
b 0
f 0
cc 3
eloc 11
nc 2
nop 7
1
<?php
2
3
/**
4
 *
5
 *
6
 * @category Mygento
7
 * @package Mygento_Yandexdelivery
8
 * @copyright 2017 NKS LLC. (http://www.mygento.ru)
9
 * @license GPLv2
10
 */
11
class Mygento_Yandexdelivery_Model_Carrier
0 ignored issues
show
Coding Style Compatibility introduced by
PSR1 recommends that each class must be in a namespace of at least one level to avoid collisions.

You can fix this by adding a namespace to your class:

namespace YourVendor;

class YourClass { }

When choosing a vendor namespace, try to pick something that is not too generic to avoid conflicts with other libraries.

Loading history...
12
{
13
14
    private $_name = 'yandexdelivery';
15
    private $_url = 'https://delivery.yandex.ru/api/last/';
16
17
    public function processApiKeys($data_string)
18
    {
19
        $json = json_decode(trim($data_string));
20
21
        if (!$json) {
22
            return;
23
        }
24
25
        Mage::helper($this->_name)->addLog('Processed API keys');
26
        Mage::helper($this->_name)->addLog($json);
27
28
        foreach ($json as $key => $element) {
29
            Mage::helper($this->_name)->setConfigData(trim($key), trim($element));
30
        }
31
    }
32
33
    public function processApiIds($data_string)
34
    {
35
36
        $json = json_decode(trim($data_string));
37
        $res = Mage::getSingleton('core/resource');
38
39
        Mage::helper($this->_name)->addLog('Processed API Ids');
40
        Mage::helper($this->_name)->addLog($json);
41
42
        if (empty($json)) {
43
            return;
44
        }
45
46
        Mage::helper($this->_name)->setConfigData('client_id', $json->client->id);
47
48
        $adapter = $res->getConnection('yandexdelivery_write');
49
        //process senders
50 View Code Duplication
        foreach ($json->senders as $value) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across 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...
51
            $insertData = [
52
                'id' => $value->id,
53
                'name' => $value->name
54
            ];
55
            $adapter->insertOnDuplicate($res->getTableName('yandexdelivery/sender'), $insertData, array_keys($insertData));
56
        }
57
        //process warehouses
58 View Code Duplication
        foreach ($json->warehouses as $value) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across 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...
59
            $insertData = [
60
                'id' => $value->id,
61
                'name' => $value->name
62
            ];
63
            $adapter->insertOnDuplicate($res->getTableName('yandexdelivery/warehouse'), $insertData, array_keys($insertData));
64
        }
65
        //process requisites
66 View Code Duplication
        foreach ($json->requisites as $value) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across 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...
67
            $insertData = [
68
                'id' => $value->id
69
            ];
70
            $adapter->insertOnDuplicate($res->getTableName('yandexdelivery/requisite'), $insertData, array_keys($insertData));
71
        }
72
73
        $this->getSenderInfo();
74
        $this->getRequisiteInfo();
75
        $this->getWarehouseInfo();
76
    }
77
78
    /**
79
     * автоподсказки адресов
80
     * @param string $search
81
     * @param string $type
82
     * @param string $city
83
     * @return json
84
     */
85
    public function getAutocomplete($search, $type, $city = false)
86
    {
87
        $data = [
88
            'term' => $search,
89
            'type' => $type,
90
        ];
91
92
        if ($city) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $city of type false|string is loosely compared to true; this is ambiguous if the string can be empty. You might want to explicitly use !== false 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...
93
            $data['locality_name'] = $city;
94
        }
95
96
        $result = $this->sendRequest('autocomplete', $data, true);
97
98
        if ($result->status == 'ok') {
99
            return $result->data->suggestions;
100
        }
101
        return json_encode();
0 ignored issues
show
Bug Best Practice introduced by
The return type of return json_encode(); (string) is incompatible with the return type documented by Mygento_Yandexdelivery_M...arrier::getAutocomplete of type json.

If you return a value from a function or method, it should be a sub-type of the type that is given by the parent type f.e. an interface, or abstract method. This is more formally defined by the Lizkov substitution principle, and guarantees that classes that depend on the parent type can use any instance of a child type interchangably. This principle also belongs to the SOLID principles for object oriented design.

Let’s take a look at an example:

class Author {
    private $name;

    public function __construct($name) {
        $this->name = $name;
    }

    public function getName() {
        return $this->name;
    }
}

abstract class Post {
    public function getAuthor() {
        return 'Johannes';
    }
}

class BlogPost extends Post {
    public function getAuthor() {
        return new Author('Johannes');
    }
}

class ForumPost extends Post { /* ... */ }

function my_function(Post $post) {
    echo strtoupper($post->getAuthor());
}

Our function my_function expects a Post object, and outputs the author of the post. The base class Post returns a simple string and outputting a simple string will work just fine. However, the child class BlogPost which is a sub-type of Post instead decided to return an object, and is therefore violating the SOLID principles. If a BlogPost were passed to my_function, PHP would not complain, but ultimately fail when executing the strtoupper call in its body.

Loading history...
102
    }
103
104
    private function getSenderInfo()
105
    {
106
        $result = $this->sendRequest('getSenderInfo', [], true);
107
108
        if ($result->status == 'ok') {
109
            $sender = Mage::getModel('yandexdelivery/sender')->load($result->data->id);
110
            $sender->setName($result->data->field_name);
111
            $sender->save();
112
        }
113
    }
114
115
    private function getWarehouseInfo()
116
    {
117
        $data = [
118
            'warehouse_id' => Mage::helper($this->_name)->getConfigData('warehouse'),
119
        ];
120
        $result = $this->sendRequest('getWarehouseInfo', $data, true);
121
122
        if ($result->status == 'ok') {
123
            $sender = Mage::getModel('yandexdelivery/warehouse')->load($result->data->id);
124
125
            $sender->setName($result->data->field_name);
126
            $sender->setAddress($result->data->address);
127
            $sender->save();
128
        }
129
    }
130
131
    private function getRequisiteInfo()
132
    {
133
        $data = [
134
            'requisite_id' => Mage::getStoreConfig('carriers/' . $this->_name . '/requisite')
135
        ];
136
137
        $result = $this->sendRequest('getRequisiteInfo', $data, true);
138
139
        if ($result->status != "ok") {
140
            return;
141
        }
142
        foreach ($result->data->requisites as $requsite) {
143
            $requsiteId = $requsite->id;
144
            Mage::helper($this->_name)->addLog('FFF ' . $requsiteId);
145
            if (!$requsiteId) {
146
                continue;
147
            }
148
            $requisite = Mage::getModel('yandexdelivery/requisite')->load($requsiteId);
149
            $requisite->setLegalForm($requsite->legal_form);
150
            $requisite->setLegalName($requsite->legal_name);
151
            $address = implode(', ', (array) $requsite->address_legal);
152
            $requisite->setAddress($address);
153
            $requisite->save();
154
        }
155
    }
156
157
    public function createOrder($orderId, $warehouseId, $senderId, $requisiteId, $date, $street, $house)
158
    {
159
        //создание заявки на отправку заказа в ЯД
160
        $order = Mage::getModel('sales/order')->load($orderId);
161
162
        if (!$order || !$order->getId()) {
163
            return false;
164
        }
165
166
        $data = $this->getOrderData($order);
167
168
        $data ['order_requisite'] = $requisiteId;
169
        $data ['order_warehouse'] = $warehouseId;
170
        $data['order_shipment_date'] = date('Y-m-d', strtotime($date));
171
        $data['deliverypoint']['street'] = $street;
172
        $data['deliverypoint']['house'] = $house;
173
174
        return $this->sendRequest('createOrder', $data, true, $senderId);
175
    }
176
177
    public function getTypes($addHypes = false)
178
    {
179
        $types = ['todoor', 'post', 'pickup'];
180
        $enabled = [];
181
        foreach ($types as $type) {
182
            if (Mage::getStoreConfig('carriers/yandexdelivery_' . $type . '/active')) {
183
                if ($addHypes) {
184
                    $enabled[] = "'" . $type . "'";
185
                } else {
186
                    $enabled[] = $type;
187
                }
188
            }
189
        }
190
        return $enabled;
191
    }
192
193
    public function confirmOrders($id, $type)
194
    {
195
        $data = [
196
            'order_ids' => $id,
197
            'type' => $type,
198
            'shipment_date' => date('Y-m-d')
199
        ];
200
201
        $result = $this->sendRequest('confirmSenderOrders', $data, true);
202
203
        if (!isset($result->data->result) || count($result->data->result->error) != 0 || count($result->data->errors)) {
204
            return $result;
205
        }
206
207
        //set parcel_id to DB
208
        foreach ($result->data->result->success as $success) {
209
            $yd_id_collection = Mage::getModel('yandexdelivery/shipment')->getCollection();
210
            $yd_id_collection->addFieldToFilter('yd_id', ['in' => $success->orders]);
211
            foreach ($yd_id_collection as $ydShipment) {
212
                $ydShipment->setParcelId($success->parcel_id);
213
                $ydShipment->save();
214
            }
215
        }
216
217
        return $result;
218
    }
219
220
    /**
221
     * получаем id заказа в ЯД по ордеру
222
     * @param int $orderId
223
     * @return boolean
224
     */
225
    public function getYdId($orderId)
226
    {
227
        if ($this->getShipment($orderId)) {
228
            return $this->getShipment($orderId)->getYdId();
0 ignored issues
show
Bug introduced by
The method getYdId cannot be called on $this->getShipment($orderId) (of type boolean).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
229
        }
230
        return false;
231
    }
232
233
    /**
234
     * получаем объект шипмента
235
     * @param int $orderId
236
     * @return boolean
237
     */
238 View Code Duplication
    public function getShipment($orderId)
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...
239
    {
240
        $yd_id_collection = Mage::getModel('yandexdelivery/shipment')->getCollection();
241
        $yd_id_collection->addFieldToFilter('order_id', $orderId);
242
        $yd_id_collection->load();
243
        if ($yd_id_collection->getSize() > 0) {
244
            return $yd_id_collection->getFirstItem();
245
        }
246
        return false;
247
    }
248
249
    /**
250
     * получаем id заказа в ЯД по id shipment
251
     * @param array $ids
252
     * @return boolean
253
     */
254 View Code Duplication
    public function getYdIdsByIds($ids)
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...
255
    {
256
        $yd_id_collection = Mage::getModel('yandexdelivery/shipment')->getCollection();
257
        $yd_id_collection->addFieldToFilter('id', ['in' => $ids]);
258
        $yd_id_collection->load();
259
        if ($yd_id_collection->getSize() > 0) {
260
            return $yd_id_collection->getColumnValues('yd_id');
261
        }
262
        return false;
263
    }
264
265
    public function deleteOrder($order_id)
266
    {
267
        $result = $this->sendRequest('deleteOrder', ['order_id' => $order_id], true);
268
269
        //удаляем запись в БД в случае успеха
270
        if ($result->status == "ok") {
271
            $yd_id_collection = Mage::getModel('yandexdelivery/shipment')->getCollection();
272
            $yd_id_collection->addFieldToFilter('yd_id', $order_id);
273
            $yd_id_collection->load();
274
            if ($yd_id_collection->getSize() > 0) {
275
                $item = $yd_id_collection->getFirstItem();
276
                $item->delete();
277
            }
278
        }
279
        return $result;
280
    }
281
282
    public function senderOrderStatuses($order_id)
283
    {
284
        return $this->sendRequest('getSenderOrderStatuses', ['order_id' => $order_id], true);
285
    }
286
287
    public function getSenderOrderLabel($order_id)
288
    {
289
        return $this->sendRequest('getSenderOrderLabel', ['order_id' => $order_id], true);
290
    }
291
292
    public function getSenderParcelDocs($parcel_id)
293
    {
294
        return $this->sendRequest('getSenderParcelDocs', ['parcel_id' => $parcel_id], true);
295
    }
296
297
    public function searchDeliveryList($data)
298
    {
299
        return $this->sendRequest('searchDeliveryList', $data, true);
300
    }
301
302
    public function statusOrder($order_id)
303
    {
304
        return $this->sendRequest('getOrderInfo', ['order_id' => $order_id], true);
305
    }
306
307
    protected function sendRequest($method, $data, $sign, $sender = null)
308
    {
309
        if ($sender) {
310
            $data['sender_id'] = $sender;
311
        } else {
312
            $data['sender_id'] = $this->getSender();
313
        }
314
        return json_decode(Mage::helper($this->_name)->requestApiPost($this->_url . $method, $data, $sign, $method));
315
    }
316
317
    protected function getOrderData($order)
318
    {
319
320
        if (Mage::getStoreConfig('carriers/' . $this->_name . '/onlyone')) {
321
            $weight = round(Mage::getStoreConfig('carriers/' . $this->_name . '/oneweight') * 1000 / Mage::getStoreConfig('carriers/' . $this->_name . '/weightunit'), 3);
322
            $dimensions = Mage::helper($this->_name)->getStandardSizes();
323
        } else {
324
            $processed_dimensions = Mage::helper($this->_name)->getSizes($order->getAllVisibleItems(), false);
325
            $weight = $processed_dimensions['weight'];
326
            $dimensions = Mage::helper($this->_name)->dimenAlgo($processed_dimensions['dimensions']);
327
        }
328
329
330
        $shipping_code = $order->getShippingMethod();
331
        $detect_code = str_replace('yandexdelivery_', '', $shipping_code);
332
333
        $info_array = explode('_', $detect_code);
334
335
        $data = [
336
            'order_num' => $order->getIncrementId(),
337
            'order_length' => $dimensions['A'],
338
            'order_width' => $dimensions['B'],
339
            'order_height' => $dimensions['C'],
340
            'order_weight' => $weight,
341
            'order_assessed_value' => round($order->getGrandTotal() - $order->getShippingAmount(), 0),
342
            'order_delivery_cost' => round($order->getShippingAmount(), 0),
343
            'order_shipment_type' => $info_array[0],
344
            'is_manual_delivery_cost' => 1,
345
            'recipient' => [
346
                'phone' => Mage::helper('yandexdelivery')->normalizePhone($order->getShippingAddress()->getTelephone()),
347
                'email' => $order->getShippingAddress()->getEmail(),
348
                'first_name' => $order->getShippingAddress()->getFirstname(),
349
                'last_name' => $order->getShippingAddress()->getLastname(),
350
            ],
351
            'delivery' => [
352
                'to_yd_warehouse' => Mage::getStoreConfig('carriers/' . $this->_name . '/yd_warehouse'),
353
                'delivery' => $info_array[3],
354
                'direction' => $info_array[2],
355
                'tariff' => $info_array[1],
356
            ],
357
            'deliverypoint' => [
358
                'city' => $order->getShippingAddress()->getCity(),
359
                'index' => $order->getShippingAddress()->getPostcode(),
360
            ],
361
        ];
362
363
        $invoicesSum = 0;
364
365
        if ($order->hasInvoices()) {
366
            //check all invoices sum
367
368
            $invoicesCollection = $order->getInvoiceCollection();
369
370
            foreach ($invoicesCollection as $invoice) {
371
                $invoicesSum += $invoice->getGrandTotal();
372
            }
373
374
            //check all credit memo sum ??
375
        }
376
        $data['order_amount_prepaid'] = $invoicesSum;
377
378
        if (isset($info_array[4])) {
379
            //если ПВЗ
380
            $data['delivery']['pickuppoint'] = $info_array[4];
381
        }
382
383
        $order_items = [];
384
385
        foreach ($order->getAllVisibleItems() as $item) {
386
            $order_items[] = [
387
                'orderitem_name' => $item->getName(),
388
                'orderitem_quantity' => round($item->getQtyOrdered(), 2),
389
                'orderitem_cost' => $item->getRowTotalInclTax() / ceil($item->getQtyOrdered()),
390
                'orderitem_article' => $item->getSku(),
391
            ];
392
        }
393
394
        $data['order_items'] = $order_items;
395
396
        return $data;
397
    }
398
399
    protected function getSender()
400
    {
401
        return Mage::helper($this->_name)->getConfigData('sender');
402
    }
403
404
    //currently unused
405
406
    public function getPaymentMethods()
407
    {
408
        return $this->sendRequest('getPaymentMethods', [], true);
409
    }
410
}
411