ApiController::parseProductOffer()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 8
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
cc 1
eloc 6
c 2
b 0
f 0
nc 1
nop 2
dl 0
loc 8
rs 10
1
<?php
2
3
namespace carono\exchange1c\controllers;
4
5
use carono\exchange1c\behaviors\BomBehavior;
6
use carono\exchange1c\ExchangeEvent;
7
use carono\exchange1c\ExchangeModule;
8
use carono\exchange1c\helpers\ByteHelper;
9
use carono\exchange1c\helpers\NodeHelper;
10
use carono\exchange1c\helpers\SerializeHelper;
11
use carono\exchange1c\interfaces\DocumentInterface;
12
use carono\exchange1c\interfaces\OfferInterface;
13
use carono\exchange1c\interfaces\ProductInterface;
14
use Yii;
15
use yii\db\ActiveRecord;
16
use yii\helpers\FileHelper;
17
use yii\web\Response;
18
use Zenwalker\CommerceML\CommerceML;
19
use Zenwalker\CommerceML\Model\Classifier;
20
use Zenwalker\CommerceML\Model\Group;
21
use Zenwalker\CommerceML\Model\Image;
22
use Zenwalker\CommerceML\Model\Offer;
23
use Zenwalker\CommerceML\Model\Product;
24
use Zenwalker\CommerceML\Model\PropertyCollection;
0 ignored issues
show
Bug introduced by
The type Zenwalker\CommerceML\Model\PropertyCollection was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
25
use Zenwalker\CommerceML\Model\Simple;
26
use Zenwalker\CommerceML\Model\RequisiteCollection;
0 ignored issues
show
Bug introduced by
The type Zenwalker\CommerceML\Model\RequisiteCollection was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
27
28
/**
29
 * Default controller for the `api` module
30
 *
31
 * @property ExchangeModule $module
32
 */
