2namespace Bitrix\Sale\Internals;
5use Bitrix\Main\Application;
6use Bitrix\Main\Localization\Loc;
9Loc::loadMessages(__FILE__);
74 return 'b_sale_discount_coupon';
87 'autocomplete' =>
true,
88 'title' => Loc::getMessage(
'DISCOUNT_COUPON_ENTITY_ID_FIELD')
92 'validation' =>
array(__CLASS__,
'validateDiscountId'),
93 'title' => Loc::getMessage(
'DISCOUNT_COUPON_ENTITY_DISCOUNT_ID_FIELD')
96 'values' =>
array(
'N',
'Y'),
97 'default_value' =>
'Y',
98 'title' => Loc::getMessage(
'DISCOUNT_COUPON_ENTITY_ACTIVE_FIELD')
101 'default_value' =>
null,
102 'title' => Loc::getMessage(
'DISCOUNT_COUPON_ENTITY_ACTIVE_FROM_FIELD')
105 'default_value' =>
null,
106 'title' => Loc::getMessage(
'DISCOUNT_COUPON_ENTITY_ACTIVE_TO_FIELD')
110 'validation' =>
array(__CLASS__,
'validateCoupon'),
111 'title' => Loc::getMessage(
'DISCOUNT_COUPON_ENTITY_COUPON_FIELD')
114 'validation' =>
array(__CLASS__,
'validateType'),
115 'title' => Loc::getMessage(
'DISCOUNT_COUPON_ENTITY_TYPE_FIELD')
118 'default_value' => 0,
119 'title' => Loc::getMessage(
'DISCOUNT_COUPON_ENTITY_MAX_USE_FIELD')
122 'default_value' => 0,
123 'title' => Loc::getMessage(
'DISCOUNT_COUPON_ENTITY_USE_COUNT_FIELD')
126 'default_value' => 0,
127 'title' => Loc::getMessage(
'DISCOUNT_COUPON_ENTITY_USER_ID_FIELD')
130 'default_value' =>
null,
131 'title' => Loc::getMessage(
'DISCOUNT_COUPON_ENTITY_DATE_APPLY_FIELD')
135 'title' => Loc::getMessage(
'DISCOUNT_COUPON_ENTITY_TIMESTAMP_X_FIELD')
137 'MODIFIED_BY' =>
new Main\Entity\IntegerField(
'MODIFIED_BY',
array(
138 'default_value' =>
null,
139 'title' => Loc::getMessage(
'DISCOUNT_COUPON_ENTITY_MODIFIED_BY_FIELD')
141 'DATE_CREATE' =>
new Main\Entity\DatetimeField(
'DATE_CREATE',
array(
143 'title' => Loc::getMessage(
'DISCOUNT_COUPON_ENTITY_DATE_CREATE_FIELD')
146 'default_value' =>
null,
147 'title' => Loc::getMessage(
'DISCOUNT_COUPON_ENTITY_CREATED_BY_FIELD')
149 'DESCRIPTION' =>
new Main\Entity\TextField(
'DESCRIPTION',
array(
150 'default_value' =>
null,
151 'title' => Loc::getMessage(
'DISCOUNT_COUPON_ENTITY_DESCRIPTION_FIELD')
153 'CREATED_BY_USER' =>
new Main\Entity\ReferenceField(
156 array(
'=this.CREATED_BY' =>
'ref.ID'),
157 array(
'join_type' =>
'LEFT')
159 'MODIFIED_BY_USER' =>
new Main\Entity\ReferenceField(
162 array(
'=this.MODIFIED_BY' =>
'ref.ID'),
163 array(
'join_type' =>
'LEFT')
165 'DISCOUNT' =>
new Main\Entity\ReferenceField(
167 'Bitrix\Sale\Internals\Discount',
168 array(
'=this.DISCOUNT_ID' =>
'ref.ID'),
169 array(
'join_type' =>
'LEFT')
182 array(__CLASS__,
'checkDiscountId')
195 array(__CLASS__,
'checkCoupon')
207 array(__CLASS__,
'checkType')
222 if ((
int)$value <= 0)
223 return Loc::getMessage(
'DISCOUNT_COUPON_VALIDATOR_DISCOUNT_ID');
240 $value == self::TYPE_BASKET_ROW
241 || $value == self::TYPE_ONE_ORDER
242 || $value == self::TYPE_MULTI_ORDER
246 return Loc::getMessage(
'DISCOUNT_COUPON_VALIDATOR_TYPE');
260 $value = trim((
string)$value);
262 return Loc::getMessage(
'DISCOUNT_COUPON_VALIDATOR_COUPON_EMPTY');
265 if (!empty($existCoupon))
267 $currentId = (int)(is_array($primary) ? $primary[
'ID'] : $primary);
268 if ($existCoupon[
'MODULE'] !=
'sale' || $currentId != $existCoupon[
'ID'])
269 return Loc::getMessage(
'DISCOUNT_COUPON_VALIDATOR_COUPON_EXIST');
282 $result =
new Main\Entity\EventResult;
285 $modifyFieldList =
array();
289 if (!empty($modifyFieldList))
290 $result->modifyFields($modifyFieldList);
291 unset($modifyFieldList,
$data);
304 if (!self::isCheckedCouponsUse())
307 $id = (int)
$data[
'DISCOUNT_ID'];
308 self::$discountCheckList[$id] = $id;
310 self::updateUseCoupons();
321 $result =
new Main\Entity\EventResult;
324 $modifyFieldList =
array();
328 if (!empty($modifyFieldList))
329 $result->modifyFields($modifyFieldList);
330 unset($modifyFieldList,
$data);
343 if (!self::isCheckedCouponsUse())
346 if (isset(
$data[
'DISCOUNT_ID']))
348 $data[
'DISCOUNT_ID'] = (int)
$data[
'DISCOUNT_ID'];
349 $coupon = static::getList(
array(
350 'select' =>
array(
'ID',
'DISCOUNT_ID'),
351 'filter' =>
array(
'=ID' =>
$event->getParameter(
'id'))
355 $coupon[
'DISCOUNT_ID'] = (int)$coupon[
'DISCOUNT_ID'];
356 if ($coupon[
'DISCOUNT_ID'] !==
$data[
'DISCOUNT_ID'])
358 self::$discountCheckList[
$data[
'DISCOUNT_ID']] =
$data[
'DISCOUNT_ID'];
359 self::$discountCheckList[$coupon[
'DISCOUNT_ID']] = $coupon[
'DISCOUNT_ID'];
375 self::updateUseCoupons();
386 if (!self::isCheckedCouponsUse())
388 $coupon = self::getList(
array(
389 'select' =>
array(
'ID',
'DISCOUNT_ID'),
390 'filter' =>
array(
'=ID' =>
$event->getParameter(
'id'))
394 $coupon[
'DISCOUNT_ID'] = (int)$coupon[
'DISCOUNT_ID'];
395 self::$discountCheckList[$coupon[
'DISCOUNT_ID']] = $coupon[
'DISCOUNT_ID'];
408 self::updateUseCoupons();
419 $extendedMode = ($extendedMode ===
true);
423 self::TYPE_BASKET_ROW => Loc::getMessage(
'DISCOUNT_COUPON_TABLE_TYPE_BASKET_ROW'),
424 self::TYPE_ONE_ORDER => Loc::getMessage(
'DISCOUNT_COUPON_TABLE_TYPE_ONE_ORDER'),
425 self::TYPE_MULTI_ORDER => Loc::getMessage(
'DISCOUNT_COUPON_TABLE_TYPE_MULTI_ORDER')
428 return array(self::TYPE_BASKET_ROW, self::TYPE_ONE_ORDER, self::TYPE_MULTI_ORDER);
438 self::$checkDiscountCouponsUse--;
448 self::$checkDiscountCouponsUse++;
458 return (self::$checkDiscountCouponsUse >= 0);
468 self::$discountCheckList =
array();
479 if (!is_array($discountList))
480 $discountList =
array($discountList => $discountList);
481 if (!empty($discountList))
482 self::$discountCheckList = (empty(self::$discountCheckList) ? $discountList : array_merge(self::$discountCheckList, $discountList));
492 if (!self::isCheckedCouponsUse() || empty(self::$discountCheckList))
496 if (empty(self::$discountCheckList))
499 $withoutCoupons = array_fill_keys(self::$discountCheckList,
true);
500 $withCoupons =
array();
503 'filter' =>
array(
'@DISCOUNT_ID' => self::$discountCheckList),
504 'group' =>
array(
'DISCOUNT_ID')
508 $coupon[
'CNT'] = (int)$coupon[
'CNT'];
509 if ($coupon[
'CNT'] > 0)
511 $coupon[
'DISCOUNT_ID'] = (int)$coupon[
'DISCOUNT_ID'];
512 unset($withoutCoupons[$coupon[
'DISCOUNT_ID']]);
513 $withCoupons[$coupon[
'DISCOUNT_ID']] =
true;
517 if (!empty($withoutCoupons))
519 $withoutCoupons = array_keys($withoutCoupons);
522 if (!empty($withCoupons))
524 $withCoupons = array_keys($withCoupons);
527 unset($withCoupons, $withoutCoupons);
529 static::clearDiscountCheckList();
544 $couponsList =
array();
546 'select' =>
array(
'ID'),
550 $couponsList[] = $coupon[
'ID'];
552 if (!empty($couponsList))
554 $conn = Application::getConnection();
555 $helper = $conn->getSqlHelper();
557 'delete from '.$helper->quote(self::getTableName()).
' where '.$helper->quote(
'DISCOUNT_ID').
' = '.
$discount
574 $currentTimestamp = $currentTime->getTimestamp();
578 if (!is_array($coupons))
579 $coupons =
array($coupons);
587 $deactivateCoupons =
array();
588 $incrementalCoupons =
array();
589 $limitedCoupons =
array();
592 'ID',
'COUPON',
'DISCOUNT_ID',
'TYPE',
'ACTIVE',
'MAX_USE',
'USE_COUNT',
'USER_ID',
'ACTIVE_TO',
'ACTIVE_FROM',
593 'DISCOUNT_ACTIVE' =>
'DISCOUNT.ACTIVE',
594 'DISCOUNT_ACTIVE_FROM' =>
'DISCOUNT.ACTIVE_FROM',
'DISCOUNT_ACTIVE_TO' =>
'DISCOUNT.ACTIVE_TO'
596 'filter' =>
array(
'@ID' => $coupons),
597 'order' =>
array(
'ID' =>
'ASC')
601 $couponCode = $existCoupon[
'COUPON'];
602 if ($existCoupon[
'DISCOUNT_ACTIVE'] !=
'Y')
604 $errorList[$couponCode] = Loc::getMessage(
'DISCOUNT_COUPON_SAVE_ERROR_DISCOUNT_INACTIVE');
608 ($existCoupon[
'DISCOUNT_ACTIVE_FROM'] instanceof
Main\
Type\
DateTime && $existCoupon[
'DISCOUNT_ACTIVE_FROM']->getTimestamp() > $currentTimestamp)
610 ($existCoupon[
'DISCOUNT_ACTIVE_TO'] instanceof
Main\
Type\
DateTime && $existCoupon[
'DISCOUNT_ACTIVE_TO']->getTimestamp() < $currentTimestamp)
613 $errorList[$couponCode] = Loc::getMessage(
'DISCOUNT_COUPON_SAVE_ERROR_DISCOUNT_WRONG_ACTIVE_PERIOD');
617 $existCoupon[
'USER_ID'] = (int)$existCoupon[
'USER_ID'];
618 if ($existCoupon[
'USER_ID'] > 0 && $existCoupon[
'USER_ID'] !=
$userId)
620 $errorList[$couponCode] = Loc::getMessage(
'DISCOUNT_COUPON_SAVE_ERROR_WRONG_USER_COUPON');
624 ($existCoupon[
'ACTIVE_FROM'] instanceof
Main\
Type\
DateTime && $existCoupon[
'ACTIVE_FROM']->getTimestamp() > $currentTimestamp)
626 ($existCoupon[
'ACTIVE_TO'] instanceof
Main\
Type\
DateTime && $existCoupon[
'ACTIVE_TO']->getTimestamp() < $currentTimestamp)
629 $errorList[$couponCode] = Loc::getMessage(
'DISCOUNT_COUPON_SAVE_ERROR_COUPON_WRONG_ACTIVE_PERIOD');
632 if ($existCoupon[
'ACTIVE'] !=
'Y')
634 switch ($existCoupon[
'TYPE'])
636 case self::TYPE_BASKET_ROW:
637 $errorList[$couponCode] = Loc::getMessage(
'DISCOUNT_COUPON_SAVE_ERROR_COUPON_BASKET_ROW_INACTIVE');
639 case self::TYPE_ONE_ORDER:
640 $errorList[$couponCode] = Loc::getMessage(
'DISCOUNT_COUPON_SAVE_ERROR_COUPON_ONE_ORDER_INACTIVE');
643 $errorList[$couponCode] = Loc::getMessage(
'DISCOUNT_COUPON_SAVE_ERROR_COUPON_INACTIVE');
650 $existCoupon[
'TYPE'] == self::TYPE_BASKET_ROW
651 || $existCoupon[
'TYPE'] == self::TYPE_ONE_ORDER
654 $deactivateCoupons[$couponCode] = $existCoupon[
'ID'];
656 elseif ($existCoupon[
'TYPE'] == self::TYPE_MULTI_ORDER)
658 $existCoupon[
'MAX_USE'] = (int)$existCoupon[
'MAX_USE'];
659 $existCoupon[
'USE_COUNT'] = (int)$existCoupon[
'USE_COUNT'];
661 if ($existCoupon[
'MAX_USE'] > 0 && $existCoupon[
'USE_COUNT'] >= $existCoupon[
'MAX_USE'])
663 $errorList[$couponCode] = Loc::getMessage(
'DISCOUNT_COUPON_SAVE_ERROR_COUPON_MAX_USE_LIMIT');
666 if ($existCoupon[
'MAX_USE'] > 0 && $existCoupon[
'USE_COUNT'] >= ($existCoupon[
'MAX_USE'] - 1))
668 $limitedCoupons[$existCoupon[
'COUPON']] = $existCoupon[
'ID'];
672 $incrementalCoupons[$existCoupon[
'COUPON']] = $existCoupon[
'ID'];
678 if (!empty($errorList))
682 'ERROR' => $errorList,
688 if (!empty($deactivateCoupons) || !empty($limitedCoupons) || !empty($incrementalCoupons))
690 $conn = Application::getConnection();
691 $helper = $conn->getSqlHelper();
692 $tableName = $helper->quote(self::getTableName());
693 if (!empty($deactivateCoupons))
696 'update '.$tableName.
' set '.$helper->quote(
'ACTIVE').
' = \'N\', '.$helper->quote(
'DATE_APPLY').
' = '.$helper->getCurrentDateTimeFunction().
697 ' where '.$helper->quote(
'ID').
' in ('.implode(
',', $deactivateCoupons).
')'
700 if (!empty($incrementalCoupons))
703 'update '.$tableName.
' set '.$helper->quote(
'DATE_APPLY').
' = '.$helper->getCurrentDateTimeFunction().
', '.
704 $helper->quote(
'USE_COUNT').
' = '.$helper->quote(
'USE_COUNT').
' + 1'.
705 ' where '.$helper->quote(
'ID').
' in ('.implode(
',', $incrementalCoupons).
')'
708 if (!empty($limitedCoupons))
711 'update '.$tableName.
' set '.$helper->quote(
'DATE_APPLY').
' = '.$helper->getCurrentDateTimeFunction().
', '.
712 $helper->quote(
'ACTIVE').
' = \'N\', '.$helper->quote(
'USE_COUNT').
' = '.$helper->quote(
'USE_COUNT').
' + 1'.
713 ' where '.$helper->quote(
'ID').
' in ('.implode(
',', $limitedCoupons).
')'
716 unset($tableName, $helper);
721 'DEACTIVATE' => $deactivateCoupons,
722 'LIMITED' => $limitedCoupons,
723 'INCREMENT' => $incrementalCoupons
733 public static function generateCoupon($check =
false)
735 static $eventExists =
null;
737 $check = ($check ===
true);
738 if ($eventExists ===
true || $eventExists ===
null)
742 $resultList =
$event->getResults();
743 if (!empty($resultList) && is_array($resultList))
746 foreach ($resultList as &$eventResult)
748 if ($eventResult->getType() !=
Main\EventResult::SUCCESS)
751 $result = $eventResult->getParameters();
757 if ($eventExists ===
null)
758 $eventExists =
false;
761 $allchars =
'ABCDEFGHIJKLNMOPQRSTUVWXYZ0123456789';
762 $charsLen = mb_strlen($allchars) - 1;
766 $resultCorrect =
true;
769 for (
$i = 0;
$i < 5;
$i++)
770 $partOne .= mb_substr($allchars, rand(0, $charsLen), 1);
772 for (
$i = 0;
$i < 7;
$i++)
773 $partTwo .= mb_substr($allchars, rand(0, $charsLen), 1);
775 $result =
'SL-'.$partOne.
'-'.$partTwo;
778 $existCoupon = Sale\DiscountCouponsManager::isExist(
$result);
779 $resultCorrect = empty($existCoupon);
781 }
while (!$resultCorrect);
795 $result =
new Main\Entity\Result();
806 Loc::getMessage(
'DISCOUNT_COUPON_PACKET_COUNT_ERR'),
810 foreach (static::getEntity()->getFields() as $field)
817 $data[$field->getName()] = $field->getDefaultValue();
820 $checkResult = static::checkPacket(
$data,
false);
821 if (!$checkResult->isSuccess())
823 foreach ($checkResult->getErrors() as $checkError)
825 $result->addError($checkError);
831 $discountIterator = DiscountTable::getList(
array(
832 'select' =>
array(
'ID',
'USE_COUPONS'),
833 'filter' =>
array(
'=ID' =>
$data[
'DISCOUNT_ID'])
835 if (
$discount = $discountIterator->fetch())
837 $useCoupons = (
$discount[
'USE_COUPONS'] ==
'Y');
842 Loc::getMessage(
'DISCOUNT_COUPON_PACKET_DISCOUNT_ERR'),
849 self::setDiscountCheckList(
$data[
'DISCOUNT_ID']);
850 self::disableCheckCouponsUse();
851 $limit = (int)$limit;
858 $data[
'COUPON'] = self::generateCoupon(
true);
859 $couponResult = self::add(
$data);
860 if ($couponResult->isSuccess())
863 }
while ($resultCount <
$count && $all < $limit);
865 'result' => $resultCount,
870 if ($resultCount == 0)
874 ? Loc::getMessage(
'DISCOUNT_COUPON_PACKET_GENERATE_COUPON_ZERO_ERR')
875 : Loc::getMessage(
'DISCOUNT_COUPON_PACKET_NEW_GENERATE_COUPON_ZERO_ERR')
879 self::clearDiscountCheckList();
885 'DISCOUNT_COUPON_PACKET_GENERATE_COUPON_COUNT_ERR',
887 '#RESULT#' => $resultCount,
895 self::enableCheckCouponsUse();
896 self::updateUseCoupons();
910 $result =
new Main\Entity\Result();
912 $newDiscount = ($newDiscount ===
true);
916 Loc::getMessage(
'DISCOUNT_COUPON_PACKET_EMPTY'),
922 if (empty(
$data[
'TYPE']) || !in_array((
int)
$data[
'TYPE'], self::getCouponTypes(
false)))
925 Loc::getMessage(
'DISCOUNT_COUPON_VALIDATOR_TYPE'),
929 if (!$newDiscount && empty(
$data[
'DISCOUNT_ID']))
932 Loc::getMessage(
'DISCOUNT_COUPON_VALIDATOR_DISCOUNT_ID'),
943 Loc::getMessage(
'DISCOUNT_COUPON_VALIDATOR_PERIOD'),
959 $result =
new Main\Entity\Result();
966 if (isset(
$fields[
'ACTIVE_FROM']) && is_string(
$fields[
'ACTIVE_FROM']))
971 if (isset(
$fields[
'ACTIVE_TO']) && is_string(
$fields[
'ACTIVE_TO']))
988 $couponType = (int)$couponType;
990 $couponType == self::TYPE_BASKET_ROW
991 || $couponType == self::TYPE_ONE_ORDER
992 || $couponType == self::TYPE_MULTI_ORDER
1006 static $currentUserID =
false;
1007 if ($currentUserID ===
false)
1011 $currentUserID = (isset(
$USER) &&
$USER instanceof \CUser ? (int)
$USER->getID() :
null);
1013 foreach ($keys as $oneKey)
1016 if (array_key_exists($oneKey,
$data))
1017 $setField = (
$data[$oneKey] !==
null && (int)
$data[$oneKey] <= 0);
1020 $result[$oneKey] = $currentUserID;
1035 foreach ($keys as $oneKey)
1038 if (array_key_exists($oneKey,
$data))
1039 $setField = (
$data[$oneKey] !==
null && !is_object(
$data[$oneKey]));
if($_SERVER $defaultValue['REQUEST_METHOD']==="GET" &&!empty($RestoreDefaults) && $bizprocPerms==="W" &&check_bitrix_sessid())
if(!is_object($USER)||! $USER->IsAuthorized()) $userId
static setUserID(&$result, $data, $keys)
static setTimestamp(&$result, $data, $keys)
static setUseCoupons($discountList, $use)
static normalizeArrayValuesByInt(&$map, $sorted=true)
static createFromUserTime($timeString)
static checkCoupon($value, $primary, array $row, Main\Entity\Field $field)
static isValidCouponType($couponType)
static clearDiscountCheckList()
static getCouponTypes($extendedMode=false)
static setUserID(array &$result, array $data, array $keys)
static updateUseCoupons()
static deleteByDiscount($discount)
static isCheckedCouponsUse()
const EVENT_ON_AFTER_DELETE_DISCOUNT
static onUpdate(Main\Entity\Event $event)
static prepareCouponData(&$fields)
static onBeforeAdd(Main\Entity\Event $event)
static $discountCheckList
const EVENT_ON_GENERATE_COUPON
static setDiscountCheckList($discountList)
static onAfterDelete(Main\Entity\Event $event)
static onDelete(Main\Entity\Event $event)
static checkPacket(array $data, $newDiscount=false)
static $checkDiscountCouponsUse
static validateDiscountId()
static onAfterUpdate(Main\Entity\Event $event)
static onBeforeUpdate(Main\Entity\Event $event)
static checkType($value, $primary, array $row, Main\Entity\Field $field)
static onAfterAdd(Main\Entity\Event $event)
static saveApplied($coupons, $userId, Main\Type\DateTime $currentTime)
static setTimestamp(array &$result, array $data, array $keys)
static checkDiscountId($value, $primary, array $row, Main\Entity\Field $field)
static addPacket(array $data, $count, $limit=0)
static disableCheckCouponsUse()
static enableCheckCouponsUse()
if($usePageNavigation) $couponIterator
</td ></tr ></table ></td ></tr >< tr >< td class="bx-popup-label bx-width30"><?=GetMessage("PAGE_NEW_TAGS")?> array( $site)
if( $daysToExpire >=0 &&$daysToExpire< 60 elseif)( $daysToExpire< 0)