- Модуль: sale
- Путь к файлу: ~/bitrix/modules/sale/lib/helpers/admin/orderedit.php
- Класс: BitrixSaleHelpersAdminOrderEdit
- Вызов: OrderEdit::createOrderFromForm
static function createOrderFromForm(array $formData, $creatorUserId, $createUserIfNeed, array $files, Result &$opResult)
{
if(!isset($formData["SITE_ID"]) || $formData["SITE_ID"] == '')
throw new ArgumentNullException('formData["SITE_ID"]');
$registry = SaleRegistry::getInstance(SaleRegistry::REGISTRY_TYPE_ORDER);
/** @var SaleOrder $orderClass */
$orderClass = $registry->getOrderClassName();
global $APPLICATION, $USER;
$order = $orderClass::create($formData["SITE_ID"]);
$saleModulePermissions = $APPLICATION->GetGroupRight("sale");
$userCompanyId = null;
if($saleModulePermissions == "P")
{
$userCompanyList = CompanyManager::getUserCompanyList($USER->GetID());
if (!empty($userCompanyList) && is_array($userCompanyList))
{
$userCompanyId = reset($userCompanyList);
if (intval($userCompanyId) > 0 && empty($formData['ORDER']['COMPANY_ID']))
{
$formData['ORDER']['COMPANY_ID'] = $userCompanyId;
}
}
}
/** @var BitrixSaleResult $res */
$res = self::fillSimpleFields($order, $formData, $creatorUserId);
if(!$res->isSuccess())
$opResult->addErrors($res->getErrors());
$res = self::fillOrderProperties($order, $formData, $files);
if(!$res->isSuccess())
$opResult->addErrors($res->getErrors());
//creates new user if need
$order->setFieldNoDemand(
"USER_ID",
self::getUserId($order, $formData, $createUserIfNeed, $opResult)
);
$fUserId = null;
if ($order->getUserId() > 0)
{
$fUserId = Fuser::getIdByUserId($order->getUserId());
}
$needDataUpdate = array();
$basketCodeMap = array();
//init basket
if(isset($formData["PRODUCT"]) && is_array($formData["PRODUCT"]) && !empty($formData["PRODUCT"]))
{
$isStartField = $order->isStartField();
$basketClass = $registry->getBasketClassName();
/** @var Basket $basket */
$basket = $basketClass::create($formData["SITE_ID"]);
$res = $order->setBasket($basket);
if(!$res->isSuccess())
$opResult->addErrors($res->getErrors());
$basket->setFUserId($fUserId);
BitrixSaleProviderBase::setUsingTrustData(true);
$sort = 100;
$maxBasketCodeIdx = 0;
foreach($formData["PRODUCT"] as $basketCode => $productData)
{
$formData["PRODUCT"][$basketCode]["SORT"] = $sort;
$sort += 100;
/* Fix collision if price of new product is larger than exists have.
* After sorting new product pick basket code from existing products.
* See below.
*/
if(self::isBasketItemNew($basketCode))
{
$basketInternalId = intval(mb_substr($basketCode, 1));
if($basketInternalId > $maxBasketCodeIdx)
$maxBasketCodeIdx = $basketInternalId;
if(self::$needUpdateNewProductPrice)
{
unset($formData["PRODUCT"][$basketCode]["PROVIDER_DATA"]);
unset($formData["PRODUCT"][$basketCode]["SET_ITEMS_DATA"]);
}
}
}
sortByColumn($formData["PRODUCT"], array("BASE_PRICE" => SORT_DESC, "PRICE" => SORT_DESC), '', null, true);
foreach($formData["PRODUCT"] as $basketCode => $productData)
{
if (($productData['IS_SET_ITEM'] ?? null) === 'Y')
{
continue;
}
if(!isset($productData["PROPS"]) || !is_array($productData["PROPS"]))
{
$productData["PROPS"] = array();
}
// Always search only by $basketCode so that can add duplicates
$item =
$basketCode != self::BASKET_CODE_NEW
? $basket->getItemByBasketCode($basketCode)
: null
;
if($item == null && $basketCode != self::BASKET_CODE_NEW)
{
$item = $basket->getItemByBasketCode($basketCode);
}
if($item && $item->isBundleChild())
{
$item = null;
}
if($item)
{
//Let's extract cached provider product data from field
if(!empty($productData["PROVIDER_DATA"]) && CheckSerializedData($productData["PROVIDER_DATA"]))
{
$providerData = unserialize($productData["PROVIDER_DATA"], ['allowed_classes' => false]);
self::setProviderTrustData($item, $order, $providerData);
}
if(!empty($productData["SET_ITEMS_DATA"]) && CheckSerializedData($productData["SET_ITEMS_DATA"]))
$productData["SET_ITEMS"] = unserialize($productData["SET_ITEMS_DATA"], ['allowed_classes' => false]);
$res = $item->setField("QUANTITY", $item->getField("QUANTITY")+$productData["QUANTITY"]);
if(!$res->isSuccess())
$opResult->addErrors($res->getErrors());
}
else
{
if($basketCode != self::BASKET_CODE_NEW)
$setBasketCode = $basketCode;
elseif(intval($maxBasketCodeIdx) > 0)
$setBasketCode = 'n'.strval($maxBasketCodeIdx+1); //Fix collision part 2.
else
$setBasketCode = null;
$productId = $productData["PRODUCT_ID"];
if (isset($productData["OFFER_ID"]) && !empty($productData["OFFER_ID"]))
{
$productId = $productData["OFFER_ID"];
}
$item = $basket->createItem($productData["MODULE"], $productId, $setBasketCode);
if ($basketCode != $productData["BASKET_CODE"])
$productData["BASKET_CODE"] = $item->getBasketCode();
if($basketCode == self::BASKET_CODE_NEW)
{
$opResult->setData(array("NEW_ITEM_BASKET_CODE" => $productData["BASKET_CODE"]));
$needDataUpdate[] = $item->getBasketCode();
}
if(!empty($productData['REPLACED']) && $productData['REPLACED'] == 'Y')
$needDataUpdate[] = $item->getBasketCode();
if($basketCode != $item->getBasketCode())
$basketCodeMap[$basketCode] = $item->getBasketCode();
if(isset($productData["PROPS"]) && !empty($productData["PROPS"]) && is_array($productData["PROPS"]))
{
/** @var BitrixSaleBasketPropertiesCollection $property */
$property = $item->getPropertyCollection();
$property->setProperty($productData["PROPS"]);
}
}
}
$productsData = $formData["PRODUCT"];
if(!empty($basketCodeMap))
{
foreach($basketCodeMap as $old => $new)
{
$productsData[$new] = $productsData[$old];
unset($productsData[$old]);
}
}
$res = self::fillBasketItems($basket, $productsData, $order, array_unique($needDataUpdate));
if(!$res->isSuccess())
{
$opResult->addErrors($res->getErrors());
if($res->isTerminal())
{
return null;
}
}
if ($isStartField)
{
$hasMeaningfulFields = $order->hasMeaningfulField();
/** @var Result $r */
$r = $order->doFinalAction($hasMeaningfulFields);
if (!$r->isSuccess())
{
$opResult->addErrors($r->getErrors());
}
}
if(isset($formData["DISCOUNTS"]) && is_array($formData["DISCOUNTS"]))
$order->getDiscount()->setApplyResult($formData["DISCOUNTS"]);
}
else
{
$opResult->addError(new EntityError(Loc::getMessage("SALE_ORDEREDIT_ERROR_NO_PRODUCTS")));
}
return $order;
}