33
class ApiController extends Controller
34
{
35
    public $enableCsrfValidation = false;
36
    public $commerceMLVersion = '2.10';
37
38
    const EVENT_BEFORE_UPDATE_PRODUCT = 'beforeUpdateProduct';
39
    const EVENT_AFTER_UPDATE_PRODUCT = 'afterUpdateProduct';
40
    const EVENT_BEFORE_UPDATE_OFFER = 'beforeUpdateOffer';
41
    const EVENT_AFTER_UPDATE_OFFER = 'afterUpdateOffer';
42
    const EVENT_BEFORE_PRODUCT_SYNC = 'beforeProductSync';
43
    const EVENT_AFTER_PRODUCT_SYNC = 'afterProductSync';
44
    const EVENT_BEFORE_OFFER_SYNC = 'beforeOfferSync';
45
    const EVENT_AFTER_OFFER_SYNC = 'afterOfferSync';
46
    const EVENT_AFTER_FINISH_UPLOAD_FILE = 'afterFinishUploadFile';
47
    const EVENT_AFTER_EXPORT_ORDERS = 'afterExportOrders';
48
49
    protected $_ids;
50
51
    public function init()
52
    {
53
        set_time_limit($this->module->timeLimit);
54
        if ($this->module->memoryLimit) {
55
            ini_set('memory_limit', $this->module->memoryLimit);
56
        }
57
        parent::init();
58
    }
59
60
61
    /**
62
     * @return array
63
     */
64
    public function behaviors()
65
    {
66
        return array_merge(parent::behaviors(), [
67
            'bom' => [
68
                'class' => BomBehavior::class,
69
                'only' => ['query'],
70
            ],
71
        ]);
72
    }
73
74
    /**
75
     * @param \yii\base\Action $action
76
     * @param mixed $result
77
     * @return mixed|string
78
     */
79
    public function afterAction($action, $result)
80
    {
81
        Yii::$app->response->headers->set('uid', Yii::$app->user->getId());
0 ignored issues
show
Bug introduced by
The method getId() does not exist on null. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

81
        Yii::$app->response->headers->set('uid', Yii::$app->user->/** @scrutinizer ignore-call */ getId());

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
82
        if (is_bool($result)) {
83
            return $result ? 'success' : 'failure';
84
        }
85
86
        if (is_array($result)) {
87
            $r = [];
88
            foreach ($result as $key => $value) {
89
                $r[] = is_int($key) ? $value : $key . '=' . $value;
90
            }
91
            return implode("\n", $r);
92
        }
93
94
        return parent::afterAction($action, $result);
95
    }
96
97
    /**
98
     * @param $type
99
     * @return array|bool
100
     */
101
    public function actionCheckauth($type)
0 ignored issues
show
Unused Code introduced by
The parameter $type is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

101
    public function actionCheckauth(/** @scrutinizer ignore-unused */ $type)

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
102
    {
103
        if (Yii::$app->user->isGuest) {
104
            return false;
105
        }
106
107
        return [
108
            'success',
109
            'PHPSESSID',
110
            Yii::$app->session->getId(),
0 ignored issues
show
Bug introduced by
The method getId() does not exist on null. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

110
            Yii::$app->session->/** @scrutinizer ignore-call */ 
111
                                getId(),

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
111
        ];
112
    }
113
114
    /**
115
     * @return float|int|false
116
     */
117
    protected function getFileLimit()
118
    {
119
        $limit = ByteHelper::maximum_upload_size();
120
        if (!($limit % 2)) {
121
            $limit--;
122
        }
123
        return $limit;
124
    }
125
126
    /**
127
     * @return array
128
     */
129
    public function actionInit($type)
130
    {
131
        switch ($type) {
132
            case 'catalog':
133
                $pattern = '*.xml';
134
                $dir = $this->module->getTmpDir() . DIRECTORY_SEPARATOR . $pattern;
135
                foreach (glob($dir) as $file) {
136
                    if ($this->module->debug) {
137
                        rename($file, str_replace('.xml', date("_Y-m-d H.i.s", filemtime($file)) . '.xml.bak', $file));
138
                    } else {
139
                        FileHelper::unlink($file);
140
                    }
141
                }
142
                break;
143
        }
144
        return [
145
            'zip' => class_exists('ZipArchive') && $this->module->useZip ? 'yes' : 'no',
146
            'file_limit' => $this->getFileLimit(),
147
        ];
148
    }
149
150
    /**
151
     * @param $type
152
     * @param $filename
153
     * @return bool
154
     */
155
    public function actionFile($type, $filename)
0 ignored issues
show
Unused Code introduced by
The parameter $type is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

155
    public function actionFile(/** @scrutinizer ignore-unused */ $type, $filename)

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
156
    {
157
        $body = Yii::$app->request->getRawBody();
158
        $filePath = $this->module->getTmpDir() . DIRECTORY_SEPARATOR . $filename;
159
        if (!is_dir(dirname($filePath))) {
160
            FileHelper::createDirectory(dirname($filePath));
161
        }
162
        $isArchive = strtolower(pathinfo($filePath, PATHINFO_EXTENSION)) === 'zip';
163
        file_put_contents($filePath, $body, FILE_APPEND);
164
        if ((int)Yii::$app->request->headers->get('Content-Length') != $this->getFileLimit()) {
165
            if ($isArchive) {
166
                $this->extractArchive($filePath);
167
            }
168
            $this->afterFinishUploadFile($filePath);
169
        }
170
        return true;
171
    }
172
173
    /**
174
     * @param $file
175
     */
176
    public function parsingImport($file)
177
    {
178
        $this->_ids = [];
179
        $commerce = new CommerceML();
180
        $commerce->loadImportXml($file);
181
        $classifierFile = Yii::getAlias($this->module->tmpDir . '/classifier.xml');
182
        if ($commerce->classifier->xml) {
183
            $commerce->classifier->xml->saveXML($classifierFile);
184
        } else {
185
            $commerce->classifier->xml = simplexml_load_string(file_get_contents($classifierFile));
0 ignored issues
show
Documentation Bug introduced by
It seems like simplexml_load_string(fi...tents($classifierFile)) can also be of type false. However, the property $xml is declared as type SimpleXMLElement. Maybe add an additional type check?

Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a mixed type is assigned to a property that is type hinted more strictly.

For example, imagine you have a variable $accountId that can either hold an Id object or false (if there is no account id yet). Your code now assigns that value to the id property of an instance of the Account class. This class holds a proper account, so the id value must no longer be false.

Either this assignment is in error or a type check should be added for that assignment.

class Id
{
    public $id;

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

}

class Account
{
    /** @var  Id $id */
    public $id;
}

$account_id = false;

if (starsAreRight()) {
    $account_id = new Id(42);
}

$account = new Account();
if ($account instanceof Id)
{
    $account->id = $account_id;
}
Loading history...
186
        }
187
        $this->beforeProductSync();
188
        if ($groupClass = $this->getGroupClass()) {
189
            $groupClass::createTree1c($commerce->classifier->getGroups());
190
        }
191
        $productClass = $this->getProductClass();
192
        $productClass::createProperties1c($commerce->classifier->getProperties());
193
        foreach ($commerce->catalog->getProducts() as $product) {
194
            if (!$model = $productClass::createModel1c($product)) {
195
                Yii::error("Модель продукта не найдена, проверьте реализацию $productClass::createModel1c",
196
                    'exchange1c');
197
                continue;
198
            }
199
            $this->parseProduct($model, $product);
200
            $this->_ids[] = $model->getPrimaryKey();
201
            $model = null;
202
            unset($model, $product);
203
            gc_collect_cycles();
204
        }
205
        $this->afterProductSync();
206
    }
207
208
    /**
209
     * @param $file
210
     */
211
    public function parsingOffer($file)
212
    {
213
        $this->_ids = [];
214
        $commerce = new CommerceML();
215
        $commerce->loadOffersXml($file);
216
        if ($offerClass = $this->getOfferClass()) {
217
            $offerClass::createPriceTypes1c($commerce->offerPackage->getPriceTypes());
218
        }
219
        $this->beforeOfferSync();
220
        foreach ($commerce->offerPackage->getOffers() as $offer) {
221
            $product_id = $offer->getClearId();
222
            if ($product = $this->findProductModelById($product_id)) {
223
                $model = $product->getOffer1c($offer);
224
                $this->parseProductOffer($model, $offer);
225
                $this->_ids[] = $model->getPrimaryKey();
226
            } else {
227
                Yii::warning("Продукт $product_id не найден в базе", 'exchange1c');
228
                continue;
229
            }
230
            unset($model);
231
        }
232
        $this->afterOfferSync();
233
    }
234
235
    /**
236
     * @param $file
237
     */
238
    public function parsingOrder($file)
239
    {
240
        /**
241
         * @var DocumentInterface $documentModel
242
         */
243
        $commerce = new CommerceML();
244
        $commerce->addXmls(false, false, $file);
245
        $documentClass = $this->module->documentClass;
246
        foreach ($commerce->order->documents as $document) {
247
            if ($documentModel = $documentClass::findOne((string)$document->Номер)) {
248
                $documentModel->setRaw1cData($commerce, $document);
249
            }
250
        }
251
    }
252
253
    /**
254
     * @param $filePath
255
     */
256
    private function extractArchive($filePath)
257
    {
258
        $zip = new \ZipArchive();
259
        $zip->open($filePath);
260
        $zip->extractTo(dirname($filePath));
261
        $zip->close();
262
        if (!$this->module->debug) {
263
            FileHelper::unlink($filePath);
264
        }
265
    }
266
267
    /**
268
     * @param $type
269
     * @param $filename
270
     * @return bool
271
     */
272
    public function actionImport($type, $filename)
273
    {
274
        $file = $this->module->getTmpDir() . DIRECTORY_SEPARATOR . $filename;
275
        switch ($type) {
276
            case 'catalog':
277
                if (strpos($file, 'offer') !== false) {
278
                    $this->parsingOffer($file);
279
                } elseif (strpos($file, 'import') !== false) {
280
                    $this->parsingImport($file);
281
                }
282
                break;
283
            case 'sale':
284
                if (strpos($file, 'order') !== false) {
285
                    $this->parsingOrder($file);
286
                }
287
                break;
288
        }
289
        if (!$this->module->debug) {
290
            FileHelper::unlink($file);
291
        }
292
        return true;
293
    }
294
295
    protected function clearTmp()
296
    {
297
        FileHelper::removeDirectory($this->module->getTmpDir());
298
    }
299
300
    /**
301
     * @param $type
302
     * @return mixed
303
     */
304
    public function actionQuery($type)
0 ignored issues
show
Unused Code introduced by
The parameter $type is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

304
    public function actionQuery(/** @scrutinizer ignore-unused */ $type)

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
305
    {
306
        /**
307
         * @var DocumentInterface $document
308
         */
309
        $response = Yii::$app->response;
0 ignored issues
show
Documentation Bug introduced by
It seems like Yii::app->response can also be of type yii\web\Response. However, the property $response is declared as type yii\console\Response. Maybe add an additional type check?

Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a mixed type is assigned to a property that is type hinted more strictly.

For example, imagine you have a variable $accountId that can either hold an Id object or false (if there is no account id yet). Your code now assigns that value to the id property of an instance of the Account class. This class holds a proper account, so the id value must no longer be false.

Either this assignment is in error or a type check should be added for that assignment.

class Id
{
    public $id;

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

}

class Account
{
    /** @var  Id $id */
    public $id;
}

$account_id = false;

if (starsAreRight()) {
    $account_id = new Id(42);
}

$account = new Account();
if ($account instanceof Id)
{
    $account->id = $account_id;
}
Loading history...
310
        $response->format = Response::FORMAT_RAW;
311
        $response->getHeaders()->set('Content-Type', 'application/xml; charset=windows-1251');
312
313
        $root = new \SimpleXMLElement('<КоммерческаяИнформация></КоммерческаяИнформация>');
314
        $root->addAttribute('ВерсияСхемы', $this->commerceMLVersion);
315
        $root->addAttribute('ДатаФормирования', date('Y-m-d\TH:i:s'));
316
317
        $ids = [];
318
        if ($this->module->exchangeDocuments) {
319
            $document = $this->module->documentClass;
320
            foreach ($document::findDocuments1c() as $order) {
321
                $ids[] = $order->getPrimaryKey();
322
                NodeHelper::appendNode($root, SerializeHelper::serializeDocument($order));
323
            }
324
            if ($this->module->debug) {
325
                $xml = $root->asXML();
326
                $xml = html_entity_decode($xml, ENT_NOQUOTES, 'UTF-8');
327
                file_put_contents($this->module->getTmpDir() . '/query.xml', $xml);
328
            }
329
        }
330
        $this->afterExportOrders($ids);
331
        return $root->asXML();
332
    }
333
334
    /**
335
     * @param $type
336
     * @return bool
337
     */
338
    public function actionSuccess($type)
0 ignored issues
show
Unused Code introduced by
The parameter $type is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

338
    public function actionSuccess(/** @scrutinizer ignore-unused */ $type)

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
339
    {
340
        return true;
341
    }
342
343
    /**
344
     * @param $name
345
     * @param $value
346
     */
347
    protected static function setData($name, $value)
348
    {
349
        Yii::$app->session->set($name, $value);
350
    }
351
352
    /**
353
     * @param $name
354
     * @param null $default
0 ignored issues
show
Documentation Bug introduced by
Are you sure the doc-type for parameter $default is correct as it would always require null to be passed?
Loading history...
355
     * @return mixed
356
     */
357
    protected static function getData($name, $default = null)
358
    {
359
        return Yii::$app->session->get($name, $default);
360
    }
361
362
    /**
363
     * @return bool
364
     */
365
    protected static function clearData()
366
    {
367
        return Yii::$app->session->closeSession();
368
    }
369
370
    /**
371
     * @param ProductInterface $model
372
     * @param \Zenwalker\CommerceML\Model\Product $product
373
     */
374
    protected function parseProduct($model, $product)
375
    {
376
        $this->beforeUpdateProduct($model);
377
        $model->setRaw1cData($product->owner, $product);
378
        $this->parseGroups($model, $product);
379
        $this->parseProperties($model, $product);
380
        $this->parseRequisites($model, $product);
381
        $this->parseImage($model, $product);
382
        $this->afterUpdateProduct($model);
383
        unset($group);
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $group seems to be never defined.
Loading history...
384
    }
385
386
    /**
387
     * @param OfferInterface $model
388
     * @param Offer $offer
389
     */
390
    protected function parseProductOffer($model, $offer)
391
    {
392
        $this->beforeUpdateOffer($model, $offer);
393
        $this->parseSpecifications($model, $offer);
394
        $this->parsePrice($model, $offer);
395
        $model->{$model::getIdFieldName1c()} = $offer->id;
396
        $model->save();
397
        $this->afterUpdateOffer($model, $offer);
398
    }
399
400
    /**
401
     * @param string $id
402
     *
403
     * @return ProductInterface|null
404
     */
405
    protected function findProductModelById($id)
406
    {
407
        /**
408
         * @var $class ProductInterface
409
         */
410
        $class = $this->getProductClass();
411
        return $class::find()->andWhere([$class::getIdFieldName1c() => $id])->one();
0 ignored issues
show
Bug Best Practice introduced by
The expression return $class::find()->a...ame1c() => $id))->one() also could return the type array which is incompatible with the documented return type carono\exchange1c\interfaces\ProductInterface|null.
Loading history...
412
    }
