1C-Bitrix 25.700.0
Загрузка...
Поиск...
Не найдено
transportbase.php
См. документацию.
1<?php
8
9namespace Bitrix\Sender\Integration\Crm\ReturnCustomer;
10
11use Bitrix\Crm\Category\DealCategory;
12use Bitrix\Crm\DealTable;
13use Bitrix\Crm\EntityManageFacility;
14use Bitrix\Crm\Integrity\ActualEntitySelector;
15use Bitrix\Crm\Order\Basket;
16use Bitrix\Crm\Order\BasketItem;
17use Bitrix\Crm\Order\Company;
18use Bitrix\Crm\Order\ContactCompanyEntity;
19use Bitrix\Crm\Order\Order;
20use Bitrix\Crm\Order\Payment;
21use Bitrix\Crm\PhaseSemantics;
22use Bitrix\Crm\Service\Container;
23use Bitrix\Crm\Timeline;
24use Bitrix\Main\Type\DateTime;
25use Bitrix\Sender\Internals\Queue;
26use Bitrix\Sender\Message;
27use Bitrix\Sender\Recipient;
28use Bitrix\Sender\Transport;
29
35{
36 const CODE = self::CODE_UNDEFINED;
37 const CODE_RC_LEAD = 'rc_lead';
38 const CODE_RC_DEAL = 'rc_deal';
39
41 protected $configuration;
42
45
49 public function __construct()
50 {
51 $this->configuration = new Message\Configuration();
52 }
53
59 public function getName()
60 {
61 return 'Rc';
62 }
63
69 public function getCode()
70 {
71 return static::CODE;
72 }
73
87
93 public function loadConfiguration()
94 {
96 }
97
99 {
100 $this->configuration = $configuration;
101 }
102
108 public function start()
109 {
110
111 }
112
119 public function send(Message\Adapter $message)
120 {
121 $config = $message->getConfiguration();
122 $authorId = $config->get('LETTER_CREATED_BY_ID');
123 $crmEntityTypeId = Service::getTypeIdByRecipientType($message->getRecipientType());
124 $crmEntityId = $message->getRecipientCode();
125 $text = $message->replaceFields($config->get('COMMENT'), '#', $crmEntityTypeId);
126
127 if (!$this->responsibleQueue || $this->responsibleQueue->getId() <> $message->getId())
128 {
129 $responsibleList = $config->get('ASSIGNED_BY');
130 if ($responsibleList)
131 {
132 $responsibleList = explode(',', $responsibleList);
133 }
134 if (empty($responsibleList))
135 {
136 $responsibleList = [$authorId];
137 }
138 $this->responsibleQueue = (new Queue('sender/rc', $message->getId()))
139 ->enableUserCheck()
140 ->disableAutoSave()
141 ->setValues($responsibleList);
142
143 if ($config->get('CHECK_WORK_TIME') === 'Y')
144 {
145 $this->responsibleQueue->enableWorkTimeCheck();
146 }
147 }
148
149 $entityFields['TITLE'] = $message->replaceFields($config->get('TITLE'), '#', $crmEntityTypeId);
150 $assignedId = $this->getAssignedWithCrmData((int)$crmEntityTypeId, (int)$crmEntityId);
151 $isAssignedById = ($config->get('LINK_WITH_RESPONSIBLE') === 'Y') && $assignedId;
152 $entityFields['ASSIGNED_BY_ID'] = $isAssignedById ? $assignedId : $this->responsibleQueue->next();
153
154 $selector = (new ActualEntitySelector())
155 ->setEntity($crmEntityTypeId, $crmEntityId)
156 ->search();
157 $facility = new EntityManageFacility($selector);
158 $facility->enableAutoGenRc();
159
160 if ($config->get('ALWAYS_ADD') === 'Y' || $config->get('FROM_PREVIOUS') === 'Y')
161 {
162 $facility->setRegisterMode(EntityManageFacility::REGISTER_MODE_ALWAYS_ADD);
163 }
164
165 $crmRegisterOptions = ['CURRENT_USER' => $authorId];
166
167 switch ($message->getCode())
168 {
170 if (empty($entityFields['SOURCE_ID']))
171 {
172 $entityFields['SOURCE_ID'] = 'RC_GENERATOR';
173 }
174 $facility->registerLead($entityFields, true, $crmRegisterOptions);
175 break;
176
178 if (empty($entityFields['SOURCE_ID']))
179 {
180 $entityFields['SOURCE_ID'] = 'RC_GENERATOR';
181 }
182 $entityFields['CATEGORY_ID'] = $this->detectDealCategoryId(
183 $config->get('CATEGORY_ID'),
184 $facility
185 );
186
187
188 if ($config->get('FROM_PREVIOUS') === 'Y')
189 {
190 $lastDeal = $this->getLastDeal($facility, $config->get('DEAL_DAYS_AGO'));
191 $lastOrder = $this->getOrderData($lastDeal['ID']);
192 if(!$lastDeal || !$lastOrder)
193 {
194 $this->responsibleQueue->previous();
195 return false;
196 }
197
198 $entityFields += $lastDeal;
199 }
200
201
202 $registeredId = $facility->registerDeal($entityFields, true, $crmRegisterOptions);
203
204 if($registeredId && $config->get('FROM_PREVIOUS') === 'Y')
205 {
206 $this->copyDealProducts($lastDeal['ID'], $registeredId);
207 $this->copyOrder($lastDeal['ID'], $registeredId);
208 }
209 break;
210
211 default:
212 return false;
213 }
214
215 if (!$facility->getRegisteredId())
216 {
217 $this->responsibleQueue->previous();
218 return false;
219 }
220
221 if (!$text)
222 {
223 return true;
224 }
225
226 $commentId = Timeline\CommentEntry::create([
227 'TYPE_ID' => Timeline\TimelineType::COMMENT,
228 'AUTHOR_ID' => $authorId,
229 'TEXT' => $text,
230 'SETTINGS' => [],
231 'BINDINGS' => [
232 [
233 'ENTITY_TYPE_ID' => $facility->getRegisteredTypeId(),
234 'ENTITY_ID' => $facility->getRegisteredId(),
235 'IS_FIXED' => true
236 ]
237 ],
238 'ASSOCIATED_ENTITY_TYPE_ID' => $facility->getRegisteredTypeId(),
239 'ASSOCIATED_ENTITY_ID' => $facility->getRegisteredId()
240 ]);
241
242 return $commentId > 0;
243 }
244
250 public function end()
251 {
252 if ($this->responsibleQueue)
253 {
254 $this->responsibleQueue->save();
255 }
256 }
257
258 protected function detectDealCategoryId($categoryId, EntityManageFacility $facility)
259 {
260 if ($facility->canAddDeal() && !is_numeric($categoryId))
261 {
262 // retrieve category from last deal if it configured.
263 $categoryId = $this->getLastDealCategoryId($facility);
264 }
265
266 $categoryId = (int) $categoryId;
267 $categories = array_map(
268 function ($category)
269 {
270 return (int) $category['ID'];
271 },
272 DealCategory::getAll(true)
273 );
274
275 if (!in_array($categoryId, $categories))
276 {
277 $categoryId = $categories[0];
278 }
279
280 return $categoryId;
281 }
282
283 protected function getLastDealCategoryId(EntityManageFacility $facility)
284 {
285 $categoryId = null;
286 $categoryFilters = [];
287 if ($facility->getSelector()->getCompanyId())
288 {
289 $categoryFilters[] = [
290 '=COMPANY_ID' => $facility->getSelector()->getCompanyId()
291 ];
292 }
293 if ($facility->getSelector()->getContactId())
294 {
295 $categoryFilters[] = [
296 '=CONTACT_ID' => $facility->getSelector()->getContactId()
297 ];
298 }
299 foreach ($categoryFilters as $categoryFilter)
300 {
301 $categoryFilter['=STAGE_SEMANTIC_ID'] = [
302 PhaseSemantics::PROCESS,
303 PhaseSemantics::SUCCESS
304 ];
305 $dealRow = DealTable::getRow([
306 'select' => ['CATEGORY_ID'],
307 'filter' => $categoryFilter,
308 'limit' => 1,
309 'order' => ['DATE_CREATE' => 'DESC']
310 ]);
311
312 if (!$dealRow)
313 {
314 break;
315 }
316 $categoryId = $dealRow['CATEGORY_ID'];
317 }
318
319 return $categoryId;
320 }
321
322 protected function getLastDeal(EntityManageFacility $facility, $days)
323 {
324 $categoryId = null;
325 $dealFilters = [];
326 if ($facility->getSelector()->getCompanyId())
327 {
328 $dealFilters[] = [
329 '=COMPANY_ID' => $facility->getSelector()->getCompanyId()
330 ];
331 }
332 if ($facility->getSelector()->getContactId())
333 {
334 $dealFilters[] = [
335 '=CONTACT_ID' => $facility->getSelector()->getContactId()
336 ];
337 }
338 foreach ($dealFilters as $dealFilter)
339 {
340 $dealFilter['=STAGE_SEMANTIC_ID'] = [
341 PhaseSemantics::SUCCESS
342 ];
343 $days = (int) $days;
344
345 $dateCreate = (new \DateTime())->modify("-$days days");
346
347 $beginningOfTheDay = DateTime::createFromPhp($dateCreate->setTime(0,0,0));
348 $endOfTheDay = DateTime::createFromPhp($dateCreate->setTime(23,59,59));
349
350 $dealFilter['<DATE_CREATE'] = $endOfTheDay;
351 $dealFilter['>DATE_CREATE'] = $beginningOfTheDay;
352
353 $dealFilter['=HAS_PRODUCTS'] = 1;
354
355 $dealRow = DealTable::getRow([
356 'select' => ['ID', 'CURRENCY_ID', 'RECEIVED_AMOUNT'],
357 'filter' => $dealFilter,
358 'limit' => 1,
359 'order' => ['DATE_CREATE' => 'DESC']
360 ]);
361
362 if (!$dealRow)
363 {
364 break;
365 }
366
367 return $dealRow;
368 }
369
370 return null;
371 }
372
373 protected function getOrderData($dealId)
374 {
375 $dbRes = \Bitrix\Crm\Order\EntityBinding::getList([
376 'select' => ['PAYMENT_ID' => 'ORDER.PAYMENT.ID', 'PAYMENT_ORDER_ID' => 'ORDER.PAYMENT.ORDER_ID'],
377 'filter' => [
378 'OWNER_ID' => $dealId,
379 'OWNER_TYPE_ID' => \CCrmOwnerType::Deal,
380 '!ORDER.PAYMENT.PS_RECURRING_TOKEN' => '',
381 '=ORDER.PAYMENT.PAID' => 'Y',
382 ],
383 'order' => ['ORDER.PAYMENT.ID' => 'DESC']
384 ]);
385
386 return $dbRes->fetch();
387 }
388
389 protected function copyDealProducts($fromDealId, $toDealId)
390 {
391
392 $productRows = \CCrmDeal::LoadProductRows($fromDealId);
393
394 foreach($productRows as &$productRow)
395 {
396 $productRow['ID'] = 0;
397 }
398
399 \CCrmDeal::SaveProductRows($toDealId, $productRows, false);
400 }
401
402 protected function copyOrder($formDealId, $toDealId)
403 {
404 if ($data = $this->getOrderData($formDealId))
405 {
406 $registry = \Bitrix\Sale\Registry::getInstance( \Bitrix\Sale\Registry::REGISTRY_TYPE_ORDER);
407 $orderClassName = $registry->getOrderClassName();
408
410 $order = $orderClassName::load($data['PAYMENT_ORDER_ID']);
411 if ($order)
412 {
414 $newOrder = $orderClassName::create($order->getSiteId(), $order->getUserId(), $order->getCurrency());
415
417 $basketClassName = $registry->getBasketClassName();
418
419 $newBasket = $basketClassName::create($order->getSiteId());
421 foreach ($order->getBasket() as $item)
422 {
423 $basketItem = $newBasket->createItem($item->getField('MODULE'), $item->getProductId());
424 $basketItem->setFields([
425 'PRODUCT_PROVIDER_CLASS' => $item->getField('PRODUCT_PROVIDER_CLASS'),
426 'QUANTITY' => $item->getQuantity(),
427 'CURRENCY' => $item->getCurrency(),
428 'BASE_PRICE' => $item->getBasePrice(),
429 'PRICE' => $item->getPrice(),
430 'CUSTOM_PRICE' => $item->isCustomPrice() ? 'Y' : 'N',
431
432 ]);
433 }
434
435 $newOrder->setBasket($newBasket);
436
438 $payment = $order->getPaymentCollection()->getItemById($data['PAYMENT_ID']);
439 if ($payment)
440 {
441 $newPayment = $newOrder->getPaymentCollection()->createItem();
442 $newPayment->setFields([
443 'PAY_SYSTEM_ID' => $payment->getPaymentSystemId(),
444 'PAY_SYSTEM_NAME' => $payment->getPaymentSystemName(),
445 'PS_RECURRING_TOKEN' => $payment->getField('PS_RECURRING_TOKEN'),
446 'SUM' => $payment->getSum(),
447 ]);
448 }
449
451 $newShipment = $newOrder->getShipmentCollection()->createItem();
452 foreach ($newBasket as $item)
453 {
454 $newShipmentItem = $newShipment->getShipmentItemCollection()->createItem($item);
455 $newShipmentItem->setQuantity($item->getQuantity());
456 }
457
458 $binding = $newOrder->createEntityBinding();
459 $binding->setField('OWNER_ID', $toDealId);
460 $binding->setField('OWNER_TYPE_ID', \CCrmOwnerType::Deal);
461
463 foreach ($order->getContactCompanyCollection()->getCompanies() as $item)
464 {
466 $newCompany = $newOrder->getContactCompanyCollection()->createCompany();
467 $newCompany->setField('ENTITY_ID', $item->getField('ENTITY_ID'));
468 $newCompany->setField('IS_PRIMARY', $item->getField('IS_PRIMARY'));
469 }
470
472 foreach ($order->getContactCompanyCollection()->getContacts() as $item)
473 {
475 $newContact = $newOrder->getContactCompanyCollection()->createContact();
476 $newContact->setField('ENTITY_ID', $item->getField('ENTITY_ID'));
477 $newContact->setField('IS_PRIMARY', $item->getField('IS_PRIMARY'));
478 }
479
480 $newOrder->refreshData();
481 $newOrder->doFinalAction();
482
483 $newOrder->save();
484 }
485 }
486 }
487
488 private function getAssignedWithCrmData(int $typeId, int $entityId): ?int
489 {
490 $factory = Container::getInstance()->getFactory($typeId);
491
492 if (!$factory)
493 {
494 return null;
495 }
496
497 $entity = $factory->getItem($entityId);
498 if ($entity)
499 {
500 $assignedId = (int)$entity->get('ASSIGNED_BY_ID');
501 if ($assignedId)
502 {
503 return $assignedId;
504 }
505 }
506
507 return null;
508 }
509}
static getInstance($type)
Определения registry.php:183
static getTypeIdByRecipientType($recipientType)
Определения service.php:73
getLastDeal(EntityManageFacility $facility, $days)
Определения transportbase.php:322
getLastDealCategoryId(EntityManageFacility $facility)
Определения transportbase.php:283
saveConfiguration(Message\Configuration $configuration)
Определения transportbase.php:98
detectDealCategoryId($categoryId, EntityManageFacility $facility)
Определения transportbase.php:258
const CRM_COMPANY_ID
Определения type.php:24
const CRM_LEAD_ID
Определения type.php:26
const CRM_CONTACT_ID
Определения type.php:25
$data['IS_AVAILABLE']
Определения .description.php:13
$entity
Определения adapter.php:9
$payment
Определения payment.php:14
$order
Определения payment.php:8
$entityId
Определения payment.php:4
$message
Определения payment.php:8
$config
Определения quickway.php:69
$text
Определения template_pdf.php:79
$dbRes
Определения yandex_detail.php:168