Bitrix-D7 23.9
 
Загрузка...
Поиск...
Не найдено
synchronizer.php
1<?php
2
3
5
6
21
27final class Synchronizer
28{
29 protected $request;
30
31 const SYNCHRONIZER_MARKER_ERROR = 'SYNCHRONIZER_ERROR';
32 const MODE_SAVE = 'save';
33 const MODE_DELETE = 'delete';
34
35 public function __construct()
36 {
37 $this->request = Context::getCurrent()->getRequest();
38 }
39
40 public function incomingReplication($id='', $xmlId='', $action='', $accessToken='')
41 {
42 $result = new Result();
43 $instance = Manager::getInstance();
44
45 if($instance->isActive() == false)
46 return $result;
47
48 //region debug
49 if($id === '')
50 $id = $this->request->getPost('data')['FIELDS']['ID'];
51 if($xmlId === '')
52 $xmlId = $this->request->getPost('data')['FIELDS']['XML_ID'];
53 if($action === '')
54 $action = $this->request->getPost('data')['FIELDS']['ACTION'];
55 if($accessToken === '')
56 $accessToken = $this->request->getPost('auth')['access_token'];
57 //endregion
58
59 LoggerDiag::addMessage('SYNCHRONIZER_INCOMING_REPLICATION_INCOMING_REQUEST', var_export(['id'=>$id, 'xmlId'=>$xmlId,' action'=>$action, 'accessToken'=>$accessToken], true));
60 LoggerDiag::addMessage('SYNCHRONIZER_INCOMING_REPLICATION_FLAGS', var_export(['action'=>$instance->getAction()], true));
61
62 $r = $instance->getClient()->checkAccessToken($accessToken);
63 if($r->isSuccess())
64 {
65 LoggerDiag::addMessage('SYNCHRONIZER_INCOMING_REPLICATION_CHECK_ACCESS_TOKEN_SUCCESS', var_export(['access_token'=>$accessToken], true));
66
67 $instance->setAccessToken($accessToken);
68
69 if($action == self::MODE_DELETE)
70 {
71 //TODO: ,
72
73 LoggerDiag::addMessage('SYNCHRONIZER_INCOMING_REPLICATION_FILTER_BY_XML_ID', var_export(['xmlId'=>$xmlId], true));
74
77 $orderClass = $registry->getOrderClassName();
78
80 $orders = $orderClass::loadByFilter(['filter'=>['XML_ID'=>$xmlId]]);
81 if(count($orders)>0)
82 {
83 LoggerDiag::addMessage('SYNCHRONIZER_INCOMING_REPLICATION_FILTER_BY_XML_ID_SUCCESS', var_export($orders, true));
84
85 $controllerOrder = new \Bitrix\Sale\Controller\Order();
86 LoggerDiag::addMessage('SYNCHRONIZER_INCOMING_REPLICATION_DELETED_BY_INTERNAL_ID', var_export($orders[0], true));
87
89 $controllerOrder->importDeleteAction($orders[0]);
90 if(count($controllerOrder->getErrors())>0)
91 {
92 $r->addErrors($controllerOrder->getErrors());
93 LoggerDiag::addMessage('SYNCHRONIZER_INCOMING_REPLICATION_DELETED_BY_INTERNAL_ID_ERROR');
94 }
95 else
96 LoggerDiag::addMessage('SYNCHRONIZER_INCOMING_REPLICATION_DELETED_BY_INTERNAL_ID_SUCCESS');
97 }
98 else
99 {
100 $r->addError(new Error('Order not found', 'ORDER_NOT_FOUND'));
101 LoggerDiag::addMessage('SYNCHRONIZER_INCOMING_REPLICATION_FILTER_BY_XML_ID_ERROR');
102 }
103 }
104 elseif($action == self::MODE_SAVE)
105 {
106 LoggerDiag::addMessage('SYNCHRONIZER_INCOMING_REPLICATION_REQUEST_EXTERNAL_ENTITY_BY_ID', var_export(['id'=>$id], true));
107
108 $r = $instance->getClient()->call(
109 'sale.order.get',
110 [
111 'auth'=>$accessToken,
112 'id'=>$id
113 ]
114 );
115 if($r->isSuccess())
116 {
117 LoggerDiag::addMessage('SYNCHRONIZER_INCOMING_REPLICATION_REQUEST_EXTERNAL_ENTITY_BY_ID_SUCCESS', var_export(['sale.order.get'=>$r->getData()['DATA']['result']], true));
118
119 $r = $this->import($r->getData()['DATA']['result']);
120 if($r->isSuccess())
121 {
122 $result->setData(['DATA'=>$r->getData()['DATA']]);
123
124 $orderId = isset($r->getData()['DATA']['ORDER']['ID'])?$r->getData()['DATA']['ORDER']['ID']:0;
125 $siteId = isset($r->getData()['DATA']['ORDER']['LID'])?$r->getData()['DATA']['ORDER']['LID']:'';
126
128 [
129 'direction'=>'incoming',
130 'type'=>'success',
131 'orderId'=>$orderId,
132 'siteId'=>$siteId
133 ]
134 );
135
136 self::addActionOrderHistory(
137 [
138 'orderId'=>$orderId,
139 'typeName'=>'ORDER_SYNCHRONIZATION_IMPORT',
140 'fields'=>['EXTERNAL_ORDER_ID'=>$id]
141 ]
142 );
143 }
144 else
145 {
147 [
148 'direction'=>'incoming',
149 'type'=>'failed',
150 'errorMessage'=>$r->getErrorMessages()[0]
151 ]
152 );
153 }
154 }
155 else
156 LoggerDiag::addMessage('SYNCHRONIZER_INCOMING_REPLICATION_REQUEST_EXTERNAL_ENTITY_BY_ID_ERROR');
157 }
158 else
159 {
160 $r = new Result();
161 $r->addError(new Error('Action udefined'));
162 LoggerDiag::addMessage('SYNCHRONIZER_INCOMING_REPLICATION_UNKNOWN_COMMAND', var_export(['action'=>$action], true));
163 }
164 }
165 else
166 LoggerDiag::addMessage('SYNCHRONIZER_INCOMING_REPLICATION_CHECK_ACCESS_TOKEN_ERROR');
167
168 if(!$r->isSuccess())
169 {
170 $result->addErrors($r->getErrors());
171 LoggerDiag::addMessage('SYNCHRONIZER_INCOMING_REPLICATION_RESULT_ERROR', var_export([
172 'parameters'=>[
173 'action'=>$action,
174 'id'=>$id,
175 'xmlId'=>$xmlId,
176 'auth'=>$accessToken,
177 'errors'=>$result->getErrorMessages()
178 ]], true));
179
180 //return new EventResult( EventResult::ERROR, ResultError::create(current($orderController->getErrors())), 'sale');
181 }
182 else
183 {
184 LoggerDiag::addMessage('SYNCHRONIZER_INCOMING_REPLICATION_RESULT_SUCCESS', var_export([
185 'id'=>$id,
186 'xmlId'=>$xmlId,
187 'action'=>$action,
188 'result'=>$result->getData()['DATA']
189 ], true));
190 }
191
192 //return new EventResult( EventResult::SUCCESS, null, 'sale');
193 return $result;
194 }
195
196 public function onSaleOrderSaved(Order $order)
197 {
198 $instance = Manager::getInstance();
199
200 //TODO: rest-
201 if($instance->getAction() == Manager::ACTION_DELETED)
202 return new EventResult( EventResult::SUCCESS, null, 'sale');
203
204 if($instance->getAction() == Manager::ACTION_IMPORT)
205 return new EventResult( EventResult::SUCCESS, null, 'sale');
206
207 self::outcomingReplication($order, self::MODE_SAVE);
208
209 return true;
210 }
211
212 public function onSaleBeforeOrderDelete(Order $order)
213 {
214 //TODO: huck . - deleted ..
215 // . updated_1c=Y ,
216 //
217 $instance = Manager::getInstance();
218 $instance->setAction(Manager::ACTION_DELETED);
219
220 self::outcomingReplication($order, self::MODE_DELETE);
221 return true;
222 }
223
224 public static function outcomingReplication(Order $order, $mode)
225 {
226 $result = new Result();
227
228 $instance = Manager::getInstance();
229
230 if($instance->isActive() == false)
231 return $result;
232
233 LoggerDiag::addMessage('SYNCHRONIZER_OUTCOMING_REPLICATION_OUTCOMING_REQUEST', var_export(['id'=>$order->getId(), 'mode'=>$mode], true));
234 LoggerDiag::addMessage('SYNCHRONIZER_OUTCOMING_REPLICATION_FLAGS', var_export(['action'=>$instance->getAction()], true));
235
236 $synchronizer = new self();
237 $r = $synchronizer->refreshToken();
238 if($r->isSuccess())
239 {
240 LoggerDiag::addMessage('SYNCHRONIZER_OUTCOMING_REPLICATION_REFRESH_ACCESS_TOKEN_SUCCESS', var_export(['auth'=>$instance->getAccessToken()], true));
241
242 if($mode == self::MODE_DELETE)
243 {
244 $xmlId = $order->getField('XML_ID')<>'' ? $order->getField('XML_ID'):'';
245
246 LoggerDiag::addMessage('SYNCHRONIZER_OUTCOMING_REPLICATION_REQUEST_EXTERNAL_ENTITY_BY_XML_ID', var_export(['xmlId'=>$xmlId], true));
247
248 $r = $instance->getClient()->call(
249 'sale.order.list',
250 [
251 'auth'=>$instance->getAccessToken(),
252 'select'=>[],
253 'filter'=>[
254 'xmlId'=>$xmlId
255 ]
256 ]
257 );
258
259 if($r->isSuccess())
260 {
261 LoggerDiag::addMessage('SYNCHRONIZER_OUTCOMING_REPLICATION_REQUEST_EXTERNAL_ENTITY_BY_XML_ID_SUCCESS', var_export(['sale.order.list'=>$r->getData()['DATA']], true));
262
263 if(count($r->getData()['DATA']['result']['orders'])>0)
264 {
265 $fields = $r->getData()['DATA']['result']['orders'][0];
266 if($fields['id']>0)
267 {
268 LoggerDiag::addMessage('SYNCHRONIZER_OUTCOMING_REPLICATION_REQUEST_DELETED_EXTERNAL_ENTITY_BY_ID', var_export(['id'=>$fields['id']], true));
269 $r = $instance->getClient()->call(
270 'sale.order.importdelete',
271 [
272 'auth'=>$instance->getAccessToken(),
273 'id'=>$fields['id']
274 ]
275 );
276 if($r->isSuccess())
277 {
278 LoggerDiag::addMessage('SYNCHRONIZER_OUTCOMING_REPLICATION_REQUEST_DELETED_EXTERNAL_ENTITY_BY_ID_SUCCESS', var_export(['sale.order.importdelete.result'=>$r->getData()['DATA']], true));
279
280 if($r->getData()['DATA']['result']<>1)
281 {
282 LoggerDiag::addMessage('SYNCHRONIZER_OUTCOMING_REPLICATION_REQUEST_RESULT_DELETED_EXTERNAL_ENTITY_BY_ID_ERROR');
283 $result->addError(new Error('Error delete - '.$fields['id'], 'ERROR_DELETED_EXTERNAL_ORDER'));
284 }
285 else
286 LoggerDiag::addMessage('SYNCHRONIZER_OUTCOMING_REPLICATION_REQUEST_RESULT_DELETED_EXTERNAL_ENTITY_BY_ID_SUCCESS');
287 }
288 else
289 LoggerDiag::addMessage('SYNCHRONIZER_OUTCOMING_REPLICATION_REQUEST_DELETED_EXTERNAL_ENTITY_BY_ID_ERROR');
290 }
291 else
292 LoggerDiag::addMessage('SYNCHRONIZER_OUTCOMING_REPLICATION_REQUEST_PROCESS_GET_ID');
293 }
294 else
295 LoggerDiag::addMessage('SYNCHRONIZER_OUTCOMING_REPLICATION_REQUEST_LIST_EXTERNAL_ENTITIES_BY_XML_ID_ERROR');
296 }
297 else
298 LoggerDiag::addMessage('SYNCHRONIZER_OUTCOMING_REPLICATION_REQUEST_ERROR');
299 }
300 elseif($mode == self::MODE_SAVE)
301 {
302 $controllerOrder = new \Bitrix\Sale\Controller\Order();
303
304 $r = $synchronizer->requesPrepareData(
305 $controllerOrder->getAction($order)
306 );
307 if($r->isSuccess())
308 {
309 LoggerDiag::addMessage('SYNCHRONIZER_OUTCOMING_REPLICATION_GET_INTERNAL_FIELDS', var_export(['fields'=>$r->getData()['DATA']], true));
310 $client = $instance->getClient();
311 $r = $client->call(
312 'sale.order.import',
313 [
314 'auth'=>$instance->getAccessToken(),
315 'fields'=>$r->getData()['DATA']
316 ]
317 );
318
319 if($r->isSuccess())
320 {
321 // TODO: ,
322 $externalOrderId = $r->getData()['DATA']['result']['order']['id'];
323 if(intval($externalOrderId)>0)
324 {
326 [
327 'direction'=>'outcoming',
328 'type'=>'success',
329 'orderId'=>$order->getId(),
330 'siteId'=>$order->getSiteId()
331 ]
332 );
333 }
334
335 LoggerDiag::addMessage('SYNCHRONIZER_OUTCOMING_REPLICATION_GET_INTERNAL_FIELDS_SUCCESS', var_export(['sale.order.import.result'=>$r->getData()['DATA']], true));
336 }
337 else
338 LoggerDiag::addMessage('SYNCHRONIZER_OUTCOMING_REPLICATION_GET_INTERNAL_FIELDS_ERROR');
339 }
340 else
341 LoggerDiag::addMessage('SYNCHRONIZER_OUTCOMING_REPLICATION_REQUEST_PREPARE_DATA_FIELDS_ERROR');
342 }
343 else
344 {
345 $r = new Result();
346 $r->addError(new Error('Mode udefined'));
347 LoggerDiag::addMessage('SYNCHRONIZER_OUTCOMING_REPLICATION_UNKNOWN_COMMAND', var_export(['mode'=>$mode], true));
348 }
349
350 if(!$r->isSuccess())
351 $result->addErrors($r->getErrors());
352 }
353 else
354 {
355 LoggerDiag::addMessage('SYNCHRONIZER_OUTCOMING_REPLICATION_REFRESH_ACCESS_TOKEN_ERROR', var_export($r->getErrorMessages(), true));
356 $result->addError(new Error('refresh token error'));
357 }
358
359 if($result->isSuccess())
360 {
361 self::addActionOrderHistory(
362 [
363 'order'=>$order,
364 'orderId'=>$order->getId(),
365 'typeName'=>'ORDER_SYNCHRONIZATION_EXPORT'
366 ]
367 );
368
370 'CODE'=>self::SYNCHRONIZER_MARKER_ERROR,
371 'ORDER_ID'=>$order->getId(),
372 'ENTITY_ID'=>$order->getId()
373 ]);
374
375 OrderTable::update($order->getId(), ['MARKED'=>'N']);
376
377 LoggerDiag::addMessage('SYNCHRONIZER_OUTCOMING_REPLICATION_OUTCOMING_REQUEST_SUCCESS', var_export([
378 'orderId'=>$order->getId(),
379 'mode'=>$mode,
380 'result'=>$r->getData()['DATA']
381 ], true));
382 }
383 else
384 {
385 self::addActionOrderHistory(
386 [
387 'order'=>$order,
388 'orderId'=>$order->getId(),
389 'typeName'=>'ORDER_SYNCHRONIZATION_EXPORT_ERROR',
390 'fields'=>[
391 'ERROR' => $result->getErrorMessages()
392 ]
393 ]
394 );
395
396 if($instance->isMarked())
397 {
398 $result->addWarning(new Error(Loc::getMessage('SYNCH_OUTCOMING_REPLICATION_OUTCOMING_ORDER_ERROR', ['#ERROR_MESSAGE#'=>$result->getErrorMessages()[0]]), self::SYNCHRONIZER_MARKER_ERROR));
399 EntityMarker::addMarker($order, $order, $result);
401
402 if($r->isSuccess())
403 OrderTable::update($order->getId(), ['MARKED'=>'Y']);
404 }
405
406 LoggerDiag::addMessage('SYNCHRONIZER_OUTCOMING_REPLICATION_OUTCOMING_REQUEST_ERROR', var_export($result->getErrorMessages(), true));
407 }
408 return $result;
409 }
410
411 public function refreshToken()
412 {
413 $instance = Manager::getInstance();
415 $client = $instance->getClient();
416 $r = $client->refreshToken($instance->getRefreshToken());
417 if($r->isSuccess())
418 {
419 $data = $r->getData()['DATA'];
420
421 $instance->setAccessToken($data['access_token']);
422 $instance->setRefreshToken($data['refresh_token']);
423 }
424
425 return $r;
426 }
427
428 public function requesPrepareData(array $fields)
429 {
430 $result = new Result();
431 $manager = new Manager();
432
433 // tradeBindings .. .
434 // .
435 //if(count($fields['ORDER']['TRADE_BINDINGS'])>0)
436 //{
437 // foreach($fields['ORDER']['TRADE_BINDINGS'] as $k=>$item)
438 // {
439 // $fields['ORDER']['TRADE_BINDINGS'][$k]['FIELDS'] = array_intersect_key($item['FIELDS'], $restTradeBinding->getFieldsForShow());
440 // }
441 //}
442
443 // - ' 24 '
444 //
445 // .
446 if($manager->getTradePlatformsXmlId($fields['ORDER']['LID'])<>'')
447 {
448 $fields['ORDER']['TRADE_BINDINGS'][] = [
449 'XML_ID'=>$fields['ORDER']['ID'],
450 'EXTERNAL_ORDER_ID'=>$fields['ORDER']['ID'],
451 'TRADING_PLATFORM_XML_ID'=>$manager->getTradePlatformsXmlId($fields['ORDER']['LID'])
452 ];
453 }
454
455 $externalizer = new Externalizer('import', [], new \Bitrix\Sale\Controller\Order(), $fields, Controller::SCOPE_REST);
456 $fields = $externalizer->process()->getData()['data'];
457
458 //$fields = $coverter->process($fields);
459
460 $respons = new \Bitrix\Main\Engine\Response\Json($fields);
461 $fields = \Bitrix\Main\Web\Json::decode($respons->getContent());
462
463 if(is_array($fields) && count($fields)>0)
464 {
465 $result->setData(['DATA'=>$fields]);
466 }
467 else
468 {
469 $result->addError(new Error('Reques prepare data empty respons'));
470 }
471
472 return $result;
473 }
474
475 protected function import(array $fields)
476 {
477 $r = new Result();
478 $errors=[];
479
480 $internalizer = new Internalizer('import', ['fields'=>$fields], new \Bitrix\Sale\Controller\Order(), [], Controller::SCOPE_REST);
481 $process = $internalizer->process();
482
483 if($process->isSuccess())
484 {
485 $fields = $process->getData()['data']['fields'];
486
487 LoggerDiag::addMessage('SYNCHRONIZER_IMPORT_FIELDS', var_export($fields, true));
488
489 $orderController = new \Bitrix\Sale\Controller\Order();
490
491 try
492 {
493 $result = $orderController->importAction($fields);
494 }
495 catch (\Bitrix\Main\SystemException $e)
496 {
497 $errors[] = new Error('SYNCH_OUTCOMING_REPLICATION_IMPORT_INTERNAL_ERROR');
498 LoggerDiag::addMessage('SYNCHRONIZER_IMPORT_FIELDS_EXCEPTION', var_export($e->getTraceAsString(), true));
499 }
500
501 if(count($orderController->getErrors())>0)
502 {
503 $errors = $orderController->getErrors();
504 }
505 }
506 else
507 {
508 $errors = $r->getErrors();
509 }
510
511 if(count($errors)>0)
512 {
513 $r->addErrors($errors);
514 LoggerDiag::addMessage('SYNCHRONIZER_IMPORT_FIELDS_ERROR', var_export($errors, true));
515 }
516 else
517 {
518 $r->setData(['DATA'=>$result]);
519 LoggerDiag::addMessage('SYNCHRONIZER_IMPORT_FIELDS_SUCCESS', var_export($result, true));
520 }
521
522 return $r;
523 }
524
525 protected static function addMarkedTimelineExternalSystem($externalOrderId, array $params)
526 {
527 $typeId = 0;
528 $message = '';
529 $siteName = '';
530
531 $sites = self::getSites();
532 $instance = Manager::getInstance();
533
534 if($params['type'] == 'success')
535 $typeId = 2;
536 elseif ($params['type']== 'failed')
537 $typeId = 5;
538
539 if(isset($params['siteId']) && $params['siteId']<>'')
540 $siteName = isset($sites[$params['siteId']])?$sites[$params['siteId']]['NAME']:'';
541 if($siteName == '')
542 $siteName = $sites[SITE_ID]['NAME'];
543
544 if($params['direction'] == 'incoming')
545 {
546 if($params['type'] == 'success')
547 {
548 $message = Loc::getMessage('SYNCH_OUTCOMING_REPLICATION_EXTERNAL_SYSTEM_MESS_EXPORT_ORDER_SUCCESS', [
549 '#EXTERNAL_SYSTEM#'=>($siteName<>''?' ('.$siteName.')':''),
550 '#ORDER_ID#'=>($params['orderId']>0?$params['orderId']:'')
551 ]);
552 }
553 else
554 {
555 $message = Loc::getMessage('SYNCH_OUTCOMING_REPLICATION_EXTERNAL_SYSTEM_MESS_EXPORT_ORDER_ERROR', [
556 '#EXTERNAL_SYSTEM#'=>($siteName<>''?' ('.$siteName.')':''),
557 '#ERROR_MESSAGE#'=>($params['errorMessage']<>''?$params['errorMessage']:'')
558 ]);
559 }
560 }
561 if($params['direction'] == 'outcoming')
562 {
563 $message = Loc::getMessage('SYNCH_OUTCOMING_REPLICATION_EXTERNAL_SYSTEM_MESS_IMPORT_EXTERNAL_ORDER', [
564 '#EXTERNAL_SYSTEM#'=>($siteName<>''?' ('.$siteName.')':''),
565 '#ORDER_ID#'=>($params['orderId']>0?$params['orderId']:'')
566 ]);
567 }
568
569 $instance->getClient()->call(
570 'sale.synchronizer.addTimelineAfterOrderModify',
571 [
572 'auth'=>$instance->getAccessToken(),
573 'orderId'=>$externalOrderId,
574 'params'=>[
575 'type'=>$typeId,
576 'message'=>$message
577 ]
578 ]
579 );
580 }
581
586 private static function addActionOrderHistory(array $params)
587 {
588 $params['order'] = (isset($params['order']) && ($params['order'] instanceof Order)) ? $params['order']:null;
589 $params['fields'] = isset($params['fields']) ? $params['fields']:[];
590
593 $orderHistory = $registry->getOrderHistoryClassName();
594
595 $orderHistory::addAction(
596 'ORDER',
597 $params['orderId'],
598 $params['typeName'],
599 $params['orderId'],
600 $params['order'],
601 $params['fields']
602 );
603 $orderHistory::collectEntityFields('ORDER', $params['orderId']);
604 }
605
606 protected static function getSites()
607 {
608 $result=[];
609 $r = \CSite::GetList();
610 while ($row = $r->fetch())
611 $result[$row['ID']]=$row;
612
613 return $result;
614 }
615}
static getCurrent()
Definition context.php:241
static getMessage($code, $replace=null, $language=null)
Definition loc.php:29
static saveMarkers(Order $order=null)
static deleteByFilter(array $values)
static getInstance($type)
Definition registry.php:183
static addMessage($messageId, $message='')
static outcomingReplication(Order $order, $mode)
static addMarkedTimelineExternalSystem($externalOrderId, array $params)