413
414
    /**
415
     * @param Offer $offer
416
     *
417
     * @return OfferInterface|null
418
     */
419
    protected function findOfferModel($offer)
420
    {
421
        /**
422
         * @var $class ProductInterface
423
         */
424
        $class = $this->getOfferClass();
425
        return $class::find()->andWhere([$class::getIdFieldName1c() => $offer->id])->one();
0 ignored issues
show
Bug Best Practice introduced by
The expression return $class::find()->a... => $offer->id))->one() also could return the type array which is incompatible with the documented return type carono\exchange1c\interfaces\OfferInterface|null.
Loading history...
426
    }
427
428
    /**
429
     * @return ActiveRecord
430
     */
431
    protected function createProductModel($data)
432
    {
433
        $class = $this->getProductClass();
434
        if ($model = $class::createModel1c($data)) {
435
            return $model;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $model returns the type carono\exchange1c\interfaces\ProductInterface which is incompatible with the documented return type yii\db\ActiveRecord.
Loading history...
436
        }
437
438
        return Yii::createObject(['class' => $class]);
439
    }
440
441
    /**
442
     * @param OfferInterface $model
443
     * @param Offer $offer
444
     */
445
    protected function parsePrice($model, $offer)
446
    {
447
        foreach ($offer->getPrices() as $price) {
448
            $model->setPrice1c($price);
449
        }
450
    }
