17 private ?
int $compilationDealId;
23 public function run(array $fields)
25 $checkFieldsResult = $this->checkFields($fields);
26 if (!$checkFieldsResult->isSuccess())
28 $this->
addErrors($checkFieldsResult->getErrors());
32 $saveOrderResult = $this->saveOrder($fields);
33 if ($saveOrderResult->isSuccess())
35 $saveOrderData = $saveOrderResult->getData();
38 $order = $saveOrderData[
'ORDER'];
41 $user = $saveOrderData[
'USER'];
47 'HASH' => $order->getHash(),
52 $this->
addErrors($saveOrderResult->getErrors());
56 private function saveOrder(array $fields)
62 $prepareOrderResult = $this->prepareOrder($fields);
63 if ($prepareOrderResult->isSuccess())
65 $getOrderData = $prepareOrderResult->getData();
68 $order = $getOrderData[
'order'];
70 $setUserResult = $this->setUser($order, $fields);
71 if ($setUserResult->isSuccess())
73 $resultData[
'USER'] = $setUserResult->getData();
77 $this->fillErrorCollection(
79 $setUserResult->getErrors(),
85 $userProfileData = $fields[
'USER_PROFILE'] ??
null;
86 $setProfileResult = $this->setProfile($order, $userProfileData);
87 if (!$setProfileResult->isSuccess())
89 $this->fillErrorCollection(
91 $setProfileResult->getErrors(),
97 $doFinalActionsResult = $this->doFinalActions($order);
98 if (!$doFinalActionsResult->isSuccess())
100 $this->fillErrorCollection(
102 $doFinalActionsResult->getErrors(),
108 $saveResult = $order->save();
109 if (!$saveResult->isSuccess())
111 $this->fillErrorCollection(
113 $saveResult->getErrors(),
120 Main\Loader::includeModule(
'crm')
121 && class_exists(Crm\Integration\CompilationManager::class)
124 if (isset($this->compilationDealId))
126 Manager::copyOrderProductsToDeal($order, $this->compilationDealId);
129 Crm\Integration\CompilationManager::sendOrderBoundEvent($order);
130 Crm\Integration\CompilationManager::sendToCompilationDealTimeline($order);
133 $resultData[
'ORDER'] = $order;
134 $result->setData($resultData);
138 $result->addErrors($prepareOrderResult->getErrors());
144 private function checkFields(array $fields):
Sale\Result
148 if (empty($fields[
'SITE_ID']))
158 if (empty($fields[
'FUSER_ID']) || (
int)$fields[
'FUSER_ID'] <= 0)
168 if (empty($fields[
'PERSON_TYPE_ID']))
172 'personTypeId not found',
181 private function prepareOrder(array $fields):
Sale\Result
185 $order = $this->createOrder($fields[
'SITE_ID']);
187 $personTypeId = (int)$fields[
'PERSON_TYPE_ID'];
188 $setPersonTypeIdResult = $this->setPersonTypeId($order, $personTypeId);
189 if (!$setPersonTypeIdResult->isSuccess())
191 $this->fillErrorCollection(
193 $setPersonTypeIdResult->getErrors(),
199 if (!empty($fields[
'TRADING_PLATFORM_ID']))
201 $tradingPlatformId = $fields[
'TRADING_PLATFORM_ID'];
202 $setTradeBindingResult = $this->setTradeBinding($order, $tradingPlatformId);
203 if (!$setTradeBindingResult->isSuccess())
205 $this->fillErrorCollection(
207 $setTradeBindingResult->getErrors(),
214 $properties = $fields[
'PROPERTIES'] ??
null;
217 $setPropertiesResult = $this->setProperties($order, $properties);
218 if (!$setPropertiesResult->isSuccess())
220 $this->fillErrorCollection(
222 $setPropertiesResult->getErrors(),
229 $setBasketResult = $this->setBasket($order, $fields[
'FUSER_ID']);
230 if (!$setBasketResult->isSuccess())
232 $this->fillErrorCollection(
234 $setBasketResult->getErrors(),
241 Main\Loader::includeModule(
'crm')
242 && class_exists(Crm\Integration\CompilationManager::class)
245 $this->compilationDealId = Crm\Integration\CompilationManager::processOrderForCompilation($order);
248 $result->setData([
'order' => $order]);
252 private function createOrder(
string $siteId):
Sale\Order
256 $orderClassName = $registry->getOrderClassName();
258 return $orderClassName::create($siteId);
265 $setPersonTypeIdResult = $order->setPersonTypeId($personTypeId);
266 if (!$setPersonTypeIdResult->isSuccess())
268 $result->addErrors($setPersonTypeIdResult->getErrors());
278 $propertyCollection = $order->getPropertyCollection();
279 $setValuesResult = $propertyCollection->setValuesFromPost([
'PROPERTIES' => $properties], []);
280 if (!$setValuesResult->isSuccess())
282 foreach ($setValuesResult->getErrors() as $error)
284 $result->addError(
new Main\
Error($error->getMessage()));
289 foreach ($propertyCollection as $propValue)
291 if ($propValue->isUtil())
296 $verifyResult = $propValue->verify();
297 if (!$verifyResult->isSuccess())
299 foreach ($verifyResult->getErrors() as $error)
302 new Main\
Error($error->getMessage(), 0, [
'id' => $propValue->getPropertyId()])
307 $checkRequiredValueResult = $propValue->checkRequiredValue($propValue->getPropertyId(), $propValue->getValue());
308 if (!$checkRequiredValueResult->isSuccess())
310 foreach ($checkRequiredValueResult->getErrors() as $error)
313 new Main\
Error($error->getMessage(), 0, [
'id' => $propValue->getPropertyId()])
329 $basketClassName = $registry->getBasketClassName();
330 $basket = $basketClassName::loadItemsForFUser($fuserId, $order->getSiteId());
332 $refreshResult = $basket->refresh();
333 if ($refreshResult->isSuccess())
335 $saveBasketResult = $basket->save();
336 if (!$saveBasketResult->isSuccess())
338 $result->addErrors($refreshResult->getErrors());
343 $result->addErrors($refreshResult->getErrors());
346 if (!$result->isSuccess(
true))
351 $availableBasket = $basket->getOrderableItems();
352 if ($availableBasket && !$availableBasket->isEmpty())
354 $setBasketResult = $order->setBasket($availableBasket);
355 if (!$setBasketResult->isSuccess())
357 $result->addErrors($setBasketResult->getErrors());
360 elseif ($availableBasket)
362 $result->addError(
new Main\
Error(
'basket is empty'));
366 $result->addError(
new Main\
Error(
'basket is null'));
378 if ((
int)$fields[
'USER_ID'] > 0)
380 $userId = (int)$fields[
'USER_ID'];
382 if ($this->isLandingShop($order) && Main\Loader::includeModule(
'crm'))
384 Crm\Service\Sale\Order\BuyerService::getInstance()->attachUserToBuyers($userId);
392 foreach ($order->getPropertyCollection() as $property)
394 $properties[$property->getPropertyId()] = $property->getValue();
397 $userProps = Sale\Property::getMeaningfulValues($order->getPersonTypeId(), $properties);
399 $email = $userProps[
'EMAIL'] ??
'';
400 $phone = $userProps[
'PHONE'] ??
'';
402 $userId = $this->searchExistingUser($email, $phone);
405 $registerNewUserResult = $this->registerNewUser($order, $userProps);
406 if ($registerNewUserResult->isSuccess())
408 $registerNewUserData = $registerNewUserResult->getData();
409 $userId = $registerNewUserData[
'userId'];
415 $result->addErrors($registerNewUserResult->getErrors());
423 $result->addError(
new Main\
Error(
'User not found'));
427 $order->setFieldNoDemand(
'USER_ID', $userId);
431 'IS_NEW' => $isNewUser,
437 private function searchExistingUser(
string $email,
string $phone): ?
int
439 $existingUserId =
null;
443 $res = Main\UserTable::getRow([
450 if (isset($res[
'ID']))
452 $existingUserId = (int)$res[
'ID'];
456 if (!$existingUserId && !empty($phone))
458 $normalizedPhone = NormalizePhone($phone);
459 $normalizedPhoneForRegistration = Main\UserPhoneAuthTable::normalizePhoneNumber($phone);
461 if (!empty($normalizedPhone))
463 $res = Main\UserTable::getRow([
468 '=PHONE_AUTH.PHONE_NUMBER' => $normalizedPhoneForRegistration,
469 '=PERSONAL_PHONE' => $normalizedPhone,
470 '=PERSONAL_MOBILE' => $normalizedPhone,
475 if (isset($res[
'ID']))
477 $existingUserId = (int)$res[
'ID'];
482 return $existingUserId;
489 $siteId = $order->getSiteId();
491 $userData = $this->generateUserData($userProps);
493 'LOGIN' => $userData[
'NEW_LOGIN'],
494 'NAME' => $userData[
'NEW_NAME'],
495 'LAST_NAME' => $userData[
'NEW_LAST_NAME'],
496 'PASSWORD' => $userData[
'NEW_PASSWORD'],
497 'CONFIRM_PASSWORD' => $userData[
'NEW_PASSWORD_CONFIRM'],
498 'EMAIL' => $userData[
'NEW_EMAIL'],
499 'GROUP_ID' => $userData[
'GROUP_ID'],
502 'PERSONAL_PHONE' => isset($userProps[
'PHONE']) ? NormalizePhone($userProps[
'PHONE']) :
'',
503 'PERSONAL_ZIP' => $userProps[
'ZIP'] ??
'',
504 'PERSONAL_STREET' => $userProps[
'ADDRESS'] ??
'',
507 $userPhoneAuth = Main\Config\Option::get(
'main',
'new_user_phone_auth',
'N', $siteId) ===
'Y';
510 $normalizedPhoneForRegistration =
'';
511 if (!empty($userProps[
'PHONE']))
513 $normalizedPhoneForRegistration = Main\UserPhoneAuthTable::normalizePhoneNumber($userProps[
'PHONE']);
516 $fields[
'PHONE_NUMBER'] = $normalizedPhoneForRegistration;
519 if ($this->isLandingShop($order) && Main\Loader::includeModule(
'crm'))
521 $fields[
'GROUP_ID'] = Crm\Order\BuyerGroup::getDefaultGroups();
522 $fields[
'EXTERNAL_AUTH_ID'] =
'shop';
523 $fields[
'UF_DEPARTMENT'] = [];
524 if (!empty($userData[
'NEW_EMAIL']))
526 $fields[
'LOGIN'] = $userData[
'NEW_EMAIL'];
530 $user = new \CUser();
531 $addResult = $user->Add($fields);
532 if ((
int)$addResult <= 0)
534 $errors = explode(
'<br>', $user->LAST_ERROR);
535 TrimArr($errors,
true);
536 foreach ($errors as $error)
538 $result->addError(
new Main\
Error($error));
543 $result->setData([
'userId' => $addResult]);
549 private function generateUserData(array $userProps = []): array
551 $userEmail = isset($userProps[
'EMAIL']) ? trim((
string)$userProps[
'EMAIL']) :
'';
552 $newLogin = $userEmail;
554 if (empty($userEmail))
558 $normalizedPhone = NormalizePhone($userProps[
'PHONE']);
559 if (!empty($normalizedPhone))
561 $newLogin = $normalizedPhone;
566 $newEmail = $userEmail;
569 if (empty($newLogin))
571 $newLogin = Main\Security\Random::getString(5).random_int(0, 99999);
574 $pos = mb_strpos($newLogin,
'@');
577 $newLogin = mb_substr($newLogin, 0, $pos);
580 if (mb_strlen($newLogin) > 47)
582 $newLogin = mb_substr($newLogin, 0, 47);
585 $newLogin = str_pad($newLogin, 3,
'_');
587 $dbUserLogin = \CUser::GetByLogin($newLogin);
588 if ($userLoginResult = $dbUserLogin->Fetch())
592 $newLoginTmp = $newLogin.random_int(0, 99999);
593 $dbUserLogin = \CUser::GetByLogin($newLoginTmp);
595 while ($userLoginResult = $dbUserLogin->Fetch());
597 $newLogin = $newLoginTmp;
603 $payerName = isset($userProps[
'PAYER']) ? trim((
string)$userProps[
'PAYER']) :
'';
604 if (!empty($payerName))
606 $payerName = preg_replace(
'/\s{2,}/',
' ', $payerName);
607 $nameParts = explode(
' ', $payerName);
608 if (isset($nameParts[1]))
610 $newName = $nameParts[1];
611 $newLastName = $nameParts[0];
615 $newName = $nameParts[0];
621 $defaultGroups = Main\Config\Option::get(
'main',
'new_user_registration_def_group',
'');
622 if (!empty($defaultGroups))
624 $groupIds = explode(
',', $defaultGroups);
627 $newPassword = \CUser::GeneratePasswordByPolicy($groupIds);
630 'NEW_EMAIL' => $newEmail,
631 'NEW_LOGIN' => $newLogin,
632 'NEW_NAME' => $newName,
633 'NEW_LAST_NAME' => $newLastName,
634 'NEW_PASSWORD' => $newPassword,
635 'NEW_PASSWORD_CONFIRM' => $newPassword,
636 'GROUP_ID' => $groupIds,
644 $hasMeaningfulFields = $order->hasMeaningfulField();
645 $doFinalActionResult = $order->doFinalAction($hasMeaningfulFields);
647 if (!$doFinalActionResult->isSuccess())
649 $result->addErrors($doFinalActionResult->getErrors());
659 $platform = Sale\TradingPlatform\Manager::getList([
662 '=ID' => $tradingPlatformId,
667 $collection = $order->getTradeBindingCollection();
670 $binding = $collection->createItem();
671 $setFieldResult = $binding->setFields([
672 'TRADING_PLATFORM_ID' => $tradingPlatformId,
675 if (!$setFieldResult->isSuccess())
677 $result->addErrors($setFieldResult->getErrors());
683 new Main\
Error(
'Trading platform with id:"'.$tradingPlatformId.
' not found"')
694 $profileId = $profileFields[
'ID'] ?? 0;
695 $profileName = $profileFields[
'NAME'] ??
'';
699 foreach ($order->getPropertyCollection() as $property)
701 $properties[$property->getPropertyId()] = $property->getValue();
705 \CSaleOrderUserProps::DoSaveUserProfile(
709 $order->getPersonTypeId(),
714 foreach ($errors as $error)
716 $result->addError(
new Main\
Error($error[
'TEXT']));
722 private function isLandingShop(
Sale\
Order $order):
bool
725 foreach ($order->getTradeBindingCollection() as $tradingItem)
727 $platformId = $tradingItem->getField(
'TRADING_PLATFORM_ID');
728 $platform = Sale\TradingPlatform\Manager::getObjectById($platformId);
729 if ($platform instanceof
Sale\TradingPlatform\Landing\Landing)
743 private function fillErrorCollection(
Sale\
Result $result, array $errors, $code):
void
745 foreach ($errors as $error)
747 $result->addError(
new Main\
Error($error->getMessage(), $code, $error->getCustomData()));