rendered paste body<?php
/**
* Класс определяет модель запросов. Запросы хранятся в таблице "requests".
*
* Следующие атрибуты доступны в модели, они соответствуют полям в таблице 'requests':
* @property string $id Идентификатор запроса
* @property string $users_id
* @property string $plantations_id
* @property string $types_id
* @property string $sorts_id
* @property integer $boxes_amount
* @property integer $boxes_deal
* @property string $exp_time
* @property string $exp_date
* @property string $status
* @property string $create_date
* @property string $update_date
* @property string $uniq_number
* @property string $aport_delivery
* @property string $order_type
* @property integer $order_id
* @property Money $size_50
* @property Money $size_60
* @property Money $size_70
* @property Money $size_80
* @property Money $size_90
* @property Money $size_100
* @property Money $size_100p
* @property integer $size_mask
* @property integer $submarks_id
* @property integer $agent_id
*
* @package MarketPlace
* @subpackage Requests
* @version SVN: $Id$
* @todo В правила валидации обязательно включить проверку на то, что заказ, к которому приписывается заявка сделан мной
*/
class Requests extends BFActiveRecord {
/**
* Статус заявки находящейся на Market Place
*
* @var string
*/
const STATUS_ON_MARKET = 'on_market';
/**
* Статус заявки снятой с Market Place
*
* @var string
*/
const STATUS_OFF_MARKET = 'off_market';
/**
* Статус для истекшей заявки
*
* @var string
*/
const STATUS_EXPIRED = 'expired';
/**
* Статус для полностью выполненной заявки
*
* @var string
*/
const STATUS_EXECUTED = 'executed';
/**
* Статус для полностью выполненной заявки
*
* @var string
*/
const STATUS_DEAL = 'deal';
/**
* заявка от продавца
*
* @var string
*/
const TYPE_SELLER = 'seller';
/**
* Заявка от покупателя
*
* @var string
*/
const TYPE_BUYER = 'buyer';
/**
* Идентификатор агента для заявок продавца
* Поскольку для заявок продавца не требуется агент - должна использоваться эта константа
*
* @var integer
*/
const ID_AGENT_FOR_SELLERS_REQUEST = -1;
/**
* Идентификатор сабмаркировки для заявок продавца
* Поскольку для заявок продавца не требуется сабмаркировки - должна использоваться эта константа
*
* @var integer
*/
const ID_SUBMARK_FOR_SELLERS_REQUEST = -1;
/**
* Предыдущий статус заявки
*
* @var string
*/
public $old_status = self::STATUS_OFF_MARKET;
/**
* Предыдущее значение кол-ва ящиков в заявке
* Используется для кеширования данных и последующих вычислениях при сохранении
*
* @var integer
*/
private $old_amount;
/**
* Исходное значение кол-ва проданных ящиков
* Используется для кеширования данных и последующих вычислениях при сохранении
*
* @var integer
*/
private $old_deal;
/**
* Исходный номер заказа для заявки
*
* @var integer
*/
private $old_order = -1;
/**
* Максимальное количество одновременно отбираемых заявок
*
* @var integer
*/
public $limit = DEFAULT_ROW_LIMIT;
/**
* С какого элемента начинать выборку
*
* @var integer
*/
public $offset = 0;
/**
* Идентификатор встречной заявки.По-умолчанию null.Если покупаем с рынка, то здесь будет идентификатор заявки для которой мы создаём встречную.
*
* @var integer
*/
public $oppositeRequestId = null;
/**
* Имя плантации
*
* @var string
*/
public $farm_name;
/**
* Имя сорта
*
* @var string
*/
public $sort_name;
/**
* Оставить заявки только от тех, с кем у меня отношения
* @var boolean
*/
public $onlyTrusted;
/**
* Скрыть конкурентов (не выводить заявки от той роли, что и моя), но мои показать
* @var boolean
*/
public $hideCompetitors;
/**
* Геттер для приватного свойства $old_amount
*/
public function getOld_amount() {
return $this->old_amount;
}
/**
* Геттер для приватного свойства $old_deal
*/
public function getOld_deal() {
return $this->old_deal;
}
/**
* Возвращает ссылку на объект модели
*
* @return Requests
*/
public static function model($className = __CLASS__) {
return parent::model($className);
}
/**
* Определяет имя таблицы, в которой хранятся запросы
*
* @return string
*/
public function tableName() {
return 'requests';
}
/**
* Определяет правила валидации входящих данных для определения значения атрибутов модели.
*
* @return array
*/
public function rules() {
return array(
array(
'users_id, plantations_id, types_id, sorts_id, boxes_amount, exp_time, exp_date, status, uniq_number, aport_delivery, order_id',
'required'
),
array(
'order_id, size_mask, submarks_id',
'numerical',
//'integerOnly' => true
),
/*array (
'size_50, size_60, size_70, size_80, size_90, size_100, size_100p, size_std, size_fncy, size_sel',
'numerical'
),*/
array(
'users_id, plantations_id, types_id, sorts_id, boxes_amount, status, uniq_number, order_type',
'length',
'max' => 15
),
array(
'update_date',
'safe'
),
// The following rule is used by search().
// Please remove those attributes that should not be searched.
array(
'id, users_id, plantations_id, types_id, sorts_id, boxes_amount, exp_time, exp_date, status, create_date, update_date, uniq_number, aport_delivery, order_type, order_id, size_50, size_60, size_70, size_80, size_90, size_100, size_100p, size_std, size_fncy, size_sel, size_mask, submarks_id',
'safe',
'on' => 'search'
)
);
}
/**
* Определяет связи с другими моделями в системе
*
* @return array
*/
public function relations() {
return array(
'order' => array(
self::BELONGS_TO,
'Orders',
'order_id'
),
'sorts' => array(
// связь с моделью {@link Sizes}
self::BELONGS_TO,
'Sorts',
'sorts_id'
),
'types' => array(
// связь с моделью {@link Types}
self::BELONGS_TO,
'Types',
'types_id'
),
'plantation' => array(
// связь с моделью {@link Plantation}
self::BELONGS_TO,
'Plantations',
'plantations_id'
),
'sizemask' => array(
// связь с моделью {@link Sizes}
self::BELONGS_TO,
'Sizes',
'size_mask'
),
'sumboxes' => array(
self::STAT,
'Requests',
'boxes_amount',
//'select' => ' SUM(boxes_amount) '
),
'requests_stats' => array(
// связь с моделью {@link RequestsStats}
self::BELONGS_TO,
'RequestsStats',
'plantations_id, types_id, sorts_id',
),
'users' => array(
// связь с моделью {@link RequestsStats}
self::BELONGS_TO,
'Users',
'users_id',
),
'agents' => array(
// связь с моделью {@link RequestsStats}
self::BELONGS_TO,
'Users',
'agent_id',
),
'submarks' => array(
// связь с моделью {@link RequestsStats}
self::BELONGS_TO,
'Submarks',
'submarks_id',
),
);
}
/**
* Определяет имена атрибутов модели
*
* @return array
*/
public function attributeLabels() {
return array(
'id' => 'ID',
'users_id' => Yii::t('tableItems', 'Users'),
'plantations_id' => Yii::t('tableItems', 'Plantation'),
'farm_name' => Yii::t('tableItems', 'Plantation'),
'plantation.name' => Yii::t('tableItems', 'Plantation'),
'types_id' => Yii::t('tableItems', 'Type'),
'sorts_id' => Yii::t('tableItems', 'Sort'),
'sorts.name' => Yii::t('tableItems', 'Sort'),
'sort_name' => Yii::t('tableItems', 'Sort'),
'boxes_amount' => Yii::t('tableItems', 'HB'),
'exp_time' => Yii::t('requests', 'Time to exp'),
'exp_date' => Yii::t('requests', 'Exp Date'),
'status' => Yii::t('tableItems', 'Status'),
'create_date' => Yii::t('tableItems', 'Create Date'),
'update_date' => Yii::t('tableItems', 'Update Date'),
'uniq_number' => Yii::t('requests', 'Offer id'),
'aport_delivery' => Yii::t('requests', 'Aport Delivery'),
'order_type' => Yii::t('requests', 'Order Type'),
'order_id' => Yii::t('requests', 'Order Group'),
'size_50' => Yii::t('tableItems', '50'),
'size_60' => Yii::t('tableItems', '60'),
'size_70' => Yii::t('tableItems', '70'),
'size_80' => Yii::t('tableItems', '80'),
'size_90' => Yii::t('tableItems', '90'),
'size_100' => Yii::t('tableItems', '100'),
'size_100p' => Yii::t('tableItems', '100+'),
'size_std' => Yii::t('tableItems', 'Std'),
'size_fncy' => Yii::t('tableItems', 'Fncy'),
'size_sel' => Yii::t('tableItems', 'Sel'),
'size_mask' => Yii::t('tableItems', 'Size Mask'),
'submarks_id' => Yii::t('requests', 'Submark'),
);
}
/**
* Организует поиск и возвращает список объектов моделей, соответствующих критериям поиска.
*
* @return CActiveDataProvider
*/
public function search($with = array(), $order = '') {
$criteria = new CDbCriteria();
$criteria->compare('id', $this->id);
$criteria->compare('users_id', $this->users_id);
$criteria->compare('plantations_id', $this->plantations_id, false);
$criteria->compare('types_id', $this->types_id, false);
$criteria->compare('sorts_id', $this->sorts_id, false);
$criteria->compare('boxes_amount', $this->boxes_amount);
$criteria->compare('exp_time', $this->exp_time);
$criteria->compare('exp_date', $this->exp_date);
if (is_array( $this->status))
$criteria->addInCondition('t.status', $this->status);
else
$criteria->addSearchCondition('t.status', $this->status);
$criteria->compare('create_date', $this->create_date, true);
$criteria->compare('update_date', $this->update_date, true);
$criteria->compare('uniq_number', $this->uniq_number, true);
$criteria->compare('aport_delivery', $this->aport_delivery, true);
$criteria->compare('order_type', $this->order_type);
$criteria->compare('order_id', $this->order_id);
$criteria->compare('size_50', $this->size_50);
$criteria->compare('size_60', $this->size_60);
$criteria->compare('size_70', $this->size_70);
$criteria->compare('size_80', $this->size_80);
$criteria->compare('size_90', $this->size_90);
$criteria->compare('size_100', $this->size_100);
$criteria->compare('size_100p', $this->size_100p);
$criteria->compare('size_mask', $this->size_mask);
$criteria->compare('submarks_id', $this->submarks_id);
if (!empty($order)) {
$criteria->order = $order;
}
$aWith = $this->relations();
foreach ($with as $condition) {
if (in_array($condition, $aWith)) {
$criteria->with[$condition] = array(
'select' => 'name'
);
}
}
if ($this->hideCompetitors) {
// Скрыть конкурентов (не выводить заявки от той роли, что и моя), но мои показать
if (Yii::app()->user->role == Users::ROLE_BUYER) {
$criteria->addCondition('(`order_type`="' . self::TYPE_SELLER. '" OR `users_id`=' . Yii::app()->user->id . ')', 'AND');
}
elseif (Yii::app()->user->role == Users::ROLE_SELLER) {
$criteria->addCondition('(`order_type`="' . self::TYPE_BUYER. '" OR `users_id`=' . Yii::app()->user->id . ')', 'AND');
}
}
if ($this->onlyTrusted) {
$criteria->with['users'] = array(
'join' => 'LEFT JOIN relations r1 ON users.id = r1.u_1_id LEFT JOIN relations r2 ON users.id = r2.u_2_id',
'condition' => "(r1.type = 'b2s' AND r1.status = 'on' AND r1.u_2_id =" . Yii::app()->user->id . ") OR (r2.type = 'b2s' AND r2.status = 'on' AND r2.u_1_id =" . Yii::app()->user->id . ")"
);
}
$criteria->limit = $this->limit;
$criteria->offset = $this->offset;
return new CActiveDataProvider(get_class($this), array(
'criteria' => $criteria,
'pagination' => criteriaToPaginator::convert($criteria)
));
}
/**
* Список полей, которые нужно привести к/из UTC
* afterFind - при выводе все timestamp, а также некоторые time
* преобразуются из UTC (в которой хранятся), к пользовательской timezone
* beforeSave - перед сохранением некоторые time преобразуются из
* пользовательской timezone в UTC
* по-умолчанию поля типа time закоментированы
* @return array
*/
public function convertDateTime() {
return array(
'afterFind' => array(
//'exp_time',
'exp_date',
'create_date',
'update_date',
),
'beforeSave' => array(
//'exp_time',
),
);
}
/**
* Возвращает список плантаций для текущего пользователя
*
* @return array
*/
public function getPlantationsList() {
$oPlantation = new Plantations();
return CHtml::listData($oPlantation->getPlantationsForUser(Yii::app()->user->id)->getData(), 'id', 'name');
}
/**
* Возвращает список заказов текущего пользователя
*
* @return array
*/
public function getOrdersList() {
$oOrders = new Orders();
return CHtml::listData($oOrders->getOrdersForUser(Yii::app()->user->id)->getData(), 'id', 'name');
}
/**
* Возвращает список типов цветов по указанной плантации
*
* @param integer $iPlantation Идентификатор плантации
* @return array
*/
public function getTypesListByPlantation($iPlantation = -1) {
if (empty($iPlantation) or $iPlantation == -1)
return array();
return PriceList::model()->getTypeForPlantation($iPlantation);
}
/**
* Строит список сортов по идентификатору плантации и типу
*
* @param integer $iType Тип, для которого нужно построить список
* @param integer $iPlantation Идентификатор плантации
* @return array
*/
public function getSortsListByTypesAndPlantation($iType, $iPlantation) {
$aReturn = PriceList::model()->getSortForPlantation($iPlantation, $iType);
if (!empty($aReturn))
return $aReturn['names'];
else
return array();
}
/**
* Метод вызывается перед валидацией данных и подготавливает данные запроса к валидации
*
* @param CModelEvent $oEvent
*/
public function onBeforeValidate($oEvent) {
if (!isset($this->order_id)) {
throw new CHttpException(400, 'Invalid request. Please do not repeat this request again.');
}
$oOrder = new Orders();
$aOrder = $oOrder->findAllByPk($this->order_id);
if (count($aOrder) != 1) {
throw new CHttpException(400, 'Invalid request. Please do not repeat this request again.');
}
$oExpOrderDate = DateTime::createFromFormat(MYSQL_DATETIME_FORMAT, $aOrder[0]->exp_date);
// рассчитываем протухание
$oExpReqDate = new DateTime();
$aExpTime = explode(':', $this->exp_time);
if (!isset($aExpTime[1])) {
$aExpTime[1] = 0; // можем ввести только часы
}
$oExpReqDate = $oExpReqDate->add(new DateInterval('PT' . $aExpTime[0] . 'H' . $aExpTime[1] . 'M'));
if ($oExpReqDate > $oExpOrderDate) {
$oExpReqDate = $oExpOrderDate;
}
$this->exp_date = $oExpReqDate->format(MYSQL_DATETIME_FORMAT);
$this->aport_delivery = $aOrder[0]->air_date;
$this->uniq_number = $this->generateUniqNumber();
if (!($this->size_50 instanceof Money))
$this->size_50 = new Money($this->size_50, Currency::USD_CURRENCY, false);
if (!($this->size_60 instanceof Money))
$this->size_60 = new Money($this->size_60, Currency::USD_CURRENCY, false);
if (!($this->size_70 instanceof Money))
$this->size_70 = new Money($this->size_70, Currency::USD_CURRENCY, false);
if (!($this->size_80 instanceof Money))
$this->size_80 = new Money($this->size_80, Currency::USD_CURRENCY, false);
if (!($this->size_90 instanceof Money))
$this->size_90 = new Money($this->size_90, Currency::USD_CURRENCY, false);
if (!($this->size_100 instanceof Money))
$this->size_100 = new Money($this->size_100, Currency::USD_CURRENCY, false);
if (!($this->size_100p instanceof Money))
$this->size_100p = new Money($this->size_100p, Currency::USD_CURRENCY, false);
return parent::onBeforeValidate($oEvent);
}
/**
* Сохраняет запрос и отправляет (если необходимо) информацию о нем в очередь.
* Внимание! Выполнение метода должно проходить в рамках транзакции!!!
*
* Необходимость:
* - запрос доступен для покупки
* - запрос был от продавца,
* - в нем еще есть ящики для покупки
* - если заявка новая - для нее будет поставлена задача на протухание
*/
public function saveAndSendToQueue() {
$bReturn = false;
$q = new QueueTask();
$isNew = false;
if ($this->getIsNewRecord()) {
$isNew = true;
}
if (!($id = parent::save())) {
$bReturn = false;
}
else {
if ($isNew) {
$date = new DateTime($this->exp_date);
if ($q->add('ProcessingRequestExpired', array(
$this->id
), $date->getTimestamp(), //date(MYSQL_DATETIME_FORMAT, $this->exp_date),
QueueTask::LEVEL_HIGHT)) {
$bReturn = true;
}
}
if ($this->status === self::STATUS_ON_MARKET and $this->boxes_amount > 0 and $this->order_type == self::TYPE_SELLER) {
if ($q->add('ProcessingDeal', array(
$this->id
), time(), QueueTask::LEVEL_IMMEDIATE)) {
$bReturn = true;
}
else {
$bReturn = false;
}
}
else {
$bReturn = true;
}
}
unset($q);
return $bReturn;
}
/**
* Возвращает тип запроса (по сути - кто его сделал)
*
* @param string $sUserRole Роль пользователя
* @return string
* @exception Для ролей, отличных от покупателя или продавца будет брошено исключение
*/
public function getOrderType($sUserRole) {
if ($sUserRole == Users::ROLE_BUYER) {
return self::TYPE_BUYER;
}
elseif ($sUserRole == Users::ROLE_SELLER) {
return self::TYPE_SELLER;
}
else {
throw new CHttpException(400, 'Invalid request. Please do not repeat this request again.');
}
}
/**
* Генерирует уникальный идентификатор запроса
* @link http://redmine.biflorica.com/projects/bif/wiki/Идентификатор_сделки
*
* @return string
*/
private function generateUniqNumber() {
$oSequence = new Sequence();
return $oSequence->getUniqNumber(Yii::app()->user->role);
}
/**
* Возвращает true, если заявка выполнена, иначе - false
*
* @return boolean
*/
public function isCompleted() {
return ($this->boxes_amount == 0);
}
/**
* Выставляет или снимает (в зависимости от текущего статуса) заявку на маркет.
* Если заявка просрочена или уже куплена будет возвращено false
*
* @return boolean
*/
public function moveToOrFromMarketPlace() {
if ($this->status !== self::STATUS_OFF_MARKET and $this->status !== self::STATUS_ON_MARKET) {
return false;
}
$order = Orders::model()->findByPk($this->order_id);
if (is_null($order)) {
return false;
}
if ($this->status == self::STATUS_OFF_MARKET) {
$this->status = self::STATUS_ON_MARKET;
$iDeltaBoxes = array(
$this->boxes_amount,
-$this->boxes_amount
);
}
elseif ($this->status == self::STATUS_ON_MARKET) {
$this->status = self::STATUS_OFF_MARKET;
$iDeltaBoxes = array(
-$this->boxes_amount,
$this->boxes_amount
);
}
$bReturn = $this->saveAndSendToQueue();
if ($bReturn) {
$order->changeCountMarketRequests($iDeltaBoxes[0], $iDeltaBoxes[1]);
}
return $bReturn;
}
/**
* Клонирует объект
*
* @param Requests $oFrom Объект, от которого происходит клонирование
*/
public function cloneFrom(Requests $oFrom) {
$aAtributes = $oFrom->getAttributes();
if ($aAtributes['boxes_amount']==0)
{
$aAtributes['boxes_amount'] = $aAtributes['boxes_deal'];
$aAtributes['boxes_deal'] = 0;
}
$aAtributes['uniq_number'] = $this->generateUniqNumber();
$aAtributes['update_date'] = null;
$aAtributes['status'] = self::STATUS_OFF_MARKET;
unset($aAtributes['create_date']);
unset($aAtributes['id']);
$this->setAttributes($aAtributes, false);
return $this->saveAndSendToQueue();
}
/**
* Добавляет коробки обратно в заявку (после отмены сделки)
*
* @param integer $boxes_amount количество коробок
* @param array $dealData Массив с исходным цена для сделки. Пример array('size_50'=>'1.56', и т.д. для всех размеров)
*/
public function addCanceledBoxesFromDeal($boxes_amount, $dealData) {
$currentTime = new DateTime("now");
// Проверим изменились ли исходные данные заявки
$isReqChanged = false;
foreach (FlowersSizes::getAllSize() as $size) {
$size = 'size_' . $size;
if (!empty($this->$size) AND !empty($dealData->$size) AND $this->$size != $dealData->$size) {
$isReqChanged = true;
break;
}
}
if ($isReqChanged) {
// исходная заявка изменилась
// Значит создаём новую заявку
$newReq = clone $this;
$newReq->boxes_amount = $this->boxes_amount + $boxes_amount;
$newReq->boxes_deal = $newReq->boxes_deal - $boxes_amount;
$newReq->status = (($newReq->order_type == Requests::TYPE_SELLER AND Yii::app()->user->role == Users::ROLE_BUYER) OR ($newReq->order_type == Requests::TYPE_BUYER AND Yii::app()->user->role == Users::ROLE_SELLER)) ? Requests::STATUS_ON_MARKET : Requests::STATUS_OFF_MARKET;
$newReq->create_date = $currentTime->format(MYSQL_DATETIME_FORMAT);
foreach (FlowersSizes::getAllSize() as $size) {
$newReq->{'size_' . $size} = $dealData->{'size_' . $size};
}
$newReq->save();
}
else {
// исходная заявка не изменилась
// Значит просто добавим ящики
$this->boxes_amount = $this->boxes_amount + $boxes_amount;
$this->boxes_deal = $this->boxes_deal - $boxes_amount;
$this->status = (($this->order_type == Requests::TYPE_SELLER AND Yii::app()->user->role == Users::ROLE_BUYER) OR ($this->order_type == Requests::TYPE_BUYER AND Yii::app()->user->role == Users::ROLE_SELLER)) ? Requests::STATUS_ON_MARKET : Requests::STATUS_OFF_MARKET;
$this->update_date = $currentTime->format(MYSQL_DATETIME_FORMAT);
$this->save();
}
}
/**
* Вызывается перед сохранение данных, которые и приводятся к правильному виду
*
* @todo Вынести проверку заказа в валидацию
* @return boolean
*/
public function beforeSave() {
$this->size_50 = $this->size_50->getValue();
$this->size_60 = $this->size_60->getValue();
$this->size_70 = $this->size_70->getValue();
$this->size_80 = $this->size_80->getValue();
$this->size_90 = $this->size_90->getValue();
$this->size_100 = $this->size_100->getValue();
$this->size_100p = $this->size_100p->getValue();
$this->size_mask = $this->countSizeMask();
// Проверка на то, что заявка попадает в заказ того пользователя, который с ней работает
if (!Orders::model()->isBelongsToUser($this->order_id, $this->users_id)) {
$this->addError('order_id', 'Access denied');
return false;
}
// пересчитать кол-во ящиков для всего заказа
$oOrder = Orders::model()->findByPk($this->order_id);
/* @var $oOrder Orders */
if (!$this->getIsNewRecord()) { // изменение существующей заявки
Yii::app()->getComponent('ChangeBoxesCountHelper')->prepareBoxesChange($this);
}
else {
// создание новой заявки
if ($this->status == self::STATUS_ON_MARKET) {
$result = $oOrder->changeCountMarketRequests($this->boxes_amount, null);
if (!$result)
return false;
}
elseif ($this->status == self::STATUS_OFF_MARKET) {
$result = $oOrder->changeCountMarketRequests(null, $this->boxes_amount);
if (!$result)
return false;
}
}
return parent::beforeSave();
}
/**
* Вызывается перед удалением заявки.
* Используется для изменения кол-ва ящиков в заказе
*
*/
public function beforeDelete() {
parent::beforeDelete();
$this->boxes_amount = 0;
$this->boxes_deal = 0;
Yii::app()->getComponent('ChangeBoxesCountHelper')->prepareBoxesChange($this);
return true;
}
/**
* Вычисляет size_mark
* @return integer
*/
private function countSizeMask() {
$sizeMask = 0;
if ($this->size_50 > 0) {
$sizeMask += 1;
}
if ($this->size_60 > 0) {
$sizeMask += 2;
}
if ($this->size_70 > 0) {
$sizeMask += 4;
}
if ($this->size_80 > 0) {
$sizeMask += 8;
}
if ($this->size_90 > 0) {
$sizeMask += 16;
}
if ($this->size_100 > 0) {
$sizeMask += 32;
}
if ($this->size_100p > 0) {
$sizeMask += 64;
}
return $sizeMask;
}
/**
* Высчитывает размер цветов в заявке по ее маске
*
*/
public function getSizeByMask() {
$size = array();
$this->getMaxSize($this->size_mask, 64, $size);
return $size;
}
/**
* Высчитывает размер цветов в заявке по ее маске
* Используется для отделения основного метода от рекурсивной реализации
*/
private function getMaxSize($size, $factor, &$aSize=array()) {
if ($factor<1)
return;
if ($size>$factor) {
$aSize[] = $factor;
$this->getMaxSize($size-$factor, $factor/2, $aSize);
}
else {
$this->getMaxSize($size, $factor/2, $aSize);
}
}
/**
* Организует сохранение запроса
*
* @param boolean $runValidation
* @param array $attributes
*/
public function save($runValidation = true, $attributes = null) {
if (empty($this->oppositeRequestId) and $this->status == self::STATUS_ON_MARKET and $this->order_type == self::TYPE_SELLER and $this->isNewRecord) {
return $this->saveAndSendToQueue();
}
else {
return parent::save($runValidation, $attributes);
}
}
/**
* Подготавливает данные для работы - приводит типы и т.д.
*/
function afterSave() {
$return = parent::afterSave();
if ($return === false)
return false;
$this->size_50 = new Money($this->size_50);
$this->size_60 = new Money($this->size_60);
$this->size_70 = new Money($this->size_70);
$this->size_80 = new Money($this->size_80);
$this->size_90 = new Money($this->size_90);
$this->size_100 = new Money($this->size_100);
$this->size_100p = new Money($this->size_100p);
RequestsStats::model()->updateByRequest($this);
if ($this->order_type == Requests::TYPE_SELLER) {
RequestsDaily::model()->updateByRequest($this);
}
return $return;
}
/**
* Метод вызывается после поиска данных и подготавливает данные
*
*/
public function afterFind() {
$return = parent::afterFind();
$this->size_50 = new Money($this->size_50);
$this->size_60 = new Money($this->size_60);
$this->size_70 = new Money($this->size_70);
$this->size_80 = new Money($this->size_80);
$this->size_90 = new Money($this->size_90);
$this->size_100 = new Money($this->size_100);
$this->size_100p = new Money($this->size_100p);
// закешили данные, при сохранении будем смотреть что поменялось
$this->old_amount = $this->boxes_amount;
$this->old_status = $this->status;
$this->old_deal = $this->boxes_deal;
$this->old_order = $this->order_id;
return $return;
}
/**
* Проверяет название размера
*
* @param string $name
* @return boolean
*/
public function checkSize($name) {
return (isset($this->{$name}) && $this->{$name}->getValue() > 0);
}
/**
* Получается статистические данные по конкретному заказу
*
* @param array $iOrderId номер заказ
* @return array
*/
public function buildStats($aOrderId) {
$rows = Yii::app()->db->createCommand("SELECT COUNT(*) as count, status FROM `requests` WHERE order_id IN(" . implode(',',$aOrderId) . ") GROUP BY `status`")->queryAll();
foreach ($rows as $row) {
$result[$row['status']] = $row['count'];
}
return array(
'on_market' => (isset($result['on_market'])) ? $result['on_market'] : 0,
'off_market' => (isset($result['off_market'])) ? $result['off_market'] : 0,
'deals' => (isset($result['executed'])) ? $result['executed'] : 0,
'cancel' => (isset($result['expired'])) ? $result['expired'] : 0,
);
}
public function isExpired()
{
return $this->status==self::STATUS_EXPIRED;
}
public function isOffMarket()
{
return $this->status==self::STATUS_OFF_MARKET;
}
}