451
452
    /**
453
     * @param ProductInterface $model
454
     * @param Product $product
455
     */
456
    protected function parseImage($model, $product)
457
    {
458
        $images = $product->getImages();
459
        foreach ($images as $image) {
460
            $path = realpath($this->module->getTmpDir() . DIRECTORY_SEPARATOR . $image->path);
461
            if (file_exists($path)) {
462
                $model->addImage1c($path, $image->caption);
463
            }
464
        }
465
    }
466
467
    /**
468
     * @param ProductInterface $model
469
     * @param Product $product
470
     */
471
    protected function parseGroups($model, $product)
472
    {
473
        $group = $product->getGroup();
474
        $model->setGroup1c($group);
475
    }
476
477
    /**
478
     * @param ProductInterface $model
479
     * @param Product $product
480
     */
481
    protected function parseRequisites($model, $product)
482
    {
483
        $requisites = $product->getRequisites();
484
        foreach ($requisites as $requisite) {
485
            $model->setRequisite1c($requisite->name, $requisite->value);
486
        }
487
    }
488
489
    /**
490
     * @param OfferInterface $model
491
     * @param Offer $offer
492
     */
493
    protected function parseSpecifications($model, $offer)
494
    {
495
        foreach ($offer->getSpecifications() as $specification) {
496
            $model->setSpecification1c($specification);
497
        }
498
    }
