Bitrix-D7 23.9
 
Загрузка...
Поиск...
Не найдено
transportbase.php
1<?php
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;
29
35{
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
80 {
81 return [
82 Recipient\Type::CRM_COMPANY_ID,
83 Recipient\Type::CRM_CONTACT_ID,
84 Recipient\Type::CRM_LEAD_ID,
85 ];
86 }
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 switch ($message->getCode())
166 {
168 if (empty($entityFields['SOURCE_ID']))
169 {
170 $entityFields['SOURCE_ID'] = 'RC_GENERATOR';
171 }
172 $facility->registerLead($entityFields);
173 break;
174
176 if (empty($entityFields['SOURCE_ID']))
177 {
178 $entityFields['SOURCE_ID'] = 'RC_GENERATOR';
179 }
180 $entityFields['CATEGORY_ID'] = $this->detectDealCategoryId(
181 $config->get('CATEGORY_ID'),
182 $facility
183 );
184
185
186 if ($config->get('FROM_PREVIOUS') === 'Y')
187 {
188 $lastDeal = $this->getLastDeal($facility, $config->get('DEAL_DAYS_AGO'));
189 $lastOrder = $this->getOrderData($lastDeal['ID']);
190 if(!$lastDeal || !$lastOrder)
191 {
192 $this->responsibleQueue->previous();
193 return false;
194 }
195
196 $entityFields += $lastDeal;
197 }
198
199
200 $registeredId = $facility->registerDeal($entityFields);
201
202 if($registeredId && $config->get('FROM_PREVIOUS') === 'Y')
203 {
204 $this->copyDealProducts($lastDeal['ID'], $registeredId);
205 $this->copyOrder($lastDeal['ID'], $registeredId);
206 }
207 break;
208
209 default:
210 return false;
211 }
212
213 if (!$facility->getRegisteredId())
214 {
215 $this->responsibleQueue->previous();
216 return false;
217 }
218
219 if (!$text)
220 {
221 return true;
222 }
223
224 $commentId = Timeline\CommentEntry::create([
225 'TYPE_ID' => Timeline\TimelineType::COMMENT,
226 'AUTHOR_ID' => $authorId,
227 'TEXT' => $text,
228 'SETTINGS' => [],
229 'BINDINGS' => [
230 [
231 'ENTITY_TYPE_ID' => $facility->getRegisteredTypeId(),
232 'ENTITY_ID' => $facility->getRegisteredId(),
233 'IS_FIXED' => true
234 ]
235 ],
236 'ASSOCIATED_ENTITY_TYPE_ID' => $facility->getRegisteredTypeId(),
237 'ASSOCIATED_ENTITY_ID' => $facility->getRegisteredId()
238 ]);
239
240 return $commentId > 0;
241 }
242
248 public function end()
249 {
250 if ($this->responsibleQueue)
251 {
252 $this->responsibleQueue->save();
253 }
254 }
255
256 protected function detectDealCategoryId($categoryId, EntityManageFacility $facility)
257 {
258 if ($facility->canAddDeal() && !is_numeric($categoryId))
259 {
260 // retrieve category from last deal if it configured.
261 $categoryId = $this->getLastDealCategoryId($facility);
262 }
263
264 $categoryId = (int) $categoryId;
265 $categories = array_map(
266 function ($category)
267 {
268 return (int) $category['ID'];
269 },
270 DealCategory::getAll(true)
271 );
272
273 if (!in_array($categoryId, $categories))
274 {
275 $categoryId = $categories[0];
276 }
277
278 return $categoryId;
279 }
280
281 protected function getLastDealCategoryId(EntityManageFacility $facility)
282 {
283 $categoryId = null;
284 $categoryFilters = [];
285 if ($facility->getSelector()->getCompanyId())
286 {
287 $categoryFilters[] = [
288 '=COMPANY_ID' => $facility->getSelector()->getCompanyId()
289 ];
290 }
291 if ($facility->getSelector()->getContactId())
292 {
293 $categoryFilters[] = [
294 '=CONTACT_ID' => $facility->getSelector()->getContactId()
295 ];
296 }
297 foreach ($categoryFilters as $categoryFilter)
298 {
299 $categoryFilter['=STAGE_SEMANTIC_ID'] = [
300 PhaseSemantics::PROCESS,
301 PhaseSemantics::SUCCESS
302 ];
303 $dealRow = DealTable::getRow([
304 'select' => ['CATEGORY_ID'],
305 'filter' => $categoryFilter,
306 'limit' => 1,
307 'order' => ['DATE_CREATE' => 'DESC']
308 ]);
309
310 if (!$dealRow)
311 {
312 break;
313 }
314 $categoryId = $dealRow['CATEGORY_ID'];
315 }
316
317 return $categoryId;
318 }
319
320 protected function getLastDeal(EntityManageFacility $facility, $days)
321 {
322 $categoryId = null;
323 $dealFilters = [];
324 if ($facility->getSelector()->getCompanyId())
325 {
326 $dealFilters[] = [
327 '=COMPANY_ID' => $facility->getSelector()->getCompanyId()
328 ];
329 }
330 if ($facility->getSelector()->getContactId())
331 {
332 $dealFilters[] = [
333 '=CONTACT_ID' => $facility->getSelector()->getContactId()
334 ];
335 }
336 foreach ($dealFilters as $dealFilter)
337 {
338 $dealFilter['=STAGE_SEMANTIC_ID'] = [
339 PhaseSemantics::SUCCESS
340 ];
341 $days = (int) $days;
342
343 $dateCreate = (new \DateTime())->modify("-$days days");
344
345 $beginningOfTheDay = DateTime::createFromPhp($dateCreate->setTime(0,0,0));
346 $endOfTheDay = DateTime::createFromPhp($dateCreate->setTime(23,59,59));
347
348 $dealFilter['<DATE_CREATE'] = $endOfTheDay;
349 $dealFilter['>DATE_CREATE'] = $beginningOfTheDay;
350
351 $dealFilter['=HAS_PRODUCTS'] = 1;
352
353 $dealRow = DealTable::getRow([
354 'select' => ['ID', 'CURRENCY_ID', 'RECEIVED_AMOUNT'],
355 'filter' => $dealFilter,
356 'limit' => 1,
357 'order' => ['DATE_CREATE' => 'DESC']
358 ]);
359
360 if (!$dealRow)
361 {
362 break;
363 }
364
365 return $dealRow;
366 }
367
368 return null;
369 }
370
371 protected function getOrderData($dealId)
372 {
373 $dbRes = \Bitrix\Crm\Order\EntityBinding::getList([
374 'select' => ['PAYMENT_ID' => 'ORDER.PAYMENT.ID', 'PAYMENT_ORDER_ID' => 'ORDER.PAYMENT.ORDER_ID'],
375 'filter' => [
376 'OWNER_ID' => $dealId,
377 'OWNER_TYPE_ID' => \CCrmOwnerType::Deal,
378 '!ORDER.PAYMENT.PS_RECURRING_TOKEN' => '',
379 '=ORDER.PAYMENT.PAID' => 'Y',
380 ],
381 'order' => ['ORDER.PAYMENT.ID' => 'DESC']
382 ]);
383
384 return $dbRes->fetch();
385 }
386
387 protected function copyDealProducts($fromDealId, $toDealId)
388 {
389
390 $productRows = \CCrmDeal::LoadProductRows($fromDealId);
391
392 foreach($productRows as &$productRow)
393 {
394 $productRow['ID'] = 0;
395 }
396
397 \CCrmDeal::SaveProductRows($toDealId, $productRows, false);
398 }
399
400 protected function copyOrder($formDealId, $toDealId)
401 {
402 if ($data = $this->getOrderData($formDealId))
403 {
404 $registry = \Bitrix\Sale\Registry::getInstance( \Bitrix\Sale\Registry::REGISTRY_TYPE_ORDER);
405 $orderClassName = $registry->getOrderClassName();
406
408 $order = $orderClassName::load($data['PAYMENT_ORDER_ID']);
409 if ($order)
410 {
412 $newOrder = $orderClassName::create($order->getSiteId(), $order->getUserId(), $order->getCurrency());
413
415 $basketClassName = $registry->getBasketClassName();
416
417 $newBasket = $basketClassName::create($order->getSiteId());
419 foreach ($order->getBasket() as $item)
420 {
421 $basketItem = $newBasket->createItem($item->getField('MODULE'), $item->getProductId());
422 $basketItem->setFields([
423 'PRODUCT_PROVIDER_CLASS' => $item->getField('PRODUCT_PROVIDER_CLASS'),
424 'QUANTITY' => $item->getQuantity(),
425 'CURRENCY' => $item->getCurrency(),
426 'BASE_PRICE' => $item->getBasePrice(),
427 'PRICE' => $item->getPrice(),
428 'CUSTOM_PRICE' => $item->isCustomPrice() ? 'Y' : 'N',
429
430 ]);
431 }
432
433 $newOrder->setBasket($newBasket);
434
436 $payment = $order->getPaymentCollection()->getItemById($data['PAYMENT_ID']);
437 if ($payment)
438 {
439 $newPayment = $newOrder->getPaymentCollection()->createItem();
440 $newPayment->setFields([
441 'PAY_SYSTEM_ID' => $payment->getPaymentSystemId(),
442 'PAY_SYSTEM_NAME' => $payment->getPaymentSystemName(),
443 'PS_RECURRING_TOKEN' => $payment->getField('PS_RECURRING_TOKEN'),
444 'SUM' => $payment->getSum(),
445 ]);
446 }
447
449 $newShipment = $newOrder->getShipmentCollection()->createItem();
450 foreach ($newBasket as $item)
451 {
452 $newShipmentItem = $newShipment->getShipmentItemCollection()->createItem($item);
453 $newShipmentItem->setQuantity($item->getQuantity());
454 }
455
456 $binding = $newOrder->createEntityBinding();
457 $binding->setField('OWNER_ID', $toDealId);
458 $binding->setField('OWNER_TYPE_ID', \CCrmOwnerType::Deal);
459
461 foreach ($order->getContactCompanyCollection()->getCompanies() as $item)
462 {
464 $newCompany = $newOrder->getContactCompanyCollection()->createCompany();
465 $newCompany->setField('ENTITY_ID', $item->getField('ENTITY_ID'));
466 $newCompany->setField('IS_PRIMARY', $item->getField('IS_PRIMARY'));
467 }
468
470 foreach ($order->getContactCompanyCollection()->getContacts() as $item)
471 {
473 $newContact = $newOrder->getContactCompanyCollection()->createContact();
474 $newContact->setField('ENTITY_ID', $item->getField('ENTITY_ID'));
475 $newContact->setField('IS_PRIMARY', $item->getField('IS_PRIMARY'));
476 }
477
478 $newOrder->refreshData();
479 $newOrder->doFinalAction();
480
481 $newOrder->save();
482 }
483 }
484 }
485
486 private function getAssignedWithCrmData(int $typeId, int $entityId): ?int
487 {
488 $factory = Container::getInstance()->getFactory($typeId);
489
490 if (!$factory)
491 {
492 return null;
493 }
494
495 $entity = $factory->getItem($entityId);
496 if ($entity)
497 {
498 $assignedId = (int)$entity->get('ASSIGNED_BY_ID');
499 if ($assignedId)
500 {
501 return $assignedId;
502 }
503 }
504
505 return null;
506 }
507}
static createFromPhp(\DateTime $datetime)
Definition datetime.php:232
getLastDeal(EntityManageFacility $facility, $days)
saveConfiguration(Message\Configuration $configuration)
detectDealCategoryId($categoryId, EntityManageFacility $facility)