%PDF- %PDF-
Direktori : /home/bitrix/www/bitrix/modules/catalog/lib/ |
Current File : /home/bitrix/www/bitrix/modules/catalog/lib/discountcoupon.php |
<?php namespace Bitrix\Catalog; 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> COUPON string(32) mandatory * <li> DATE_APPLY datetime optional * <li> TYPE enum optional default 'O' * <li> TIMESTAMP_X datetime optional * <li> MODIFIED_BY int optional * <li> DATE_CREATE datetime optional * <li> CREATED_BY int optional * <li> DESCRIPTION string 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\Catalog\DiscountTable} * </ul> * * @package Bitrix\Catalog **/ class DiscountCouponTable extends Main\Entity\DataManager { const TYPE_ONE_ROW = 'Y'; const TYPE_ONE_ORDER = 'O'; const TYPE_NO_LIMIT = 'N'; protected static $existCouponsManager = null; protected static $types = array(); protected static $typeUnknown = false; /** * Returns DB table name for entity. * * @return string */ public static function getTableName() { return 'b_catalog_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') )), 'COUPON' => new Main\Entity\StringField('COUPON', array( 'required' => true, 'validation' => array(__CLASS__, 'validateCoupon'), 'title' => Loc::getMessage('DISCOUNT_COUPON_ENTITY_COUPON_FIELD') )), 'DATE_APPLY' => new Main\Entity\DatetimeField('DATE_APPLY', array( 'default_value' => null, 'title' => Loc::getMessage('DISCOUNT_COUPON_ENTITY_DATE_APPLY_FIELD') )), 'TYPE' => new Main\Entity\EnumField('TYPE', array( 'column_name' => 'ONE_TIME', 'values' => array(self::TYPE_ONE_ROW, self::TYPE_ONE_ORDER, self::TYPE_NO_LIMIT), 'default_value' => self::TYPE_ONE_ORDER, 'title' => Loc::getMessage('DISCOUNT_COUPON_ENTITY_ONE_TIME_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') ), 'MODIFIED_BY_USER' => new Main\Entity\ReferenceField( 'MODIFIED_BY_USER', '\Bitrix\Main\User', array('=this.MODIFIED_BY' => 'ref.ID') ), 'DISCOUNT' => new Main\Entity\ReferenceField( 'DISCOUNT', '\Bitrix\Catalog\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') ); } /** * 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; } /** * Validate coupon. * * @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'); if (self::$existCouponsManager === null) self::initUseMode(); if (self::$existCouponsManager) { $existCoupon = Sale\DiscountCouponsManager::isExist($value); if (!empty($existCoupon)) { $currentId = (int)(is_array($primary) ? $primary['ID'] : $primary); if ($existCoupon['MODULE'] != 'catalog' || $currentId != $existCoupon['ID']) return Loc::getMessage('DISCOUNT_COUPON_VALIDATOR_COUPON_EXIST'); } } else { $currentId = (int)(is_array($primary) ? $primary['ID'] : $primary); $couponIterator = self::getList(array( 'select' => array('ID'), 'filter' => array('=COUPON' => $value, '!=ID' => $currentId), 'limit' => 1 )); if ($existCoupon = $couponIterator->fetch()) 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); return $result; } /** * 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); return $result; } /** * Delete all coupons for discount. * * @param int $discount Discount id. * @return void */ public static function deleteByDiscount($discount) { $discount = (int)$discount; if ($discount <= 0) return; $conn = Main\Application::getConnection(); $helper = $conn->getSqlHelper(); $conn->queryExecute( 'delete from '.$helper->quote(self::getTableName()).' where '.$helper->quote('DISCOUNT_ID').' = '.$discount ); unset($helper, $conn); } /** * Return methods for coupons manager. * * @param Main\Event $event Event from coupons manager. * @return Main\EventResult */ public static function couponManager(Main\Event $event) { if (self::$existCouponsManager === null) self::initUseMode(); if (!self::$existCouponsManager) { $result = new Main\EventResult(Main\EventResult::ERROR, null, 'catalog'); } else { self::initTypes($event); $result = new Main\EventResult( Main\EventResult::SUCCESS, array( 'mode' => Sale\DiscountCouponsManager::COUPON_MODE_SIMPLE, 'getData' => array('\Bitrix\Catalog\DiscountCouponTable', 'getData'), 'isExist' => array('\Bitrix\Catalog\DiscountCouponTable', 'isExist'), 'saveApplied' => array('\Bitrix\Catalog\DiscountCouponTable', 'saveApplied'), ), 'catalog' ); } return $result; } /** * Return coupon description. * * @param string $coupon Coupon for search. * @return array|false */ public static function getData($coupon) { if (self::$existCouponsManager === null) self::initUseMode(); $couponIterator = self::getList(array( 'select' => array( 'ID', 'COUPON', 'DISCOUNT_ID', 'TYPE', 'ACTIVE', 'DISCOUNT_NAME' => 'DISCOUNT.NAME', 'DISCOUNT_ACTIVE' => 'DISCOUNT.ACTIVE', 'DISCOUNT_ACTIVE_FROM' => 'DISCOUNT.ACTIVE_FROM', 'DISCOUNT_ACTIVE_TO' => 'DISCOUNT.ACTIVE_TO' ), 'filter' => array('=COUPON' => $coupon) )); if ($existCoupon = $couponIterator->fetch()) { if (!empty(self::$types)) { $existCoupon['TYPE'] = ( isset(self::$types[$existCoupon['TYPE']]) ? self::$types[$existCoupon['TYPE']] : self::$typeUnknown ); } return $existCoupon; } return false; } /** * Check existing coupon. * * @param string $coupon Coupon for checking. * @return array|false */ public static function isExist($coupon) { $couponIterator = self::getList(array( 'select' => array('ID', 'COUPON'), 'filter' => array('=COUPON' => $coupon) )); if ($existCoupon = $couponIterator->fetch()) { return array( 'ID' => $existCoupon['ID'], 'COUPON' => $existCoupon['COUPON'], 'MODULE' => 'catalog' ); } return false; } /** * Save apllied coupons. * * @param array $coupons Coupons list. * @param int $userId Order user id. * @param Main\Type\DateTime $currentTime Apply time. * @return array|bool */ public static function saveApplied($coupons, $userId, Main\Type\DateTime $currentTime) { $currentTimestamp = $currentTime->getTimestamp(); if ($userId === null || (int)$userId == 0) return false; if (!is_array($coupons)) $coupons = array($coupons); if (empty($coupons)) return false; Main\Type\Collection::normalizeArrayValuesByInt($coupons); if (empty($coupons)) return false; $deactivateCoupons = array(); $multiCoupons = array(); $couponIterator = self::getList(array( 'select' => array( 'ID', 'COUPON', 'DISCOUNT_ID', 'TYPE', 'ACTIVE', 'DISCOUNT_ACTIVE' => 'DISCOUNT.ACTIVE', 'DISCOUNT_ACTIVE_FROM' => 'DISCOUNT.ACTIVE_FROM', 'DISCOUNT_ACTIVE_TO' => 'DISCOUNT.ACTIVE_TO' ), 'filter' => array('@ID' => $coupons, '=ACTIVE' => 'Y'), 'order' => array('ID' => 'ASC') )); while ($existCoupon = $couponIterator->fetch()) { if ($existCoupon['DISCOUNT_ACTIVE'] != 'Y') 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) ) continue; if ( $existCoupon['TYPE'] == self::TYPE_ONE_ROW || $existCoupon['TYPE'] == self::TYPE_ONE_ORDER ) { $deactivateCoupons[$existCoupon['COUPON']] = $existCoupon['ID']; } else { $multiCoupons[$existCoupon['COUPON']] = $existCoupon['ID']; } } unset($existCoupon, $couponIterator, $coupons); if (!empty($deactivateCoupons) || !empty($multiCoupons)) { $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($multiCoupons)) { $conn->queryExecute( 'update '.$tableName.' set '.$helper->quote('DATE_APPLY').' = '.$helper->getCurrentDateTimeFunction(). ' where '.$helper->quote('ID').' in ('.implode(',', $multiCoupons).')' ); } unset($tableName, $helper); } return array( 'DEACTIVATE' => $deactivateCoupons, 'INCREMENT' => $multiCoupons ); } /** * 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_ONE_ROW => Loc::getMessage('DISCOUNT_COUPON_TABLE_TYPE_ONE_ROW'), self::TYPE_ONE_ORDER => Loc::getMessage('DISCOUNT_COUPON_TABLE_TYPE_ONE_ORDER'), self::TYPE_NO_LIMIT => Loc::getMessage('DISCOUNT_COUPON_TABLE_TYPE_NO_LIMIT') ); } return array(self::TYPE_ONE_ROW, self::TYPE_ONE_ORDER, self::TYPE_NO_LIMIT); } /** * Init use mode. * * @return void */ protected static function initUseMode() { if (self::$existCouponsManager === null) self::$existCouponsManager = Main\ModuleManager::isModuleInstalled('sale') && Main\Loader::includeModule('sale'); } /** * Set types table. * * @param Main\Event $event Manager data. * @return void */ protected static function initTypes(Main\Event $event) { if (self::$existCouponsManager === null) self::initUseMode(); if (!self::$existCouponsManager) return; self::$types = array( self::TYPE_ONE_ROW => Sale\Internals\DiscountCouponTable::TYPE_BASKET_ROW, self::TYPE_ONE_ORDER => Sale\Internals\DiscountCouponTable::TYPE_ONE_ORDER, self::TYPE_NO_LIMIT => Sale\Internals\DiscountCouponTable::TYPE_MULTI_ORDER ); self::$typeUnknown = $event->getParameter('COUPON_UNKNOWN'); } /** * 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(&$result, $data, $keys) { static $currentUserID = false; if ($currentUserID === false) { global $USER; $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(&$result, $data, $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); } }