499
500
    /**
501
     * @param ProductInterface $model
502
     * @param Product $product
503
     */
504
    protected function parseProperties($model, $product)
505
    {
506
        $properties = $product->getProperties();
507
        foreach ($properties as $property) {
508
            $model->setProperty1c($property);
509
        }
510
    }
511
512
    /**
513
     * @return OfferInterface
514
     */
515
    protected function getOfferClass()
516
    {
517
        return $this->module->offerClass;
518
    }
519
520
    /**
521
     * @return ProductInterface
522
     */
523
    protected function getProductClass()
524
    {
525
        return $this->module->productClass;
526
    }
527
528
    /**
529
     * @return DocumentInterface
530
     */
531
    protected function getDocumentClass()
532
    {
533
        return $this->module->documentClass;
534
    }
535
536
    /**
537
     * @return \carono\exchange1c\interfaces\GroupInterface
538
     */
539
    protected function getGroupClass()
540
    {
541
        return $this->module->groupClass;
542
    }
543
544
    /**
545
     * @return bool
546
     */
547
    public function actionError()
548
    {
549
        return false;
550
    }
551
552
    /**
553
     * @param $filePath
554
     */
555
    public function afterFinishUploadFile($filePath)
556
    {
557
        $this->module->trigger(self::EVENT_AFTER_FINISH_UPLOAD_FILE, new ExchangeEvent(['filePath' => $filePath]));
558
    }
