function CalculateAffiliate($affiliate, $dateFrom = false, $dateTo = false, $datePlanFrom = false, $datePlanTo = false) { global $DB; // Prepare function params - affiliate $arAffiliate = CSaleAffiliate::CheckAffiliateFunc($affiliate); if (!$arAffiliate) { return False; } $db_events = GetModuleEvents("sale", "OnBeforeAffiliateCalculate"); while ($arEvent = $db_events->Fetch()) { if (ExecuteModuleEventEx($arEvent, array(&$arAffiliate, &$dateFrom, &$dateTo, &$datePlanFrom, &$datePlanTo)) === false) { return false; } } $affiliateID = IntVal($arAffiliate["ID"]); if (!$dateFrom || StrLen($dateFrom) <= 0) { if (StrLen($arAffiliate["LAST_CALCULATE"]) > 0) { $dateFrom = $arAffiliate["LAST_CALCULATE"]; } else { $dateFrom = date($DB->DateFormatToPHP(CSite::GetDateFormat("FULL")), mktime(0, 0, 0, 1, 1, 1990)); } } if (!$dateTo || StrLen($dateTo) <= 0) { $dateTo = date($DB->DateFormatToPHP(CSite::GetDateFormat("FULL")), time() + CTimeZone::GetOffset()); } // Get affiliate plan $arAffiliatePlan = CSaleAffiliate::SetAffiliatePlan($arAffiliate, $datePlanFrom, $datePlanTo); if (!$arAffiliatePlan) { return False; } if ($arAffiliatePlan && !is_array($arAffiliatePlan)) { return true; } // Get affiliate plan params $arPlanSections = array(); $dbPlanSection = CSaleAffiliatePlanSection::GetList(array(), array("PLAN_ID" => $arAffiliate["PLAN_ID"]), false, false, array("ID", "MODULE_ID", "SECTION_ID", "RATE", "RATE_TYPE", "RATE_CURRENCY")); while ($arPlanSection = $dbPlanSection->Fetch()) { $arPlanSections[$arPlanSection["MODULE_ID"] . $arPlanSection["SECTION_ID"]] = $arPlanSection; } // Get affiliate parents $arAffiliateParents = array(); $affiliateParent = IntVal($arAffiliate["AFFILIATE_ID"]); $count = 0; while ($affiliateParent > 0 && $count < 5) { $dbAffiliateParent = CSaleAffiliate::GetList(array(), array("ID" => $affiliateParent, "ACTIVE" => "Y"), false, false, array("ID", "AFFILIATE_ID")); if ($arAffiliateParent = $dbAffiliateParent->Fetch()) { $count++; $arAffiliateParents[] = $affiliateParent; $affiliateParent = IntVal($arAffiliateParent["AFFILIATE_ID"]); } else { $affiliateParent = 0; } } // Get tier if (!array_key_exists("SALE_AFFILIATE_TIER_TMP_CACHE", $GLOBALS)) { $GLOBALS["SALE_AFFILIATE_TIER_TMP_CACHE"] = array(); } if (!array_key_exists($arAffiliate["SITE_ID"], $GLOBALS["SALE_AFFILIATE_TIER_TMP_CACHE"])) { $dbAffiliateTier = CSaleAffiliateTier::GetList(array(), array("SITE_ID" => $arAffiliate["SITE_ID"]), false, false, array("RATE1", "RATE2", "RATE3", "RATE4", "RATE5")); if ($arAffiliateTier = $dbAffiliateTier->Fetch()) { $GLOBALS["SALE_AFFILIATE_TIER_TMP_CACHE"][$arAffiliate["SITE_ID"]] = array(DoubleVal($arAffiliateTier["RATE1"]), DoubleVal($arAffiliateTier["RATE2"]), DoubleVal($arAffiliateTier["RATE3"]), DoubleVal($arAffiliateTier["RATE4"]), DoubleVal($arAffiliateTier["RATE5"])); } else { $GLOBALS["SALE_AFFILIATE_TIER_TMP_CACHE"][$arAffiliate["SITE_ID"]] = array(0, 0, 0, 0, 0); } } // Orders cicle $affiliateSum = 0; $affiliateCurrency = CSaleLang::GetLangCurrency($arAffiliate["SITE_ID"]); $dbOrders = \Bitrix\Sale\Internals\OrderTable::getList(array('filter' => array("=ALLOW_DELIVERY" => 'Y', ">=DATE_ALLOW_DELIVERY" => $dateFrom, "<DATE_ALLOW_DELIVERY" => $dateTo, "=AFFILIATE_ID" => $affiliateID, "=LID" => $arAffiliate["SITE_ID"], "=CANCELED" => 'N'), 'select' => array("ID", "LID", "PRICE_DELIVERY", "PRICE", "CURRENCY", "TAX_VALUE", "AFFILIATE_ID", "BASKET_QUANTITY" => 'BASKET.QUANTITY', "BASKET_PRODUCT_ID" => 'BASKET.PRODUCT_ID', "BASKET_MODULE" => 'BASKET.MODULE', "BASKET_PRICE" => 'BASKET.PRICE', "BASKET_CURRENCY" => 'BASKET.CURRENCY', "BASKET_DISCOUNT_PRICE" => 'BASKET.DISCOUNT_PRICE'), 'order' => array('ID' => 'ASC'))); $fOrderId = ""; while ($arOrder = $dbOrders->fetch()) { $arProductSections = array(); if (!array_key_exists("SALE_PRODUCT_SECTION_CACHE", $GLOBALS)) { $GLOBALS["SALE_PRODUCT_SECTION_CACHE"] = array(); } if (array_key_exists($arOrder["BASKET_MODULE"] . $arOrder["BASKET_PRODUCT_ID"], $GLOBALS["SALE_PRODUCT_SECTION_CACHE"])) { $arProductSections = $GLOBALS["SALE_PRODUCT_SECTION_CACHE"][$arOrder["BASKET_MODULE"] . $arOrder["BASKET_PRODUCT_ID"]]; unset($GLOBALS["SALE_PRODUCT_SECTION_CACHE"][$arOrder["BASKET_MODULE"] . $arOrder["BASKET_PRODUCT_ID"]]); $GLOBALS["SALE_PRODUCT_SECTION_CACHE"] = $GLOBALS["SALE_PRODUCT_SECTION_CACHE"] + array($arOrder["BASKET_MODULE"] . $arOrder["BASKET_PRODUCT_ID"] => $arProductSections); } else { if ($arOrder["BASKET_MODULE"] == "catalog") { CModule::IncludeModule("catalog"); $arSku = CCatalogSku::GetProductInfo($arOrder["BASKET_PRODUCT_ID"]); if ($arSku && count($arSku) > 0) { $elementId = $arSku["ID"]; } else { $elementId = $arOrder["BASKET_PRODUCT_ID"]; } $arProductSections = CCatalogProduct::GetProductSections($elementId); } else { $events = GetModuleEvents("sale", "OnAffiliateGetSections"); if ($arEvent = $events->Fetch()) { $arProductSections = ExecuteModuleEventEx($arEvent, array($arOrder["BASKET_MODULE"], $arOrder["BASKET_PRODUCT_ID"])); } } $GLOBALS["SALE_PRODUCT_SECTION_CACHE"] = $GLOBALS["SALE_PRODUCT_SECTION_CACHE"] + array($arOrder["BASKET_MODULE"] . $arOrder["BASKET_PRODUCT_ID"] => $arProductSections); if (count($GLOBALS["SALE_PRODUCT_SECTION_CACHE"]) > 20) { array_shift($GLOBALS["SALE_PRODUCT_SECTION_CACHE"]); } } $realRate = $arAffiliatePlan["BASE_RATE"]; $realRateType = $arAffiliatePlan["BASE_RATE_TYPE"]; $realRateCurrency = $arAffiliatePlan["BASE_RATE_CURRENCY"]; $coountArProd = count($arProductSections); for ($i = 0; $i < $coountArProd; $i++) { if (array_key_exists($arOrder["BASKET_MODULE"] . $arProductSections[$i], $arPlanSections)) { $realRate = $arPlanSections[$arOrder["BASKET_MODULE"] . $arProductSections[$i]]["RATE"]; $realRateType = $arPlanSections[$arOrder["BASKET_MODULE"] . $arProductSections[$i]]["RATE_TYPE"]; $realRateCurrency = $arPlanSections[$arOrder["BASKET_MODULE"] . $arProductSections[$i]]["RATE_CURRENCY"]; break; } } if ($realRateType == "P") { if ($arOrder["CURRENCY"] != $affiliateCurrency) { if (!array_key_exists("SALE_CONVERT_CURRENCY_CACHE", $GLOBALS)) { $GLOBALS["SALE_CONVERT_CURRENCY_CACHE"] = array(); } if (!array_key_exists($arOrder["CURRENCY"] . "-" . $affiliateCurrency, $GLOBALS["SALE_CONVERT_CURRENCY_CACHE"])) { $GLOBALS["SALE_CONVERT_CURRENCY_CACHE"][$arOrder["CURRENCY"] . "-" . $affiliateCurrency] = CCurrencyRates::GetConvertFactor($arOrder["CURRENCY"], $affiliateCurrency); } if ($fOrderId != $arOrder["ID"]) { $affiliateSum += \Bitrix\Sale\PriceMaths::roundPrecision(($arOrder["PRICE"] - $arOrder["PRICE_DELIVERY"]) * $GLOBALS["SALE_CONVERT_CURRENCY_CACHE"][$arOrder["CURRENCY"] . "-" . $affiliateCurrency] * $realRate / 100); $fOrderId = $arOrder["ID"]; } } else { if ($fOrderId != $arOrder["ID"]) { $affiliateSum += \Bitrix\Sale\PriceMaths::roundPrecision(($arOrder["PRICE"] - $arOrder["PRICE_DELIVERY"]) * $realRate / 100); $fOrderId = $arOrder["ID"]; } } } else { if ($realRateCurrency != $affiliateCurrency) { if (!array_key_exists("SALE_CONVERT_CURRENCY_CACHE", $GLOBALS)) { $GLOBALS["SALE_CONVERT_CURRENCY_CACHE"] = array(); } if (!array_key_exists($realRateCurrency . "-" . $affiliateCurrency, $GLOBALS["SALE_CONVERT_CURRENCY_CACHE"])) { $GLOBALS["SALE_CONVERT_CURRENCY_CACHE"][$realRateCurrency . "-" . $affiliateCurrency] = CCurrencyRates::GetConvertFactor($realRateCurrency, $affiliateCurrency); } $affiliateSum += roundEx($realRate * $GLOBALS["SALE_CONVERT_CURRENCY_CACHE"][$realRateCurrency . "-" . $affiliateCurrency], SALE_VALUE_PRECISION); } else { $affiliateSum += roundEx($realRate, SALE_VALUE_PRECISION); } } } $arFields = array("=PENDING_SUM" => "PENDING_SUM + " . $affiliateSum, "LAST_CALCULATE" => $dateTo); $res = CSaleAffiliate::Update($affiliateID, $arFields); if (!$res) { return False; } if ($affiliateSum > 0) { $cnt = min(count($arAffiliateParents), count($GLOBALS["SALE_AFFILIATE_TIER_TMP_CACHE"][$arAffiliate["SITE_ID"]])); for ($i = 0; $i < $cnt; $i++) { $affiliateSumTmp = roundEx($affiliateSum * $GLOBALS["SALE_AFFILIATE_TIER_TMP_CACHE"][$arAffiliate["SITE_ID"]][$i] / 100, SALE_VALUE_PRECISION); $arFields = array("=PENDING_SUM" => "PENDING_SUM + " . $affiliateSumTmp); CSaleAffiliate::Update($arAffiliateParents[$i], $arFields); } } $events = GetModuleEvents("sale", "OnAfterAffiliateCalculate"); while ($arEvent = $events->Fetch()) { ExecuteModuleEventEx($arEvent, array($affiliateID)); } return True; }