PageRenderTime 47ms CodeModel.GetById 13ms RepoModel.GetById 0ms app.codeStats 0ms

/modules/sale/general/affiliate.php

https://gitlab.com/alexprowars/bitrix
PHP | 904 lines | 770 code | 121 blank | 13 comment | 170 complexity | c4a7f88f5ac52744a8b31e30db0efcff MD5 | raw file
  1. <?php
  2. IncludeModuleLangFile(__FILE__);
  3. $GLOBALS["SALE_AFFILIATE"] = Array();
  4. $GLOBALS["SALE_AFFILIATE_TIER_TMP_CACHE"] = Array();
  5. $GLOBALS["SALE_PRODUCT_SECTION_CACHE"] = Array();
  6. $GLOBALS["BASE_LANG_CURRENCIES"] = array();
  7. $GLOBALS["SALE_CONVERT_CURRENCY_CACHE"] = array();
  8. class CAllSaleAffiliate
  9. {
  10. public static function CheckFields($ACTION, &$arFields, $ID = 0)
  11. {
  12. if ((is_set($arFields, "SITE_ID") || $ACTION=="ADD") && $arFields["SITE_ID"] == '')
  13. {
  14. $GLOBALS["APPLICATION"]->ThrowException(GetMessage("ACGA1_NO_SITE"), "EMPTY_SITE_ID");
  15. return false;
  16. }
  17. if ((is_set($arFields, "USER_ID") || $ACTION=="ADD") && intval($arFields["USER_ID"]) <= 0)
  18. {
  19. $GLOBALS["APPLICATION"]->ThrowException(GetMessage("ACGA1_NO_USER"), "EMPTY_USER_ID");
  20. return false;
  21. }
  22. if (is_set($arFields, "USER_ID"))
  23. {
  24. $dbUser = CUser::GetByID($arFields["USER_ID"]);
  25. if (!$dbUser->Fetch())
  26. {
  27. $GLOBALS["APPLICATION"]->ThrowException(str_replace("#ID#", $arFields["USER_ID"], GetMessage("SKGU_NO_USER")), "ERROR_NO_USER_ID");
  28. return false;
  29. }
  30. }
  31. if ((is_set($arFields, "PLAN_ID") || $ACTION=="ADD") && intval($arFields["PLAN_ID"]) <= 0)
  32. {
  33. $GLOBALS["APPLICATION"]->ThrowException(GetMessage("ACGA1_NO_PLAN"), "EMPTY_PLAN_ID");
  34. return false;
  35. }
  36. $ID = intval($ID);
  37. $arAffiliate = false;
  38. if ($ACTION != "ADD")
  39. {
  40. if ($ID <= 0)
  41. {
  42. $GLOBALS["APPLICATION"]->ThrowException(GetMessage("ACGA1_ERROR_FUNC"), "FUNCTION_ERROR");
  43. return false;
  44. }
  45. else
  46. {
  47. $arAffiliate = CSaleAffiliate::GetByID($ID);
  48. if (!$arAffiliate)
  49. {
  50. $GLOBALS["APPLICATION"]->ThrowException(str_replace("#ID#", $ID, GetMessage("ACGA1_NO_AFFILIATE")), "NO_AFFILIATE");
  51. return false;
  52. }
  53. }
  54. }
  55. if (is_set($arFields, "AFFILIATE_ID") && intval($arFields["AFFILIATE_ID"]) <= 0)
  56. $arFields["AFFILIATE_ID"] = false;
  57. if ((is_set($arFields, "ACTIVE") || $ACTION=="ADD") && $arFields["ACTIVE"] != "Y")
  58. $arFields["ACTIVE"] = "N";
  59. if ((is_set($arFields, "FIX_PLAN") || $ACTION=="ADD") && $arFields["FIX_PLAN"] != "Y")
  60. $arFields["FIX_PLAN"] = "N";
  61. if ((is_set($arFields, "DATE_CREATE") || $ACTION=="ADD") && (!$GLOBALS["DB"]->IsDate($arFields["DATE_CREATE"], false, LANG, "FULL")))
  62. {
  63. $GLOBALS["APPLICATION"]->ThrowException(GetMessage("ACGA1_BAD_DATE"), "ERROR_DATE_CREATE");
  64. return false;
  65. }
  66. if (is_set($arFields, "PAID_SUM"))
  67. {
  68. $arFields["PAID_SUM"] = str_replace(",", ".", $arFields["PAID_SUM"]);
  69. $arFields["PAID_SUM"] = DoubleVal($arFields["PAID_SUM"]);
  70. }
  71. if (is_set($arFields, "APPROVED_SUM"))
  72. {
  73. $arFields["APPROVED_SUM"] = str_replace(",", ".", $arFields["APPROVED_SUM"]);
  74. $arFields["APPROVED_SUM"] = DoubleVal($arFields["APPROVED_SUM"]);
  75. }
  76. if (is_set($arFields, "PENDING_SUM"))
  77. {
  78. $arFields["PENDING_SUM"] = str_replace(",", ".", $arFields["PENDING_SUM"]);
  79. $arFields["PENDING_SUM"] = DoubleVal($arFields["PENDING_SUM"]);
  80. }
  81. if (is_set($arFields, "ITEMS_NUMBER"))
  82. $arFields["ITEMS_NUMBER"] = intval($arFields["ITEMS_NUMBER"]);
  83. if (is_set($arFields, "ITEMS_SUM"))
  84. {
  85. $arFields["ITEMS_SUM"] = str_replace(",", ".", $arFields["ITEMS_SUM"]);
  86. $arFields["ITEMS_SUM"] = DoubleVal($arFields["ITEMS_SUM"]);
  87. }
  88. return True;
  89. }
  90. public static function Delete($ID)
  91. {
  92. global $DB;
  93. $ID = intval($ID);
  94. $db_events = GetModuleEvents("sale", "OnBeforeAffiliateDelete");
  95. while ($arEvent = $db_events->Fetch())
  96. if (ExecuteModuleEventEx($arEvent, Array($ID))===false)
  97. return false;
  98. if ($ID <= 0)
  99. return False;
  100. if(!(CSaleAffiliateTransact::OnAffiliateDelete($ID)))
  101. return false;
  102. unset($GLOBALS["SALE_AFFILIATE"]["SALE_AFFILIATE_CACHE_".$ID]);
  103. $bResult = $DB->Query("DELETE FROM b_sale_affiliate WHERE ID = ".$ID." ", true);
  104. $events = GetModuleEvents("sale", "OnAfterAffiliateDelete");
  105. while ($arEvent = $events->Fetch())
  106. ExecuteModuleEventEx($arEvent, Array($ID, $bResult));
  107. return $bResult;
  108. }
  109. public static function GetByID($ID)
  110. {
  111. global $DB;
  112. $ID = intval($ID);
  113. if ($ID <= 0)
  114. return false;
  115. if (isset($GLOBALS["SALE_AFFILIATE"]["SALE_AFFILIATE_CACHE_".$ID]) && is_array($GLOBALS["SALE_AFFILIATE"]["SALE_AFFILIATE_CACHE_".$ID]))
  116. {
  117. return $GLOBALS["SALE_AFFILIATE"]["SALE_AFFILIATE_CACHE_".$ID];
  118. }
  119. else
  120. {
  121. $strSql =
  122. "SELECT A.ID, A.SITE_ID, A.USER_ID, A.AFFILIATE_ID, A.PLAN_ID, A.ACTIVE, A.PAID_SUM, ".
  123. " A.APPROVED_SUM, A.PENDING_SUM, A.ITEMS_NUMBER, A.ITEMS_SUM, A.AFF_SITE, A.AFF_DESCRIPTION, A.FIX_PLAN, ".
  124. " ".$DB->DateToCharFunction("A.TIMESTAMP_X", "FULL")." as TIMESTAMP_X, ".
  125. " ".$DB->DateToCharFunction("A.DATE_CREATE", "FULL")." as DATE_CREATE, ".
  126. " ".$DB->DateToCharFunction("A.LAST_CALCULATE", "FULL")." as LAST_CALCULATE ".
  127. "FROM b_sale_affiliate A ".
  128. "WHERE A.ID = ".$ID." ";
  129. $db_res = $DB->Query($strSql, false, "File: ".__FILE__."<br>Line: ".__LINE__);
  130. if ($res = $db_res->Fetch())
  131. {
  132. $GLOBALS["SALE_AFFILIATE"]["SALE_AFFILIATE_CACHE_".$ID] = $res;
  133. return $GLOBALS["SALE_AFFILIATE"]["SALE_AFFILIATE_CACHE_".$ID];
  134. }
  135. }
  136. return false;
  137. }
  138. public static function GetAffiliate($affiliateID = 0)
  139. {
  140. $affiliateID = intval($affiliateID);
  141. if ($affiliateID <= 0)
  142. {
  143. $affiliateParam = COption::GetOptionString("sale", "affiliate_param_name", "partner");
  144. if ($affiliateParam <> '' && array_key_exists($affiliateParam, $_GET))
  145. $affiliateID = intval($_GET[$affiliateParam]);
  146. }
  147. if ($affiliateID <= 0)
  148. if (array_key_exists("SALE_AFFILIATE", $_SESSION))
  149. $affiliateID = intval($_SESSION["SALE_AFFILIATE"]);
  150. if ($affiliateID <= 0)
  151. {
  152. $cookieName = COption::GetOptionString("main", "cookie_name", "BITRIX_SM");
  153. $affiliateID = intval($_COOKIE[$cookieName."_SALE_AFFILIATE"]);
  154. }
  155. if ($affiliateID > 0)
  156. {
  157. $_SESSION["SALE_AFFILIATE"] = $affiliateID;
  158. $cookieTime = intval(COption::GetOptionString("sale", "affiliate_life_time", "0"));
  159. $secure = false;
  160. if(COption::GetOptionString("sale", "use_secure_cookies", "N") == "Y" && CMain::IsHTTPS())
  161. $secure=1;
  162. $GLOBALS["APPLICATION"]->set_cookie("SALE_AFFILIATE", $affiliateID, (($cookieTime <= 0) ? 0 : time() + $cookieTime * 24 * 60 * 60), "/", false, $secure, "Y", false);
  163. }
  164. return $affiliateID;
  165. }
  166. public static function Calculate($dateFrom = false, $dateTo = false, $datePlanFrom = false, $datePlanTo = false)
  167. {
  168. global $DB;
  169. $arFilter = array(
  170. "ACTIVE" => "Y",
  171. "ORDER_ALLOW_DELIVERY" => "Y"
  172. );
  173. if (!$dateFrom || $dateFrom == '')
  174. {
  175. if (!$dateTo || $dateTo == '')
  176. $dateTo = date($DB->DateFormatToPHP(CSite::GetDateFormat("FULL")), time()+CTimeZone::GetOffset());
  177. $arFilter[">=ORDER_DATE_ALLOW_DELIVERY"] = $dateFrom;
  178. $arFilter["<ORDER_DATE_ALLOW_DELIVERY"] = $dateTo;
  179. }
  180. else
  181. {
  182. $dateTo = false;
  183. }
  184. if (!$datePlanFrom || $datePlanFrom == '')
  185. $datePlanFrom = $dateFrom;
  186. if (!$datePlanTo || $datePlanTo == '')
  187. $datePlanTo = $dateTo;
  188. $dbAffiliates = CSaleAffiliate::GetList(
  189. array(),
  190. $arFilter,
  191. array(
  192. "ID",
  193. "SITE_ID",
  194. "USER_ID",
  195. "AFFILIATE_ID",
  196. "PLAN_ID",
  197. "ACTIVE",
  198. "TIMESTAMP_X",
  199. "DATE_CREATE",
  200. "PAID_SUM",
  201. "APPROVED_SUM",
  202. "PENDING_SUM",
  203. "ITEMS_NUMBER",
  204. "ITEMS_SUM",
  205. "FIX_PLAN",
  206. "MAX" => "ORDER_ID"
  207. )
  208. );
  209. while ($arAffiliates = $dbAffiliates->Fetch())
  210. CSaleAffiliate::CalculateAffiliate($arAffiliates, $dateFrom, $dateTo, $datePlanFrom, $datePlanTo);
  211. }
  212. public static function CheckAffiliateFunc($affiliate)
  213. {
  214. if (is_array($affiliate))
  215. {
  216. $arAffiliate = $affiliate;
  217. $affiliateID = intval($arAffiliate["ID"]);
  218. if ($affiliateID <= 0)
  219. {
  220. $GLOBALS["APPLICATION"]->ThrowException(GetMessage("ACGA1_ERROR_FUNC"), "FUNCTION_ERROR");
  221. return false;
  222. }
  223. }
  224. else
  225. {
  226. $affiliateID = intval($affiliate);
  227. if ($affiliateID <= 0)
  228. return False;
  229. $dbAffiliate = CSaleAffiliate::GetList(
  230. array(),
  231. array("ID" => $affiliateID, "ACTIVE" => "Y", "PLAN_ACTIVE" => "Y"),
  232. false,
  233. false,
  234. array("ID", "SITE_ID", "USER_ID", "AFFILIATE_ID", "PLAN_ID", "ACTIVE", "TIMESTAMP_X", "DATE_CREATE", "PAID_SUM", "APPROVED_SUM", "PENDING_SUM", "ITEMS_NUMBER", "ITEMS_SUM", "LAST_CALCULATE", "FIX_PLAN", "PLAN_BASE_RATE", "PLAN_BASE_RATE_TYPE", "PLAN_BASE_RATE_CURRENCY")
  235. );
  236. $arAffiliate = $dbAffiliate->Fetch();
  237. if (!$arAffiliate)
  238. {
  239. $GLOBALS["APPLICATION"]->ThrowException(str_replace("#ID#", $affiliateID, GetMessage("ACGA1_NO_AFFILIATE")), "NO_AFFILIATE");
  240. return false;
  241. }
  242. }
  243. return $arAffiliate;
  244. }
  245. public static function SetAffiliatePlan($affiliate, $dateFrom = false, $dateTo = false)
  246. {
  247. global $DB;
  248. $arAffiliate = CSaleAffiliate::CheckAffiliateFunc($affiliate);
  249. if (!$arAffiliate)
  250. return False;
  251. // If not fixed plan
  252. $affiliateID = intval($arAffiliate["ID"]);
  253. // If fixed plan
  254. if ($arAffiliate["FIX_PLAN"] == "Y")
  255. {
  256. $dbAffiliatePlan = CSaleAffiliatePlan::GetList(
  257. array(),
  258. array(
  259. "ID" => $arAffiliate["PLAN_ID"],
  260. "ACTIVE" => "Y",
  261. "SITE_ID" => $arAffiliate["SITE_ID"]
  262. ),
  263. false,
  264. false,
  265. array("ID", "SITE_ID", "NAME", "TIMESTAMP_X", "ACTIVE", "BASE_RATE", "BASE_RATE_TYPE", "BASE_RATE_CURRENCY", "MIN_PAY", "MIN_PLAN_VALUE")
  266. );
  267. $arAffiliatePlan = $dbAffiliatePlan->Fetch();
  268. if (!$arAffiliatePlan)
  269. {
  270. $arFields = array(
  271. "ACTIVE" => "N"
  272. );
  273. $res = CSaleAffiliate::Update($affiliateID, $arFields);
  274. if ($res)
  275. $GLOBALS["APPLICATION"]->ThrowException(str_replace("#ID#", $affiliateID, GetMessage("ACGA1_NO_PLAN_DEACT")), "NO_PLAN");
  276. return false;
  277. }
  278. return $arAffiliatePlan;
  279. }
  280. if (!$dateFrom || $dateFrom == '')
  281. {
  282. if ($arAffiliate["LAST_CALCULATE"] <> '')
  283. $dateFrom = $arAffiliate["LAST_CALCULATE"];
  284. else
  285. $dateFrom = date($DB->DateFormatToPHP(CSite::GetDateFormat("FULL")), mktime(0, 0, 0, 1, 1, 1990));
  286. }
  287. if (!$dateTo || $dateTo == '')
  288. $dateTo = date($DB->DateFormatToPHP(CSite::GetDateFormat("FULL")), time()+CTimeZone::GetOffset());
  289. $affiliatePlanType = COption::GetOptionString("sale", "affiliate_plan_type", "N");
  290. $itemsValue = 0;
  291. if ($affiliatePlanType == "N")
  292. {
  293. $dbOrders = \Bitrix\Sale\Internals\OrderTable::getList(
  294. array(
  295. 'filter' => array(
  296. "=ALLOW_DELIVERY" => "Y",
  297. ">=DATE_ALLOW_DELIVERY" => $dateFrom,
  298. "<DATE_ALLOW_DELIVERY" => $dateTo,
  299. "=AFFILIATE_ID" => $affiliateID,
  300. "=LID" => $arAffiliate["SITE_ID"],
  301. ),
  302. 'runtime' => array(
  303. new \Bitrix\Main\Entity\ExpressionField('BASKET_QUANTITY', 'SUM(%s)', array('BASKET.QUANTITY'))
  304. ),
  305. 'select' => array('BASKET_QUANTITY')
  306. )
  307. );
  308. if ($arOrder = $dbOrders->fetch())
  309. $itemsValue = $arOrder["BASKET_QUANTITY"];
  310. }
  311. else
  312. {
  313. $dbOrders = \Bitrix\Sale\Internals\OrderTable::getList(
  314. array(
  315. 'filter' => array(
  316. "=ALLOW_DELIVERY" => "Y",
  317. ">=DATE_ALLOW_DELIVERY" => $dateFrom,
  318. "<DATE_ALLOW_DELIVERY" => $dateTo,
  319. "=AFFILIATE_ID" => $affiliateID,
  320. "=LID" => $arAffiliate["SITE_ID"],
  321. ),
  322. 'runtime' => array(
  323. new \Bitrix\Main\Entity\ExpressionField('ORDER_SUM_PRICE', 'SUM(%s)', array('PRICE'))
  324. ),
  325. 'select' => array('ORDER_SUM_PRICE')
  326. )
  327. );
  328. if ($arOrder = $dbOrders->fetch())
  329. $price = $arOrder["ORDER_SUM_PRICE"];
  330. $dbOrders = \Bitrix\Sale\Internals\OrderTable::getList(
  331. array(
  332. 'filter' => array(
  333. "=ALLOW_DELIVERY" => "Y",
  334. ">=DATE_ALLOW_DELIVERY" => $dateFrom,
  335. "<DATE_ALLOW_DELIVERY" => $dateTo,
  336. "=AFFILIATE_ID" => $affiliateID,
  337. "=LID" => $arAffiliate["SITE_ID"],
  338. ),
  339. 'runtime' => array(
  340. new \Bitrix\Main\Entity\ExpressionField('ORDER_PRICE_DELIVERY', 'SUM(%s)', array('PRICE_DELIVERY'))
  341. ),
  342. 'select' => array('ORDER_PRICE_DELIVERY')
  343. )
  344. );
  345. if ($arOrder = $dbOrders->fetch())
  346. $priceDelivery = $arOrder["ORDER_PRICE_DELIVERY"];
  347. $dbOrders = \Bitrix\Sale\Internals\OrderTable::getList(
  348. array(
  349. 'filter' => array(
  350. "=ALLOW_DELIVERY" => "Y",
  351. ">=DATE_ALLOW_DELIVERY" => $dateFrom,
  352. "<DATE_ALLOW_DELIVERY" => $dateTo,
  353. "=AFFILIATE_ID" => $affiliateID,
  354. "=LID" => $arAffiliate["SITE_ID"],
  355. ),
  356. 'runtime' => array(
  357. new \Bitrix\Main\Entity\ExpressionField('ORDER_TAX_VALUE', 'SUM(%s)', array('TAX_VALUE'))
  358. ),
  359. 'select' => array('ORDER_TAX_VALUE')
  360. )
  361. );
  362. if ($arOrder = $dbOrders->fetch())
  363. $priceTax = $arOrder["ORDER_TAX_VALUE"];
  364. $itemsValue = $price - $priceDelivery - $priceTax;
  365. }
  366. if (DoubleVal($itemsValue) > 0)
  367. {
  368. $dbAffiliatePlan = CSaleAffiliatePlan::GetList(
  369. array("MIN_PLAN_VALUE" => "DESC"),
  370. array(
  371. "+<=MIN_PLAN_VALUE" => $itemsValue,
  372. "ACTIVE" => "Y",
  373. "SITE_ID" => $arAffiliate["SITE_ID"]
  374. ),
  375. false,
  376. false,
  377. array("ID", "SITE_ID", "NAME", "TIMESTAMP_X", "ACTIVE", "BASE_RATE", "BASE_RATE_TYPE", "BASE_RATE_CURRENCY", "MIN_PAY", "MIN_PLAN_VALUE")
  378. );
  379. if ($arAffiliatePlan = $dbAffiliatePlan->Fetch())
  380. {
  381. if ($arAffiliate["FIX_PLAN"] != "Y")
  382. {
  383. $arFields = array(
  384. "PLAN_ID" => $arAffiliatePlan["ID"]
  385. );
  386. $res = CSaleAffiliate::Update($affiliateID, $arFields);
  387. if (!$res)
  388. return false;
  389. }
  390. }
  391. else
  392. {
  393. $arFields = array(
  394. "ACTIVE" => "N"
  395. );
  396. $res = CSaleAffiliate::Update($affiliateID, $arFields);
  397. if ($res)
  398. $GLOBALS["APPLICATION"]->ThrowException(str_replace("#ID#", $affiliateID, GetMessage("ACGA1_NO_PLAN_DEACT")), "NO_PLAN");
  399. return false;
  400. }
  401. return $arAffiliatePlan;
  402. }
  403. else
  404. return true;
  405. }
  406. public static function CalculateAffiliate($affiliate, $dateFrom = false, $dateTo = false, $datePlanFrom = false, $datePlanTo = false)
  407. {
  408. global $DB;
  409. $disableCalculate = false;
  410. // Prepare function params - affiliate
  411. $arAffiliate = CSaleAffiliate::CheckAffiliateFunc($affiliate);
  412. if (!$arAffiliate)
  413. return False;
  414. $db_events = GetModuleEvents("sale", "OnBeforeAffiliateCalculate");
  415. while ($arEvent = $db_events->Fetch())
  416. {
  417. if (ExecuteModuleEventEx($arEvent, Array(&$arAffiliate, &$dateFrom, &$dateTo, &$datePlanFrom, &$datePlanTo, &$disableCalculate)) === false)
  418. {
  419. return false;
  420. }
  421. }
  422. $affiliateID = intval($arAffiliate["ID"]);
  423. if ($disableCalculate === true)
  424. {
  425. return True;
  426. }
  427. if (!$dateFrom || $dateFrom == '')
  428. {
  429. if ($arAffiliate["LAST_CALCULATE"] <> '')
  430. $dateFrom = $arAffiliate["LAST_CALCULATE"];
  431. else
  432. $dateFrom = date($DB->DateFormatToPHP(CSite::GetDateFormat("FULL")), mktime(0, 0, 0, 1, 1, 1990));
  433. }
  434. if (!$dateTo || $dateTo == '')
  435. $dateTo = date($DB->DateFormatToPHP(CSite::GetDateFormat("FULL")), time()+CTimeZone::GetOffset());
  436. // Get affiliate plan
  437. $arAffiliatePlan = CSaleAffiliate::SetAffiliatePlan($arAffiliate, $datePlanFrom, $datePlanTo);
  438. if (!$arAffiliatePlan)
  439. return False;
  440. if ($arAffiliatePlan && !is_array($arAffiliatePlan))
  441. return true;
  442. // Get affiliate plan params
  443. $arPlanSections = array();
  444. $dbPlanSection = CSaleAffiliatePlanSection::GetList(
  445. array(),
  446. array("PLAN_ID" => $arAffiliate["PLAN_ID"]),
  447. false,
  448. false,
  449. array("ID", "MODULE_ID", "SECTION_ID", "RATE", "RATE_TYPE", "RATE_CURRENCY")
  450. );
  451. while ($arPlanSection = $dbPlanSection->Fetch())
  452. {
  453. $arPlanSections[$arPlanSection["MODULE_ID"].$arPlanSection["SECTION_ID"]] = $arPlanSection;
  454. }
  455. // Get affiliate parents
  456. $arAffiliateParents = array();
  457. $affiliateParent = intval($arAffiliate["AFFILIATE_ID"]);
  458. $count = 0;
  459. while (($affiliateParent > 0) && ($count < 5))
  460. {
  461. $dbAffiliateParent = CSaleAffiliate::GetList(
  462. array(),
  463. array("ID" => $affiliateParent, "ACTIVE" => "Y"),
  464. false,
  465. false,
  466. array("ID", "AFFILIATE_ID")
  467. );
  468. if ($arAffiliateParent = $dbAffiliateParent->Fetch())
  469. {
  470. $count++;
  471. $arAffiliateParents[] = $affiliateParent;
  472. $affiliateParent = intval($arAffiliateParent["AFFILIATE_ID"]);
  473. }
  474. else
  475. {
  476. $affiliateParent = 0;
  477. }
  478. }
  479. // Get tier
  480. if (!array_key_exists("SALE_AFFILIATE_TIER_TMP_CACHE", $GLOBALS))
  481. $GLOBALS["SALE_AFFILIATE_TIER_TMP_CACHE"] = array();
  482. if (!array_key_exists($arAffiliate["SITE_ID"], $GLOBALS["SALE_AFFILIATE_TIER_TMP_CACHE"]))
  483. {
  484. $dbAffiliateTier = CSaleAffiliateTier::GetList(array(), array("SITE_ID" => $arAffiliate["SITE_ID"]), false, false, array("RATE1", "RATE2", "RATE3", "RATE4", "RATE5"));
  485. if ($arAffiliateTier = $dbAffiliateTier->Fetch())
  486. $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"]));
  487. else
  488. $GLOBALS["SALE_AFFILIATE_TIER_TMP_CACHE"][$arAffiliate["SITE_ID"]] = array(0, 0, 0, 0, 0);
  489. }
  490. // Orders cicle
  491. $affiliateSum = 0;
  492. $affiliateCurrency = CSaleLang::GetLangCurrency($arAffiliate["SITE_ID"]);
  493. $dbOrders = \Bitrix\Sale\Internals\OrderTable::getList(
  494. array(
  495. 'filter' => array(
  496. "=ALLOW_DELIVERY" => 'Y',
  497. ">=DATE_ALLOW_DELIVERY" => $dateFrom,
  498. "<DATE_ALLOW_DELIVERY" => $dateTo,
  499. "=AFFILIATE_ID" => $affiliateID,
  500. "=LID" => $arAffiliate["SITE_ID"],
  501. "=CANCELED" => 'N',
  502. ),
  503. 'select' => array(
  504. "ID",
  505. "LID",
  506. "PRICE_DELIVERY",
  507. "PRICE",
  508. "CURRENCY",
  509. "TAX_VALUE",
  510. "AFFILIATE_ID",
  511. "BASKET_QUANTITY" => 'BASKET.QUANTITY',
  512. "BASKET_PRODUCT_ID" => 'BASKET.PRODUCT_ID',
  513. "BASKET_MODULE" => 'BASKET.MODULE',
  514. "BASKET_PRICE" => 'BASKET.PRICE',
  515. "BASKET_CURRENCY" => 'BASKET.CURRENCY',
  516. "BASKET_DISCOUNT_PRICE" => 'BASKET.DISCOUNT_PRICE'
  517. ),
  518. 'order' => array('ID' => 'ASC')
  519. )
  520. );
  521. while ($arOrder = $dbOrders->fetch())
  522. {
  523. $arProductSections = array();
  524. if (!array_key_exists("SALE_PRODUCT_SECTION_CACHE", $GLOBALS))
  525. $GLOBALS["SALE_PRODUCT_SECTION_CACHE"] = array();
  526. if (array_key_exists($arOrder["BASKET_MODULE"].$arOrder["BASKET_PRODUCT_ID"], $GLOBALS["SALE_PRODUCT_SECTION_CACHE"]))
  527. {
  528. $arProductSections = $GLOBALS["SALE_PRODUCT_SECTION_CACHE"][$arOrder["BASKET_MODULE"].$arOrder["BASKET_PRODUCT_ID"]];
  529. unset($GLOBALS["SALE_PRODUCT_SECTION_CACHE"][$arOrder["BASKET_MODULE"].$arOrder["BASKET_PRODUCT_ID"]]);
  530. $GLOBALS["SALE_PRODUCT_SECTION_CACHE"] = $GLOBALS["SALE_PRODUCT_SECTION_CACHE"] + array($arOrder["BASKET_MODULE"].$arOrder["BASKET_PRODUCT_ID"] => $arProductSections);
  531. }
  532. else
  533. {
  534. if ($arOrder["BASKET_MODULE"] == "catalog")
  535. {
  536. CModule::IncludeModule("iblock");
  537. CModule::IncludeModule("catalog");
  538. $arSku = CCatalogSku::GetProductInfo($arOrder["BASKET_PRODUCT_ID"]);
  539. if ($arSku && count($arSku) > 0)
  540. $elementId = $arSku["ID"];
  541. else
  542. $elementId = $arOrder["BASKET_PRODUCT_ID"];
  543. $elementSectionIterator = Bitrix\Iblock\SectionElementTable::getList(array(
  544. 'select' => array('IBLOCK_SECTION_ID'),
  545. 'filter' => array('=IBLOCK_ELEMENT_ID' => $elementId, '=ADDITIONAL_PROPERTY_ID' => null),
  546. ));
  547. $elementSectionList = [];
  548. while ($elementSection = $elementSectionIterator->fetch())
  549. {
  550. $arSectionsChains = \CIBlockSection::GetNavChain(0, $elementSection['IBLOCK_SECTION_ID'], array('ID'), true);
  551. foreach ($arSectionsChains as $arSectionsChain)
  552. {
  553. $elementSectionList[$arSectionsChain['ID']] = $arSectionsChain['ID'];
  554. }
  555. }
  556. unset($elementSectionIterator);
  557. if ($elementSectionList)
  558. {
  559. sort($elementSectionList);
  560. $sectionIterator = Bitrix\Iblock\SectionTable::getList(array(
  561. 'select' => array('ID', 'LEFT_MARGIN'),
  562. 'filter' => array('@ID' => $elementSectionList),
  563. 'order' => array('LEFT_MARGIN' => 'DESC')
  564. ));
  565. while($section = $sectionIterator->fetch())
  566. {
  567. $arProductSections[] = $section['ID'];
  568. }
  569. unset($sectionIterator);
  570. }
  571. unset($elementSectionList);
  572. }
  573. else
  574. {
  575. $events = GetModuleEvents("sale", "OnAffiliateGetSections");
  576. if ($arEvent = $events->Fetch())
  577. $arProductSections = ExecuteModuleEventEx($arEvent, Array($arOrder["BASKET_MODULE"], $arOrder["BASKET_PRODUCT_ID"]));
  578. }
  579. $GLOBALS["SALE_PRODUCT_SECTION_CACHE"] = $GLOBALS["SALE_PRODUCT_SECTION_CACHE"] + array($arOrder["BASKET_MODULE"].$arOrder["BASKET_PRODUCT_ID"] => $arProductSections);
  580. if (count($GLOBALS["SALE_PRODUCT_SECTION_CACHE"]) > 20)
  581. array_shift($GLOBALS["SALE_PRODUCT_SECTION_CACHE"]);
  582. }
  583. $realRate = $arAffiliatePlan["BASE_RATE"];
  584. $realRateType = $arAffiliatePlan["BASE_RATE_TYPE"];
  585. $realRateCurrency = $arAffiliatePlan["BASE_RATE_CURRENCY"];
  586. $coountArProd = count($arProductSections);
  587. for ($i = 0; $i < $coountArProd; $i++)
  588. {
  589. if (!empty($arPlanSections[$arOrder["BASKET_MODULE"].$arProductSections[$i]]))
  590. {
  591. $realRate = $arPlanSections[$arOrder["BASKET_MODULE"].$arProductSections[$i]]["RATE"];
  592. $realRateType = $arPlanSections[$arOrder["BASKET_MODULE"].$arProductSections[$i]]["RATE_TYPE"];
  593. $realRateCurrency = $arPlanSections[$arOrder["BASKET_MODULE"].$arProductSections[$i]]["RATE_CURRENCY"];
  594. break;
  595. }
  596. }
  597. if ($realRateType == "P")
  598. {
  599. if ($arOrder["CURRENCY"] != $affiliateCurrency)
  600. {
  601. if (!array_key_exists("SALE_CONVERT_CURRENCY_CACHE", $GLOBALS))
  602. $GLOBALS["SALE_CONVERT_CURRENCY_CACHE"] = array();
  603. if (!array_key_exists($arOrder["CURRENCY"]."-".$affiliateCurrency, $GLOBALS["SALE_CONVERT_CURRENCY_CACHE"]))
  604. $GLOBALS["SALE_CONVERT_CURRENCY_CACHE"][$arOrder["CURRENCY"]."-".$affiliateCurrency] = CCurrencyRates::GetConvertFactor($arOrder["CURRENCY"], $affiliateCurrency);
  605. $affiliateSum += \Bitrix\Sale\PriceMaths::roundPrecision((($arOrder["BASKET_PRICE"] * $arOrder["BASKET_QUANTITY"]) * $GLOBALS["SALE_CONVERT_CURRENCY_CACHE"][$arOrder["CURRENCY"]."-".$affiliateCurrency] * $realRate) / 100);
  606. }
  607. else
  608. {
  609. $affiliateSum += \Bitrix\Sale\PriceMaths::roundPrecision((($arOrder["BASKET_PRICE"] * $arOrder["BASKET_QUANTITY"]) * $realRate) / 100);
  610. }
  611. }
  612. else
  613. {
  614. if ($realRateCurrency != $affiliateCurrency)
  615. {
  616. if (!array_key_exists("SALE_CONVERT_CURRENCY_CACHE", $GLOBALS))
  617. $GLOBALS["SALE_CONVERT_CURRENCY_CACHE"] = array();
  618. if (!array_key_exists($realRateCurrency."-".$affiliateCurrency, $GLOBALS["SALE_CONVERT_CURRENCY_CACHE"]))
  619. $GLOBALS["SALE_CONVERT_CURRENCY_CACHE"][$realRateCurrency."-".$affiliateCurrency] = CCurrencyRates::GetConvertFactor($realRateCurrency, $affiliateCurrency);
  620. $affiliateSum += roundEx($realRate * $GLOBALS["SALE_CONVERT_CURRENCY_CACHE"][$realRateCurrency."-".$affiliateCurrency], SALE_VALUE_PRECISION);
  621. }
  622. else
  623. {
  624. $affiliateSum += roundEx($realRate, SALE_VALUE_PRECISION);
  625. }
  626. }
  627. }
  628. $arFields = array(
  629. "=PENDING_SUM" => "PENDING_SUM + ".$affiliateSum,
  630. "LAST_CALCULATE" => $dateTo
  631. );
  632. $res = CSaleAffiliate::Update($affiliateID, $arFields);
  633. if (!$res)
  634. return False;
  635. if ($affiliateSum > 0)
  636. {
  637. $cnt = min(count($arAffiliateParents), count($GLOBALS["SALE_AFFILIATE_TIER_TMP_CACHE"][$arAffiliate["SITE_ID"]]));
  638. for ($i = 0; $i < $cnt; $i++)
  639. {
  640. $affiliateSumTmp = roundEx($affiliateSum * $GLOBALS["SALE_AFFILIATE_TIER_TMP_CACHE"][$arAffiliate["SITE_ID"]][$i] / 100, SALE_VALUE_PRECISION);
  641. $arFields = array(
  642. "=PENDING_SUM" => "PENDING_SUM + ".$affiliateSumTmp
  643. );
  644. CSaleAffiliate::Update($arAffiliateParents[$i], $arFields);
  645. }
  646. }
  647. $events = GetModuleEvents("sale", "OnAfterAffiliateCalculate");
  648. while ($arEvent = $events->Fetch())
  649. ExecuteModuleEventEx($arEvent, Array($affiliateID));
  650. return True;
  651. }
  652. public static function PayAffiliate($affiliate, $payType, &$paySum)
  653. {
  654. global $DB;
  655. $arAffiliate = CSaleAffiliate::CheckAffiliateFunc($affiliate);
  656. if (!$arAffiliate)
  657. return False;
  658. $db_events = GetModuleEvents("sale", "OnBeforePayAffiliate");
  659. while ($arEvent = $db_events->Fetch())
  660. if (ExecuteModuleEventEx($arEvent, Array(&$arAffiliate, &$payType))===false)
  661. return false;
  662. $arPayTypes = array("U", "P");
  663. if ($payType == '' || !in_array($payType, $arPayTypes))
  664. {
  665. $GLOBALS["APPLICATION"]->ThrowException(GetMessage("ACGA1_BAD_FUNC1"), "ERROR_FUNCTION_CALL");
  666. return False;
  667. }
  668. $arAffiliate["PENDING_SUM"] = str_replace(",", ".", $arAffiliate["PENDING_SUM"]);
  669. $arAffiliate["PENDING_SUM"] = DoubleVal($arAffiliate["PENDING_SUM"]);
  670. $paySum = $arAffiliate["PENDING_SUM"];
  671. if ($arAffiliate["PENDING_SUM"] > 0)
  672. {
  673. if (!array_key_exists("BASE_LANG_CURRENCIES", $GLOBALS))
  674. $GLOBALS["BASE_LANG_CURRENCIES"] = array();
  675. if (!array_key_exists($arAffiliate["SITE_ID"], $GLOBALS["BASE_LANG_CURRENCIES"]))
  676. $GLOBALS["BASE_LANG_CURRENCIES"][$arAffiliate["SITE_ID"]] = CSaleLang::GetLangCurrency($arAffiliate["SITE_ID"]);
  677. if ($payType == "U")
  678. {
  679. if (!CSaleUserAccount::UpdateAccount($arAffiliate["USER_ID"], $arAffiliate["PENDING_SUM"], $GLOBALS["BASE_LANG_CURRENCIES"][$arAffiliate["SITE_ID"]], "AFFILIATE"))
  680. {
  681. if ($ex = $GLOBALS["APPLICATION"]->GetException())
  682. $GLOBALS["APPLICATION"]->ThrowException($ex->GetString(), "ACCT_UPDATE_ERROR");
  683. else
  684. $GLOBALS["APPLICATION"]->ThrowException(GetMessage("ACGA1_ERROR_TRANSF_MONEY"), "ACCT_UPDATE_ERROR");
  685. return False;
  686. }
  687. //$arFields = array("PENDING_SUM" => 0);
  688. }
  689. //else
  690. //{
  691. // $arFields = array("=PAID_SUM" => "PAID_SUM + PENDING_SUM", "PENDING_SUM" => 0);
  692. //}
  693. $arFields = array("=PAID_SUM" => "PAID_SUM + PENDING_SUM", "PENDING_SUM" => 0);
  694. if (!CSaleAffiliate::Update($arAffiliate["ID"], $arFields))
  695. {
  696. if ($ex = $GLOBALS["APPLICATION"]->GetException())
  697. $GLOBALS["APPLICATION"]->ThrowException($ex->GetString().(($payType == "U") ? GetMessage("ACGA1_TRANSF_MONEY") : ""), "AF_UPDATE_ERROR");
  698. else
  699. $GLOBALS["APPLICATION"]->ThrowException(GetMessage("ACGA1_ERROR_UPDATE_SUM").(($payType == "U") ? GetMessage("ACGA1_TRANSF_MONEY") : ""), "AF_UPDATE_ERROR");
  700. return False;
  701. }
  702. $arFields = array(
  703. "AFFILIATE_ID" => $arAffiliate["ID"],
  704. "TRANSACT_DATE" => date($DB->DateFormatToPHP(CSite::GetDateFormat("FULL", SITE_ID))),
  705. "AMOUNT" => $arAffiliate["PENDING_SUM"],
  706. "CURRENCY" => $GLOBALS["BASE_LANG_CURRENCIES"][$arAffiliate["SITE_ID"]],
  707. "DEBIT" => "Y",
  708. "DESCRIPTION" => "AFFILIATE_IN",
  709. "EMPLOYEE_ID" => ($GLOBALS["USER"]->IsAuthorized() ? $GLOBALS["USER"]->GetID() : False)
  710. );
  711. CSaleAffiliateTransact::Add($arFields);
  712. if ($payType == "U")
  713. {
  714. $arFields = array(
  715. "AFFILIATE_ID" => $arAffiliate["ID"],
  716. "TRANSACT_DATE" => date($DB->DateFormatToPHP(CSite::GetDateFormat("FULL", SITE_ID))),
  717. "AMOUNT" => $arAffiliate["PENDING_SUM"],
  718. "CURRENCY" => $GLOBALS["BASE_LANG_CURRENCIES"][$arAffiliate["SITE_ID"]],
  719. "DEBIT" => "N",
  720. "DESCRIPTION" => "AFFILIATE_ACCT",
  721. "EMPLOYEE_ID" => ($GLOBALS["USER"]->IsAuthorized() ? $GLOBALS["USER"]->GetID() : False)
  722. );
  723. CSaleAffiliateTransact::Add($arFields);
  724. }
  725. }
  726. $ID = $arAffiliate["ID"];
  727. $events = GetModuleEvents("sale", "OnAfterPayAffiliate");
  728. while ($arEvent = $events->Fetch())
  729. ExecuteModuleEventEx($arEvent, Array($ID));
  730. return True;
  731. }
  732. public static function ClearAffiliateSum($affiliate)
  733. {
  734. global $DB;
  735. $arAffiliate = CSaleAffiliate::CheckAffiliateFunc($affiliate);
  736. if (!$arAffiliate)
  737. return False;
  738. $arAffiliate["PAID_SUM"] = str_replace(",", ".", $arAffiliate["PAID_SUM"]);
  739. $arAffiliate["PAID_SUM"] = DoubleVal($arAffiliate["PAID_SUM"]);
  740. if ($arAffiliate["PAID_SUM"] > 0)
  741. {
  742. if (!array_key_exists("BASE_LANG_CURRENCIES", $GLOBALS))
  743. $GLOBALS["BASE_LANG_CURRENCIES"] = array();
  744. if (!array_key_exists($arAffiliate["SITE_ID"], $GLOBALS["BASE_LANG_CURRENCIES"]))
  745. $GLOBALS["BASE_LANG_CURRENCIES"][$arAffiliate["SITE_ID"]] = CSaleLang::GetLangCurrency($arAffiliate["SITE_ID"]);
  746. if (!CSaleAffiliate::Update($arAffiliate["ID"], array("PAID_SUM" => 0)))
  747. {
  748. if ($ex = $GLOBALS["APPLICATION"]->GetException())
  749. $GLOBALS["APPLICATION"]->ThrowException($ex->GetString(), "AF_UPDATE_ERROR");
  750. else
  751. $GLOBALS["APPLICATION"]->ThrowException(GetMessage("ACGA1_ERROR_UPDATE_SUM"), "AF_UPDATE_ERROR");
  752. return False;
  753. }
  754. $arFields = array(
  755. "AFFILIATE_ID" => $arAffiliate["ID"],
  756. "TRANSACT_DATE" => date($DB->DateFormatToPHP(CSite::GetDateFormat("FULL", SITE_ID))),
  757. "AMOUNT" => $arAffiliate["PAID_SUM"],
  758. "CURRENCY" => $GLOBALS["BASE_LANG_CURRENCIES"][$arAffiliate["SITE_ID"]],
  759. "DEBIT" => "N",
  760. "DESCRIPTION" => "AFFILIATE_CLEAR",
  761. "EMPLOYEE_ID" => ($GLOBALS["USER"]->IsAuthorized() ? $GLOBALS["USER"]->GetID() : False)
  762. );
  763. CSaleAffiliateTransact::Add($arFields);
  764. }
  765. return True;
  766. }
  767. public static function OnBeforeUserDelete($UserID)
  768. {
  769. global $DB;
  770. if (intval($UserID) <= 0)
  771. {
  772. $GLOBALS["APPLICATION"]->ThrowException("Empty user ID", "EMPTY_USER_ID");
  773. return false;
  774. }
  775. $dbAffiliate = CSaleAffiliate::GetList(array(), array("USER_ID" => $UserID), false, array("nTopCount" => 1), array("ID", "USER_ID"));
  776. if ($arAffiliate = $dbAffiliate->Fetch())
  777. {
  778. $GLOBALS["APPLICATION"]->ThrowException(str_replace("#USER_ID#", $UserID, GetMessage("AF_ERROR_USER")), "ERROR_AFFILIATE");
  779. return False;
  780. }
  781. return true;
  782. }
  783. }