559
560
    public function beforeProductSync()
561
    {
562
        $this->module->trigger(self::EVENT_BEFORE_PRODUCT_SYNC, new ExchangeEvent());
563
    }
564
565
    public function afterProductSync()
566
    {
567
        $this->module->trigger(self::EVENT_AFTER_PRODUCT_SYNC, new ExchangeEvent(['ids' => $this->_ids]));
568
    }
569
570
    public function beforeOfferSync()
571
    {
572
        $this->module->trigger(self::EVENT_BEFORE_OFFER_SYNC, new ExchangeEvent());
573
    }
574
575
    public function afterOfferSync()
576
    {
577
        $this->module->trigger(self::EVENT_AFTER_OFFER_SYNC, new ExchangeEvent(['ids' => $this->_ids]));
578
    }
579
580
    /**
581
     * @param $model
582
     */
583
    public function afterUpdateProduct($model)
584
    {
585
        $this->module->trigger(self::EVENT_AFTER_UPDATE_PRODUCT, new ExchangeEvent(['model' => $model]));
586
    }
587
588
    /**
589
     * @param $model
590
     */
591
    public function beforeUpdateProduct($model)
592
    {
593
        $this->module->trigger(self::EVENT_BEFORE_UPDATE_PRODUCT, new ExchangeEvent(['model' => $model]));
594
    }
595
596
    /**
597
     * @param $model
598
     * @param $offer
599
     */
600
    public function beforeUpdateOffer($model, $offer)
601
    {
602
        $this->module->trigger(self::EVENT_BEFORE_UPDATE_OFFER, new ExchangeEvent([
603
            'model' => $model,
604
            'ml' => $offer,
605
        ]));
606
    }
607
608
    /**
609
     * @param $model
610
     * @param $offer
611
     */
612
    public function afterUpdateOffer($model, $offer)
613
    {
614
        $this->module->trigger(self::EVENT_AFTER_UPDATE_OFFER, new ExchangeEvent(['model' => $model, 'ml' => $offer]));
615
    }
616
617
    /**
618
     * @param $ids
619
     */
620
    public function afterExportOrders($ids)
621
    {
622
        $this->module->trigger(self::EVENT_AFTER_EXPORT_ORDERS, new ExchangeEvent(['ids' => $ids]));
623
    }
624
}
625