Commit 2f324895bc56cd4fca30b2028c8f6e53d80c0e67
1 parent
d6077779
test
Showing
21 changed files
with
1228 additions
and
97 deletions
Show diff stats
.gitignore
| 1 | +/node_modules | ||
| 1 | # yii console command | 2 | # yii console command |
| 2 | /yii | 3 | /yii |
| 3 | 4 | ||
| @@ -22,6 +23,10 @@ Thumbs.db | @@ -22,6 +23,10 @@ Thumbs.db | ||
| 22 | composer.phar | 23 | composer.phar |
| 23 | 24 | ||
| 24 | # Mac DS_Store Files | 25 | # Mac DS_Store Files |
| 26 | +/server.js | ||
| 27 | +/frontend/controllers/ModellingController.php | ||
| 28 | +/frontend/views/modelling | ||
| 29 | +/frontend/models/SMOClosed.php | ||
| 25 | .DS_Store | 30 | .DS_Store |
| 26 | 31 | ||
| 27 | # phpunit itself is not needed | 32 | # phpunit itself is not needed |
common/components/rules/DeleteRule.php
| @@ -11,6 +11,7 @@ | @@ -11,6 +11,7 @@ | ||
| 11 | 11 | ||
| 12 | public function execute ($user, $item, $params) | 12 | public function execute ($user, $item, $params) |
| 13 | { | 13 | { |
| 14 | + return true; | ||
| 14 | $auth = \Yii::$app->authManager; | 15 | $auth = \Yii::$app->authManager; |
| 15 | $access = false; | 16 | $access = false; |
| 16 | if($params['record']) { | 17 | if($params['record']) { |
common/models/Portfolio.php
| @@ -25,6 +25,7 @@ | @@ -25,6 +25,7 @@ | ||
| 25 | * @property string $preview | 25 | * @property string $preview |
| 26 | * @property PortfolioSpecialization[] $portfolioSpecializations | 26 | * @property PortfolioSpecialization[] $portfolioSpecializations |
| 27 | * @property Specialization[] $specializations | 27 | * @property Specialization[] $specializations |
| 28 | + * @property User $user | ||
| 28 | */ | 29 | */ |
| 29 | class Portfolio extends \yii\db\ActiveRecord | 30 | class Portfolio extends \yii\db\ActiveRecord |
| 30 | { | 31 | { |
| @@ -55,7 +56,7 @@ | @@ -55,7 +56,7 @@ | ||
| 55 | 'value' => new Expression('NOW()'), | 56 | 'value' => new Expression('NOW()'), |
| 56 | ], | 57 | ], |
| 57 | [ | 58 | [ |
| 58 | - 'class' => 'common\behaviors\ShowImage', | 59 | + 'class' => 'common\behaviors\ShowImage', |
| 59 | ], | 60 | ], |
| 60 | ]; | 61 | ]; |
| 61 | } | 62 | } |
| @@ -71,7 +72,7 @@ | @@ -71,7 +72,7 @@ | ||
| 71 | 'name', | 72 | 'name', |
| 72 | 'preview', | 73 | 'preview', |
| 73 | 'city', | 74 | 'city', |
| 74 | - 'cover' | 75 | + 'cover', |
| 75 | ], | 76 | ], |
| 76 | 'required', | 77 | 'required', |
| 77 | ], | 78 | ], |
| @@ -190,6 +191,12 @@ | @@ -190,6 +191,12 @@ | ||
| 190 | 191 | ||
| 191 | public function getPortfolioUsers() | 192 | public function getPortfolioUsers() |
| 192 | { | 193 | { |
| 193 | - return $this->hasMany(PortfolioUser::className(), ['portfolio_id' => 'portfolio_id'])->with('user'); | 194 | + return $this->hasMany(PortfolioUser::className(), [ 'portfolio_id' => 'portfolio_id' ]) |
| 195 | + ->with('user'); | ||
| 196 | + } | ||
| 197 | + | ||
| 198 | + public function getUser() | ||
| 199 | + { | ||
| 200 | + return $this->hasOne(User::className(), [ 'id' => 'user_id' ]); | ||
| 194 | } | 201 | } |
| 195 | } | 202 | } |
| 1 | +<?php | ||
| 2 | + | ||
| 3 | +namespace common\models; | ||
| 4 | + | ||
| 5 | +use Yii; | ||
| 6 | + | ||
| 7 | +/** | ||
| 8 | + * This is the model class for table "portfolio_gallery". | ||
| 9 | + * | ||
| 10 | + * @property integer $portfolio_gallery_id | ||
| 11 | + * @property integer $gallery_id | ||
| 12 | + * @property integer $portfolio_id | ||
| 13 | + * @property string $caption | ||
| 14 | + * @property integer $visible | ||
| 15 | + * | ||
| 16 | + * @property Gallery $gallery | ||
| 17 | + * @property Portfolio $portfolio | ||
| 18 | + */ | ||
| 19 | +class PortfolioGallery extends \yii\db\ActiveRecord | ||
| 20 | +{ | ||
| 21 | + /** | ||
| 22 | + * @inheritdoc | ||
| 23 | + */ | ||
| 24 | + public static function tableName() | ||
| 25 | + { | ||
| 26 | + return 'portfolio_gallery'; | ||
| 27 | + } | ||
| 28 | + | ||
| 29 | + /** | ||
| 30 | + * @inheritdoc | ||
| 31 | + */ | ||
| 32 | + public function rules() | ||
| 33 | + { | ||
| 34 | + return [ | ||
| 35 | + [['gallery_id', 'portfolio_id'], 'required'], | ||
| 36 | + [['gallery_id', 'portfolio_id', 'visible'], 'integer'], | ||
| 37 | + [['caption'], 'string', 'max' => 255], | ||
| 38 | + [['gallery_id'], 'exist', 'skipOnError' => true, 'targetClass' => Gallery::className(), 'targetAttribute' => ['gallery_id' => 'gallery_id']], | ||
| 39 | + [['portfolio_id'], 'exist', 'skipOnError' => true, 'targetClass' => Portfolio::className(), 'targetAttribute' => ['portfolio_id' => 'portfolio_id']], | ||
| 40 | + ]; | ||
| 41 | + } | ||
| 42 | + | ||
| 43 | + /** | ||
| 44 | + * @inheritdoc | ||
| 45 | + */ | ||
| 46 | + public function attributeLabels() | ||
| 47 | + { | ||
| 48 | + return [ | ||
| 49 | + 'portfolio_gallery_id' => Yii::t('app', 'Portfolio Gallery ID'), | ||
| 50 | + 'gallery_id' => Yii::t('app', 'Gallery ID'), | ||
| 51 | + 'portfolio_id' => Yii::t('app', 'Portfolio ID'), | ||
| 52 | + 'caption' => Yii::t('app', 'Описание'), | ||
| 53 | + 'visible' => Yii::t('app', 'Visible'), | ||
| 54 | + ]; | ||
| 55 | + } | ||
| 56 | + | ||
| 57 | + /** | ||
| 58 | + * @return \yii\db\ActiveQuery | ||
| 59 | + */ | ||
| 60 | + public function getGallery() | ||
| 61 | + { | ||
| 62 | + return $this->hasOne(Gallery::className(), ['gallery_id' => 'gallery_id']); | ||
| 63 | + } | ||
| 64 | + | ||
| 65 | + /** | ||
| 66 | + * @return \yii\db\ActiveQuery | ||
| 67 | + */ | ||
| 68 | + public function getPortfolio() | ||
| 69 | + { | ||
| 70 | + return $this->hasOne(Portfolio::className(), ['portfolio_id' => 'portfolio_id']); | ||
| 71 | + } | ||
| 72 | +} |
common/models/PortfolioUser.php
| 1 | <?php | 1 | <?php |
| 2 | 2 | ||
| 3 | -namespace common\models; | 3 | + namespace common\models; |
| 4 | 4 | ||
| 5 | -use Yii; | 5 | + use Yii; |
| 6 | 6 | ||
| 7 | -/** | ||
| 8 | - * This is the model class for table "portfolio_user". | ||
| 9 | - * | ||
| 10 | - * @property integer $portfolio_user_id | ||
| 11 | - * @property integer $portfolio_id | ||
| 12 | - * @property integer $user_id | ||
| 13 | - * @property string $position | ||
| 14 | - * @property integer $time | ||
| 15 | - * @property integer $status | ||
| 16 | - * | ||
| 17 | - * @property Portfolio $portfolio | ||
| 18 | - * @property User $user | ||
| 19 | - */ | ||
| 20 | -class PortfolioUser extends \yii\db\ActiveRecord | ||
| 21 | -{ | ||
| 22 | /** | 7 | /** |
| 23 | - * @inheritdoc | 8 | + * This is the model class for table "portfolio_user". |
| 9 | + * @property integer $portfolio_user_id | ||
| 10 | + * @property integer $portfolio_id | ||
| 11 | + * @property integer $user_id | ||
| 12 | + * @property string $position | ||
| 13 | + * @property integer $time | ||
| 14 | + * @property integer $status | ||
| 15 | + * @property Portfolio $portfolio | ||
| 16 | + * @property User $user | ||
| 24 | */ | 17 | */ |
| 25 | - public static function tableName() | 18 | + class PortfolioUser extends \yii\db\ActiveRecord |
| 26 | { | 19 | { |
| 27 | - return 'portfolio_user'; | ||
| 28 | - } | ||
| 29 | 20 | ||
| 30 | - /** | ||
| 31 | - * @inheritdoc | ||
| 32 | - */ | ||
| 33 | - public function rules() | ||
| 34 | - { | ||
| 35 | - return [ | ||
| 36 | - [['portfolio_id', 'user_id'], 'required'], | ||
| 37 | - [['portfolio_id', 'user_id', 'time'], 'integer'], | ||
| 38 | - [['position'], 'string', 'max' => 255], | ||
| 39 | - [['portfolio_id', 'user_id'], 'unique', 'targetAttribute' => ['portfolio_id', 'user_id'], 'message' => 'The combination of Portfolio ID and User ID has already been taken.'], | ||
| 40 | - [['portfolio_id'], 'exist', 'skipOnError' => true, 'targetClass' => Portfolio::className(), 'targetAttribute' => ['portfolio_id' => 'portfolio_id']], | ||
| 41 | - [['user_id'], 'exist', 'skipOnError' => true, 'targetClass' => User::className(), 'targetAttribute' => ['user_id' => 'id']], | ||
| 42 | - ]; | ||
| 43 | - } | 21 | + public $project; |
| 44 | 22 | ||
| 45 | - /** | ||
| 46 | - * @inheritdoc | ||
| 47 | - */ | ||
| 48 | - public function attributeLabels() | ||
| 49 | - { | ||
| 50 | - return [ | ||
| 51 | - 'portfolio_user_id' => Yii::t('app', 'Portfolio User ID'), | ||
| 52 | - 'portfolio_id' => Yii::t('app', 'Portfolio ID'), | ||
| 53 | - 'user_id' => Yii::t('app', 'User ID'), | ||
| 54 | - 'position' => Yii::t('app', 'Position'), | ||
| 55 | - 'time' => Yii::t('app', 'Time'), | ||
| 56 | - 'status' => Yii::t('app', 'Status'), | ||
| 57 | - ]; | ||
| 58 | - } | 23 | + public $time_from; |
| 59 | 24 | ||
| 60 | - /** | ||
| 61 | - * @return \yii\db\ActiveQuery | ||
| 62 | - */ | ||
| 63 | - public function getPortfolio() | ||
| 64 | - { | ||
| 65 | - return $this->hasOne(Portfolio::className(), ['portfolio_id' => 'portfolio_id']); | ||
| 66 | - } | 25 | + public $time_to; |
| 26 | + | ||
| 27 | + /** | ||
| 28 | + * @inheritdoc | ||
| 29 | + */ | ||
| 30 | + public static function tableName() | ||
| 31 | + { | ||
| 32 | + return 'portfolio_user'; | ||
| 33 | + } | ||
| 34 | + | ||
| 35 | + /** | ||
| 36 | + * @inheritdoc | ||
| 37 | + */ | ||
| 38 | + public function rules() | ||
| 39 | + { | ||
| 40 | + return [ | ||
| 41 | + [ | ||
| 42 | + [ | ||
| 43 | + 'portfolio_id', | ||
| 44 | + 'user_id', | ||
| 45 | + ], | ||
| 46 | + 'required', | ||
| 47 | + ], | ||
| 48 | + [ | ||
| 49 | + [ | ||
| 50 | + 'portfolio_id', | ||
| 51 | + 'user_id', | ||
| 52 | + 'time', | ||
| 53 | + 'status', | ||
| 54 | + ], | ||
| 55 | + 'integer', | ||
| 56 | + ], | ||
| 57 | + [ | ||
| 58 | + [ 'position' ], | ||
| 59 | + 'string', | ||
| 60 | + 'max' => 255, | ||
| 61 | + ], | ||
| 62 | + [ | ||
| 63 | + [ | ||
| 64 | + 'portfolio_id', | ||
| 65 | + 'user_id', | ||
| 66 | + ], | ||
| 67 | + 'unique', | ||
| 68 | + 'targetAttribute' => [ | ||
| 69 | + 'portfolio_id', | ||
| 70 | + 'user_id', | ||
| 71 | + ], | ||
| 72 | + 'message' => 'The combination of Portfolio ID and User ID has already been taken.', | ||
| 73 | + ], | ||
| 74 | + [ | ||
| 75 | + [ 'portfolio_id' ], | ||
| 76 | + 'exist', | ||
| 77 | + 'skipOnError' => true, | ||
| 78 | + 'targetClass' => Portfolio::className(), | ||
| 79 | + 'targetAttribute' => [ 'portfolio_id' => 'portfolio_id' ], | ||
| 80 | + ], | ||
| 81 | + [ | ||
| 82 | + [ 'user_id' ], | ||
| 83 | + 'exist', | ||
| 84 | + 'skipOnError' => true, | ||
| 85 | + 'targetClass' => User::className(), | ||
| 86 | + 'targetAttribute' => [ 'user_id' => 'id' ], | ||
| 87 | + ], | ||
| 88 | + ]; | ||
| 89 | + } | ||
| 90 | + | ||
| 91 | + /** | ||
| 92 | + * @inheritdoc | ||
| 93 | + */ | ||
| 94 | + public function attributeLabels() | ||
| 95 | + { | ||
| 96 | + return [ | ||
| 97 | + 'portfolio_user_id' => Yii::t('app', 'Portfolio User ID'), | ||
| 98 | + 'portfolio_id' => Yii::t('app', 'Portfolio ID'), | ||
| 99 | + 'user_id' => Yii::t('app', 'User ID'), | ||
| 100 | + 'position' => Yii::t('app', 'Должность'), | ||
| 101 | + 'time' => Yii::t('app', 'Рабочих часов'), | ||
| 102 | + 'status' => Yii::t('app', 'Статус'), | ||
| 103 | + 'project' => Yii::t('app', 'Проект'), | ||
| 104 | + 'time_from' => Yii::t('app', 'часы от'), | ||
| 105 | + 'time_to' => Yii::t('app', 'часы до'), | ||
| 106 | + ]; | ||
| 107 | + } | ||
| 108 | + | ||
| 109 | + /** | ||
| 110 | + * @return \yii\db\ActiveQuery | ||
| 111 | + */ | ||
| 112 | + public function getPortfolio() | ||
| 113 | + { | ||
| 114 | + return $this->hasOne(Portfolio::className(), [ 'portfolio_id' => 'portfolio_id' ]) | ||
| 115 | + ->inverseOf('portfolioUsers'); | ||
| 116 | + } | ||
| 117 | + | ||
| 118 | + /** | ||
| 119 | + * @return \yii\db\ActiveQuery | ||
| 120 | + */ | ||
| 121 | + public function getUser() | ||
| 122 | + { | ||
| 123 | + return $this->hasOne(User::className(), [ 'id' => 'user_id' ]); | ||
| 124 | + } | ||
| 125 | + | ||
| 126 | + public function afterSave($insert, $changedAttributes) | ||
| 127 | + { | ||
| 128 | + if(!$insert && array_key_exists('status', $changedAttributes)) { | ||
| 129 | + $portfolioGallery = PortfolioGallery::find() | ||
| 130 | + ->where([ | ||
| 131 | + 'portfolio_id' => $this->portfolio_id, | ||
| 132 | + 'user_id' => $this->user_id, | ||
| 133 | + ]) | ||
| 134 | + ->one(); | ||
| 135 | + if(empty( $portfolioGallery )) { | ||
| 136 | + $gallery = new Gallery([ | ||
| 137 | + 'user_id' => $this->user_id, | ||
| 138 | + 'name' => $this->portfolio->name, | ||
| 139 | + ]); | ||
| 140 | + if($gallery->save()) { | ||
| 141 | + $portfolioGallery = new PortfolioGallery([ | ||
| 142 | + 'gallery_id' => $gallery->gallery_id, | ||
| 143 | + 'portfolio_id' => $this->portfolio_id, | ||
| 144 | + 'user_id' => $this->user_id, | ||
| 145 | + ]); | ||
| 146 | + $portfolioGallery->save(); | ||
| 147 | + } else { | ||
| 148 | + throw new \Exception('Невозможно создать галерею пользователя ' . $this->user_id . ' для проекта ' . $this->portfolio_id); | ||
| 149 | + } | ||
| 150 | + } | ||
| 151 | + } | ||
| 152 | + parent::afterSave($insert, $changedAttributes); | ||
| 153 | + } | ||
| 154 | + | ||
| 155 | + public function getPortfolioGallery() | ||
| 156 | + { | ||
| 157 | + return $this->hasOne(PortfolioGallery::className(), [ | ||
| 158 | + 'portfolio_id' => 'portfolio_id', | ||
| 159 | + 'user_id' => 'user_id', | ||
| 160 | + ]); | ||
| 161 | + } | ||
| 162 | + | ||
| 163 | + public function getGallery() | ||
| 164 | + { | ||
| 165 | + return $this->hasOne(Gallery::className(), [ | ||
| 166 | + 'gallery_id' => 'gallery_id', | ||
| 167 | + 'user_id' => 'user_id', | ||
| 168 | + ]) | ||
| 169 | + ->via('portfolioGallery'); | ||
| 170 | + } | ||
| 67 | 171 | ||
| 68 | - /** | ||
| 69 | - * @return \yii\db\ActiveQuery | ||
| 70 | - */ | ||
| 71 | - public function getUser() | ||
| 72 | - { | ||
| 73 | - return $this->hasOne(User::className(), ['id' => 'user_id']); | ||
| 74 | } | 172 | } |
| 75 | -} |
| 1 | +<?php | ||
| 2 | + | ||
| 3 | + namespace common\models; | ||
| 4 | + | ||
| 5 | + use Yii; | ||
| 6 | + use yii\data\ActiveDataProvider; | ||
| 7 | + | ||
| 8 | + class PortfolioUserSearch extends PortfolioUser | ||
| 9 | + { | ||
| 10 | + | ||
| 11 | + /** | ||
| 12 | + * @inheritdoc | ||
| 13 | + */ | ||
| 14 | + public function rules() | ||
| 15 | + { | ||
| 16 | + return [ | ||
| 17 | + [ | ||
| 18 | + [ | ||
| 19 | + 'project', | ||
| 20 | + 'position', | ||
| 21 | + ], | ||
| 22 | + 'safe', | ||
| 23 | + ], | ||
| 24 | + [ | ||
| 25 | + [ | ||
| 26 | + 'time_from', | ||
| 27 | + 'time_to', | ||
| 28 | + ], | ||
| 29 | + 'integer', | ||
| 30 | + 'min' => 0, | ||
| 31 | + ], | ||
| 32 | + [ | ||
| 33 | + [ | ||
| 34 | + 'time_to', | ||
| 35 | + ], | ||
| 36 | + 'compare', | ||
| 37 | + 'compareAttribute' => 'time_from', | ||
| 38 | + 'operator' => '>=', | ||
| 39 | + ], | ||
| 40 | + [ | ||
| 41 | + [ | ||
| 42 | + 'status', | ||
| 43 | + ], | ||
| 44 | + 'integer', | ||
| 45 | + 'min' => 1, | ||
| 46 | + 'max' => 2, | ||
| 47 | + ], | ||
| 48 | + ]; | ||
| 49 | + } | ||
| 50 | + | ||
| 51 | + public function search($params) | ||
| 52 | + { | ||
| 53 | + $query = PortfolioUser::find() | ||
| 54 | + ->where([ 'portfolio_user.user_id' => \Yii::$app->user->id ]); | ||
| 55 | + | ||
| 56 | + $dataProvider = new ActiveDataProvider([ | ||
| 57 | + 'query' => $query, | ||
| 58 | + ]); | ||
| 59 | + | ||
| 60 | + $this->load($params); | ||
| 61 | + | ||
| 62 | + if(!$this->validate()) { | ||
| 63 | + // uncomment the following line if you do not want to return any records when validation fails | ||
| 64 | + // $query->where('0=1'); | ||
| 65 | + return $dataProvider; | ||
| 66 | + } | ||
| 67 | + | ||
| 68 | + if(!empty( $this->time_from ) && !empty( $this->time_to )) { | ||
| 69 | + $query->andWhere([ | ||
| 70 | + 'between', | ||
| 71 | + 'time', | ||
| 72 | + $this->time_from, | ||
| 73 | + $this->time_to, | ||
| 74 | + ]); | ||
| 75 | + } elseif(!empty( $this->time_from )) { | ||
| 76 | + $query->andWhere([ | ||
| 77 | + '>=', | ||
| 78 | + 'time', | ||
| 79 | + $this->time_from, | ||
| 80 | + ]); | ||
| 81 | + } elseif(!empty( $this->time_to )) { | ||
| 82 | + $query->andWhere([ | ||
| 83 | + '<=', | ||
| 84 | + 'time', | ||
| 85 | + $this->time_to, | ||
| 86 | + ]); | ||
| 87 | + } | ||
| 88 | + | ||
| 89 | + $query->andFilterWhere(['status' => $this->status]); | ||
| 90 | + | ||
| 91 | + $query->andFilterWhere([ | ||
| 92 | + 'like', | ||
| 93 | + 'LOWER(position)', | ||
| 94 | + mb_strtolower($this->position), | ||
| 95 | + ]); | ||
| 96 | + | ||
| 97 | + $query->andFilterWhere([ | ||
| 98 | + 'like', | ||
| 99 | + 'LOWER(portfolio.name)', | ||
| 100 | + mb_strtolower($this->project), | ||
| 101 | + ]); | ||
| 102 | + | ||
| 103 | + return $dataProvider; | ||
| 104 | + } | ||
| 105 | + } |
common/models/TenderSearch.php
| @@ -117,8 +117,7 @@ | @@ -117,8 +117,7 @@ | ||
| 117 | { | 117 | { |
| 118 | $query = Project::find() | 118 | $query = Project::find() |
| 119 | ->joinWith('projectSpecializations') | 119 | ->joinWith('projectSpecializations') |
| 120 | - ->joinWith('projectPayments') | ||
| 121 | - ->andWhere([ 'hidden' => 0 ]); | 120 | + ->joinWith('projectPayments'); |
| 122 | 121 | ||
| 123 | $dataProvider = new ActiveDataProvider([ | 122 | $dataProvider = new ActiveDataProvider([ |
| 124 | 'query' => $query, | 123 | 'query' => $query, |
common/models/UserSearch.php
| @@ -65,7 +65,7 @@ | @@ -65,7 +65,7 @@ | ||
| 65 | $dataProvider = new ActiveDataProvider([ | 65 | $dataProvider = new ActiveDataProvider([ |
| 66 | 'query' => $query, | 66 | 'query' => $query, |
| 67 | 'pagination' => new Pagination([ | 67 | 'pagination' => new Pagination([ |
| 68 | - 'pageSize' => 10, | 68 | + 'pageSize' => 5, |
| 69 | ]), | 69 | ]), |
| 70 | 'sort' => new Sort([ | 70 | 'sort' => new Sort([ |
| 71 | 'defaultOrder' => [ | 71 | 'defaultOrder' => [ |
common/modules/comment/rbac/ArtboxCommentUpdateOwnRule.php
console/migrations/m160411_143038_create_portfolio_gallery.php
0 → 100644
| 1 | +<?php | ||
| 2 | + | ||
| 3 | + use yii\db\Migration; | ||
| 4 | + | ||
| 5 | + /** | ||
| 6 | + * Handles the creation for table `portfolio_gallery`. | ||
| 7 | + */ | ||
| 8 | + class m160411_143038_create_portfolio_gallery extends Migration | ||
| 9 | + { | ||
| 10 | + | ||
| 11 | + /** | ||
| 12 | + * @inheritdoc | ||
| 13 | + */ | ||
| 14 | + public function up() | ||
| 15 | + { | ||
| 16 | + $this->createTable('portfolio_gallery', [ | ||
| 17 | + 'portfolio_gallery_id' => $this->primaryKey(), | ||
| 18 | + 'gallery_id' => $this->integer() | ||
| 19 | + ->notNull(), | ||
| 20 | + 'portfolio_id' => $this->integer() | ||
| 21 | + ->notNull(), | ||
| 22 | + 'user_id' => $this->integer() | ||
| 23 | + ->notNull(), | ||
| 24 | + 'caption' => $this->string(), | ||
| 25 | + 'visible' => $this->smallInteger() | ||
| 26 | + ->defaultValue(1), | ||
| 27 | + ]); | ||
| 28 | + $this->addForeignKey('portfolio_gallery_gallery', '{{%portfolio_gallery}}', 'gallery_id', '{{%gallery}}', 'gallery_id', 'CASCADE', 'CASCADE'); | ||
| 29 | + $this->addForeignKey('portfolio_gallery_portfolio', '{{%portfolio_gallery}}', 'portfolio_id', '{{%portfolio}}', 'portfolio_id', 'CASCADE', 'CASCADE'); | ||
| 30 | + $this->addForeignKey('portfolio_gallery_user', '{{%portfolio_gallery}}', 'user_id', '{{%user}}', 'id', 'CASCADE', 'CASCADE'); | ||
| 31 | + } | ||
| 32 | + | ||
| 33 | + /** | ||
| 34 | + * @inheritdoc | ||
| 35 | + */ | ||
| 36 | + public function down() | ||
| 37 | + { | ||
| 38 | + $this->dropForeignKey('portfolio_gallery_user', '{{%portfolio_gallery}}'); | ||
| 39 | + $this->dropForeignKey('portfolio_gallery_gallery', '{{%portfolio_gallery}}'); | ||
| 40 | + $this->dropForeignKey('portfolio_gallery_portfolio', '{{%portfolio_gallery}}'); | ||
| 41 | + $this->dropTable('portfolio_gallery'); | ||
| 42 | + } | ||
| 43 | + } |
frontend/controllers/AccountsController.php
| @@ -19,6 +19,7 @@ | @@ -19,6 +19,7 @@ | ||
| 19 | use common\models\PortfolioSearch; | 19 | use common\models\PortfolioSearch; |
| 20 | use common\models\PortfolioSpecialization; | 20 | use common\models\PortfolioSpecialization; |
| 21 | use common\models\PortfolioUser; | 21 | use common\models\PortfolioUser; |
| 22 | + use common\models\PortfolioUserSearch; | ||
| 22 | use common\models\Project; | 23 | use common\models\Project; |
| 23 | use common\models\ProjectSearch; | 24 | use common\models\ProjectSearch; |
| 24 | use common\models\Specialization; | 25 | use common\models\Specialization; |
| @@ -33,6 +34,7 @@ | @@ -33,6 +34,7 @@ | ||
| 33 | use common\models\UserInfo; | 34 | use common\models\UserInfo; |
| 34 | 35 | ||
| 35 | use yii\base\ErrorException; | 36 | use yii\base\ErrorException; |
| 37 | + use yii\data\Sort; | ||
| 36 | use yii\db\ActiveRecord; | 38 | use yii\db\ActiveRecord; |
| 37 | use yii\filters\AccessControl; | 39 | use yii\filters\AccessControl; |
| 38 | use yii\filters\VerbFilter; | 40 | use yii\filters\VerbFilter; |
| @@ -77,6 +79,18 @@ | @@ -77,6 +79,18 @@ | ||
| 77 | ]; | 79 | ]; |
| 78 | } | 80 | } |
| 79 | 81 | ||
| 82 | + public function beforeAction($action) | ||
| 83 | + { | ||
| 84 | + $portfolio_user_count = PortfolioUser::find() | ||
| 85 | + ->where([ | ||
| 86 | + 'user_id' => \Yii::$app->user->id, | ||
| 87 | + 'status' => 2, | ||
| 88 | + ]) | ||
| 89 | + ->count(); | ||
| 90 | + $this->view->params[ 'portfolio_user_count' ] = $portfolio_user_count; | ||
| 91 | + return parent::beforeAction($action); // TODO: Change the autogenerated stub | ||
| 92 | + } | ||
| 93 | + | ||
| 80 | /** | 94 | /** |
| 81 | * Page of additional skills, consist: | 95 | * Page of additional skills, consist: |
| 82 | * * working with programs; | 96 | * * working with programs; |
| @@ -456,6 +470,107 @@ | @@ -456,6 +470,107 @@ | ||
| 456 | return $this->renderAjax('_job_form', [ 'index' => $lastindex + 1 ]); | 470 | return $this->renderAjax('_job_form', [ 'index' => $lastindex + 1 ]); |
| 457 | } | 471 | } |
| 458 | 472 | ||
| 473 | + public function actionParticipant() | ||
| 474 | + { | ||
| 475 | + $searchModel = new PortfolioUserSearch(); | ||
| 476 | + $dataProvider = $searchModel->search(Yii::$app->request->queryParams); | ||
| 477 | + $dataProvider->query->joinWith('portfolio'); | ||
| 478 | + $dataProvider->sort = new Sort([ | ||
| 479 | + 'defaultOrder' => [ | ||
| 480 | + 'portfolio_user_id' => SORT_ASC, | ||
| 481 | + ], | ||
| 482 | + 'attributes' => [ | ||
| 483 | + 'project' => [ | ||
| 484 | + 'asc' => [ | ||
| 485 | + 'portfolio.name' => SORT_ASC, | ||
| 486 | + ], | ||
| 487 | + 'desc' => [ | ||
| 488 | + 'portfolio.name' => SORT_DESC, | ||
| 489 | + ], | ||
| 490 | + ], | ||
| 491 | + 'portfolio_user_id', | ||
| 492 | + 'position', | ||
| 493 | + 'time', | ||
| 494 | + 'status', | ||
| 495 | + ], | ||
| 496 | + ]); | ||
| 497 | + $dataProvider->pagination->pageSize = 5; | ||
| 498 | + return $this->render('participant', [ | ||
| 499 | + 'searchModel' => $searchModel, | ||
| 500 | + 'dataProvider' => $dataProvider, | ||
| 501 | + ]); | ||
| 502 | + } | ||
| 503 | + | ||
| 504 | + public function actionParticipantConfirm($id) | ||
| 505 | + { | ||
| 506 | + $portfolioUser = PortfolioUser::find() | ||
| 507 | + ->where([ | ||
| 508 | + 'portfolio_user_id' => $id, | ||
| 509 | + 'user_id' => \Yii::$app->user->id, | ||
| 510 | + 'status' => 2, | ||
| 511 | + ]) | ||
| 512 | + ->one(); | ||
| 513 | + if(empty( $portfolioUser )) { | ||
| 514 | + throw new NotFoundHttpException('Приглашение не найдено'); | ||
| 515 | + } | ||
| 516 | + $portfolioUser->status = 1; | ||
| 517 | + if($portfolioUser->save(false)) { | ||
| 518 | + return $this->redirect([ 'accounts/participant' ]); | ||
| 519 | + } else { | ||
| 520 | + throw new \Exception('Неизвестная ошибка'); | ||
| 521 | + } | ||
| 522 | + } | ||
| 523 | + | ||
| 524 | + public function actionParticipantDelete($id) | ||
| 525 | + { | ||
| 526 | + $portfolioUser = PortfolioUser::find() | ||
| 527 | + ->where([ | ||
| 528 | + 'portfolio_user_id' => $id, | ||
| 529 | + 'user_id' => \Yii::$app->user->id, | ||
| 530 | + ]) | ||
| 531 | + ->one(); | ||
| 532 | + if(empty( $portfolioUser )) { | ||
| 533 | + throw new NotFoundHttpException('Приглашение не найдено'); | ||
| 534 | + } | ||
| 535 | + if($portfolioUser->delete()) { | ||
| 536 | + return $this->redirect([ 'accounts/participant' ]); | ||
| 537 | + } else { | ||
| 538 | + throw new \Exception('Неизвестная ошибка'); | ||
| 539 | + } | ||
| 540 | + } | ||
| 541 | + | ||
| 542 | + public function actionParticipantEdit($id) | ||
| 543 | + { | ||
| 544 | + $portfolioUser = PortfolioUser::find() | ||
| 545 | + ->where([ | ||
| 546 | + 'portfolio_user_id' => $id, | ||
| 547 | + 'user_id' => \Yii::$app->user->id, | ||
| 548 | + ]) | ||
| 549 | + ->with('gallery') | ||
| 550 | + ->one(); | ||
| 551 | + if(empty( $portfolioUser )) { | ||
| 552 | + throw new NotFoundHttpException('Приглашение не найдено'); | ||
| 553 | + } | ||
| 554 | + $post = \Yii::$app->request->post(); | ||
| 555 | + if(!empty( $post )) { | ||
| 556 | + if($portfolioUser->load($post)) { | ||
| 557 | + $portfolioUser->status = 1; | ||
| 558 | + if($portfolioUser->save()) { | ||
| 559 | + if(!empty($portfolioUser->gallery)) { | ||
| 560 | + $portfolioUser->gallery->load($post); | ||
| 561 | + $portfolioUser->portfolioGallery->load($post); | ||
| 562 | + if($portfolioUser->gallery->save() && $portfolioUser->portfolioGallery->save()) { | ||
| 563 | + return $this->redirect(['accounts/participant']); | ||
| 564 | + } | ||
| 565 | + } else { | ||
| 566 | + return $this->redirect(['accounts/participant-edit', 'id' => $portfolioUser->portfolio_user_id]); | ||
| 567 | + } | ||
| 568 | + } | ||
| 569 | + } | ||
| 570 | + } | ||
| 571 | + return $this->render('participant-edit', [ 'model' => $portfolioUser ]); | ||
| 572 | + } | ||
| 573 | + | ||
| 459 | /** | 574 | /** |
| 460 | * Page of User's portfolio | 575 | * Page of User's portfolio |
| 461 | * @return string | 576 | * @return string |
| @@ -510,7 +625,7 @@ | @@ -510,7 +625,7 @@ | ||
| 510 | foreach($post[ 'PortfolioUser' ] as $index => $item) { | 625 | foreach($post[ 'PortfolioUser' ] as $index => $item) { |
| 511 | $portfolioUsers[ $index ] = new PortfolioUser([ 'portfolio_id' => $portfolio->portfolio_id ]); | 626 | $portfolioUsers[ $index ] = new PortfolioUser([ 'portfolio_id' => $portfolio->portfolio_id ]); |
| 512 | } | 627 | } |
| 513 | - $success = (PortfolioUser::loadMultiple($portfolioUsers, $post) && PortfolioUser::validateMultiple($portfolioUsers)); | 628 | + $success = ( PortfolioUser::loadMultiple($portfolioUsers, $post) && PortfolioUser::validateMultiple($portfolioUsers) ); |
| 514 | if($success) { | 629 | if($success) { |
| 515 | foreach($portfolioUsers as $index => $portfolioUser) { | 630 | foreach($portfolioUsers as $index => $portfolioUser) { |
| 516 | $portfolioUser->save(false); | 631 | $portfolioUser->save(false); |
| @@ -562,7 +677,13 @@ | @@ -562,7 +677,13 @@ | ||
| 562 | ->all(); | 677 | ->all(); |
| 563 | 678 | ||
| 564 | $post = \Yii::$app->request->post(); | 679 | $post = \Yii::$app->request->post(); |
| 565 | - $portfolioUsers = $portfolio->portfolioUsers; | 680 | + $portfolioUsers = $portfolio->getPortfolioUsers() |
| 681 | + ->where([ 'status' => 2 ]) | ||
| 682 | + ->all(); | ||
| 683 | + $portfolioUsersConfirmed = $portfolio->getPortfolioUsers() | ||
| 684 | + ->where([ 'status' => 1 ]) | ||
| 685 | + ->indexBy('user_id') | ||
| 686 | + ->all(); | ||
| 566 | 687 | ||
| 567 | if(!empty( $post )) { | 688 | if(!empty( $post )) { |
| 568 | $portfolio->load($post); | 689 | $portfolio->load($post); |
| @@ -573,18 +694,33 @@ | @@ -573,18 +694,33 @@ | ||
| 573 | foreach($portfolio->specializationInput as $one_specialization) { | 694 | foreach($portfolio->specializationInput as $one_specialization) { |
| 574 | $portfolio->link('specializations', Specialization::findOne($one_specialization)); | 695 | $portfolio->link('specializations', Specialization::findOne($one_specialization)); |
| 575 | } | 696 | } |
| 576 | - $portfolio->unlinkAll('portfolioUsers', true); | 697 | + PortfolioUser::deleteAll([ |
| 698 | + 'portfolio_id' => $portfolio->portfolio_id, | ||
| 699 | + 'status' => 2, | ||
| 700 | + ]); | ||
| 577 | $success = true; | 701 | $success = true; |
| 578 | if(!empty( $post[ 'PortfolioUser' ] )) { | 702 | if(!empty( $post[ 'PortfolioUser' ] )) { |
| 579 | $portfolioUsers = [ ]; | 703 | $portfolioUsers = [ ]; |
| 580 | foreach($post[ 'PortfolioUser' ] as $index => $item) { | 704 | foreach($post[ 'PortfolioUser' ] as $index => $item) { |
| 581 | $portfolioUsers[ $index ] = new PortfolioUser([ 'portfolio_id' => $portfolio->portfolio_id ]); | 705 | $portfolioUsers[ $index ] = new PortfolioUser([ 'portfolio_id' => $portfolio->portfolio_id ]); |
| 582 | } | 706 | } |
| 583 | - $success = (PortfolioUser::loadMultiple($portfolioUsers, $post) && PortfolioUser::validateMultiple($portfolioUsers)); | 707 | + $success = PortfolioUser::loadMultiple($portfolioUsers, $post); |
| 708 | + foreach($portfolioUsers as $index => $portfolioUser) { | ||
| 709 | + if($portfolioUser->status == 1) { | ||
| 710 | + $portfolioUsersConfirmed[ $portfolioUser->user_id ]->position = $portfolioUser->position; | ||
| 711 | + $portfolioUsersConfirmed[ $portfolioUser->user_id ]->time = $portfolioUser->time; | ||
| 712 | + unset( $portfolioUsers[ $index ] ); | ||
| 713 | + } | ||
| 714 | + } | ||
| 715 | + $success = ( $success && PortfolioUser::validateMultiple($portfolioUsers) && PortfolioUser::validateMultiple($portfolioUsersConfirmed) ); | ||
| 584 | if($success) { | 716 | if($success) { |
| 585 | foreach($portfolioUsers as $index => $portfolioUser) { | 717 | foreach($portfolioUsers as $index => $portfolioUser) { |
| 718 | + $portfolioUser->status = 2; | ||
| 586 | $portfolioUser->save(false); | 719 | $portfolioUser->save(false); |
| 587 | } | 720 | } |
| 721 | + foreach($portfolioUsersConfirmed as $index => $portfolioUserConfirmed) { | ||
| 722 | + $portfolioUserConfirmed->save(false); | ||
| 723 | + } | ||
| 588 | } | 724 | } |
| 589 | } | 725 | } |
| 590 | if($success) { | 726 | if($success) { |
| @@ -594,10 +730,11 @@ | @@ -594,10 +730,11 @@ | ||
| 594 | } | 730 | } |
| 595 | 731 | ||
| 596 | return $this->render('_portfolio_form', [ | 732 | return $this->render('_portfolio_form', [ |
| 597 | - 'portfolio' => $portfolio, | ||
| 598 | - 'specializations' => $specializations, | ||
| 599 | - 'galleries' => $galleries, | ||
| 600 | - 'portfolioUsers' => $portfolioUsers, | 733 | + 'portfolio' => $portfolio, |
| 734 | + 'specializations' => $specializations, | ||
| 735 | + 'galleries' => $galleries, | ||
| 736 | + 'portfolioUsers' => $portfolioUsers, | ||
| 737 | + 'portfolioUsersConfirmed' => $portfolioUsersConfirmed, | ||
| 601 | ]); | 738 | ]); |
| 602 | } | 739 | } |
| 603 | 740 |
frontend/controllers/AjaxController.php
| 1 | <?php | 1 | <?php |
| 2 | namespace frontend\controllers; | 2 | namespace frontend\controllers; |
| 3 | 3 | ||
| 4 | + use common\models\Portfolio; | ||
| 5 | + use common\models\PortfolioUser; | ||
| 4 | use common\models\User; | 6 | use common\models\User; |
| 5 | use common\models\UserSearch; | 7 | use common\models\UserSearch; |
| 6 | use yii\db\ActiveRecord; | 8 | use yii\db\ActiveRecord; |
| @@ -26,7 +28,11 @@ | @@ -26,7 +28,11 @@ | ||
| 26 | $ids = json_decode(\Yii::$app->request->get('ids')); | 28 | $ids = json_decode(\Yii::$app->request->get('ids')); |
| 27 | $model = new UserSearch(); | 29 | $model = new UserSearch(); |
| 28 | $dataProvider = $model->search(\Yii::$app->request->queryParams); | 30 | $dataProvider = $model->search(\Yii::$app->request->queryParams); |
| 29 | - $dataProvider->query->andFilterWhere(['not in', 'id', $ids]); | 31 | + $dataProvider->query->andFilterWhere([ |
| 32 | + 'not in', | ||
| 33 | + 'id', | ||
| 34 | + $ids, | ||
| 35 | + ]); | ||
| 30 | $dataProvider->query->andWhere([ | 36 | $dataProvider->query->andWhere([ |
| 31 | 'user_info.is_freelancer' => 1, | 37 | 'user_info.is_freelancer' => 1, |
| 32 | 'type' => 1, | 38 | 'type' => 1, |
| @@ -90,4 +96,53 @@ | @@ -90,4 +96,53 @@ | ||
| 90 | ]; | 96 | ]; |
| 91 | } | 97 | } |
| 92 | 98 | ||
| 99 | + public function actionPortfolioUserRemove() | ||
| 100 | + { | ||
| 101 | + $request = \Yii::$app->request; | ||
| 102 | + $response = \Yii::$app->response; | ||
| 103 | + $response->format = $response::FORMAT_JSON; | ||
| 104 | + $post = $request->post(); | ||
| 105 | + if(empty( $post[ 'user_id' ] ) || empty( $post[ 'portfolio_id' ] )) { | ||
| 106 | + return [ 'error' => 'user_id и portfolio_id должны быть заполнены.' ]; | ||
| 107 | + } | ||
| 108 | + $user_id = $post[ 'user_id' ]; | ||
| 109 | + $portfolio_id = $post[ 'portfolio_id' ]; | ||
| 110 | + $portfolio = Portfolio::find() | ||
| 111 | + ->where([ | ||
| 112 | + 'portfolio_id' => $portfolio_id, | ||
| 113 | + 'user_id' => \Yii::$app->user->id, | ||
| 114 | + ]) | ||
| 115 | + ->one(); | ||
| 116 | + if(empty( $portfolio )) { | ||
| 117 | + return [ 'error' => 'Запись не найдена' ]; | ||
| 118 | + } | ||
| 119 | + $user = User::find() | ||
| 120 | + ->where([ 'id' => $user_id ]) | ||
| 121 | + ->one(); | ||
| 122 | + if(empty( $user )) { | ||
| 123 | + return [ 'error' => 'Пользователь не найден' ]; | ||
| 124 | + } | ||
| 125 | + $portfolio_user = PortfolioUser::find() | ||
| 126 | + ->where([ | ||
| 127 | + 'portfolio_id' => $portfolio->portfolio_id, | ||
| 128 | + 'user_id' => $user->id, | ||
| 129 | + 'status' => 1, | ||
| 130 | + ]) | ||
| 131 | + ->one(); | ||
| 132 | + if(empty( $portfolio_user )) { | ||
| 133 | + return [ 'error' => 'Пользователь не относится к данной записи' ]; | ||
| 134 | + } | ||
| 135 | + if($portfolio_user->delete()) { | ||
| 136 | + return [ | ||
| 137 | + 'result' => [ | ||
| 138 | + 'message' => 'Пользователь удален', | ||
| 139 | + 'user_id' => $user->id, | ||
| 140 | + 'portfolio_id' => $portfolio->portfolio_id, | ||
| 141 | + ], | ||
| 142 | + ]; | ||
| 143 | + } else { | ||
| 144 | + return [ 'error' => 'Ошибка удаления' ]; | ||
| 145 | + } | ||
| 146 | + } | ||
| 147 | + | ||
| 93 | } | 148 | } |
frontend/controllers/SearchController.php
| @@ -63,6 +63,7 @@ use common\models\Social; | @@ -63,6 +63,7 @@ use common\models\Social; | ||
| 63 | { | 63 | { |
| 64 | $model = new TenderSearch(); | 64 | $model = new TenderSearch(); |
| 65 | $dataProvider = $model->search(Yii::$app->request->queryParams); | 65 | $dataProvider = $model->search(Yii::$app->request->queryParams); |
| 66 | + $dataProvider->query->andWhere(['hidden' => 0]); | ||
| 66 | $dataProvider->setPagination([ | 67 | $dataProvider->setPagination([ |
| 67 | 'pageSize' => 10, | 68 | 'pageSize' => 10, |
| 68 | ]); | 69 | ]); |
| 1 | +<?php | ||
| 2 | + namespace frontend\models; | ||
| 3 | + | ||
| 4 | + use yii\base\Exception; | ||
| 5 | + use yii\base\InvalidParamException; | ||
| 6 | + use yii\base\Model; | ||
| 7 | + | ||
| 8 | + class SMOClosed extends Model | ||
| 9 | + { | ||
| 10 | + | ||
| 11 | + public $n; | ||
| 12 | + | ||
| 13 | + public $N; | ||
| 14 | + | ||
| 15 | + public $p; | ||
| 16 | + | ||
| 17 | + public $K; | ||
| 18 | + | ||
| 19 | + public $r; | ||
| 20 | + | ||
| 21 | + public $mu; | ||
| 22 | + | ||
| 23 | + public $e; | ||
| 24 | + | ||
| 25 | + public $b; | ||
| 26 | + | ||
| 27 | + public $k; | ||
| 28 | + | ||
| 29 | + public $probs; | ||
| 30 | + | ||
| 31 | + public $SMO; | ||
| 32 | + | ||
| 33 | + public $C; | ||
| 34 | + | ||
| 35 | + public $L; | ||
| 36 | + | ||
| 37 | + public $R; | ||
| 38 | + | ||
| 39 | + public $M; | ||
| 40 | + | ||
| 41 | + public $La; | ||
| 42 | + | ||
| 43 | + public $T; | ||
| 44 | + | ||
| 45 | + public $Q; | ||
| 46 | + | ||
| 47 | + function __construct(array $config) | ||
| 48 | + { | ||
| 49 | + parent::__construct($config); | ||
| 50 | + if(!intval($this->n)) { | ||
| 51 | + throw new InvalidParamException('Кількість СМО має бути цілим невід\'ємним числом'); | ||
| 52 | + } else { | ||
| 53 | + $this->k[ 0 ] = 0; | ||
| 54 | + for($i = 1; $i <= $this->n; $i++) { | ||
| 55 | + for($j = 1; $j <= $this->n; $j++) { | ||
| 56 | + $this->p[ $i ][ $j ] = 0; | ||
| 57 | + $this->r[ $i ] = 1; | ||
| 58 | + $this->mu[ $i ] = 0; | ||
| 59 | + } | ||
| 60 | + } | ||
| 61 | + } | ||
| 62 | + } | ||
| 63 | + | ||
| 64 | + public function attributeLabels() | ||
| 65 | + { | ||
| 66 | + return [ | ||
| 67 | + 'n' => 'Кількість систем масового обслуговування (n)', | ||
| 68 | + 'N' => 'Кількість вимог в мережі масового обслуговування (N)', | ||
| 69 | + 'p' => 'Матриця ймовірностей (p<sub>i,j</sub>)', | ||
| 70 | + 'K' => 'Показники системи масового обслуговування (K)', | ||
| 71 | + 'r' => 'Кількість каналів обслуговування (r)', | ||
| 72 | + 'mu' => 'Інтенсивність обслуговування каналом (1/μ)', | ||
| 73 | + 'e' => 'Коефіцієнт передачі (e)', | ||
| 74 | + 'b' => 'Початкова СМО (e = 1)', | ||
| 75 | + 'k' => 'Масив вимог', | ||
| 76 | + 'probs' => 'Допоміжні функції p<sub>i</sub>(k)', | ||
| 77 | + 'SMO' => 'Ймовірність перебування j вимоги в i-тій СМО P<sub>СМО<sub>i</sub></sub>(j)', | ||
| 78 | + 'C' => 'Нормуючий множник (C(N))', | ||
| 79 | + 'L' => 'Середня кількість вимог у черзі СМО<sub>i</sub> (L<sub>i</sub>)', | ||
| 80 | + 'R' => 'Середня кількість зайнятих пристроїв у СМО<sub>i</sub> (R<sub>i</sub>)', | ||
| 81 | + 'M' => 'Середня кількість вимог у СМО<sub>i</sub> (M<sub>i</sub>)', | ||
| 82 | + 'La' => 'Інтенсивність вихідного потоку вимог у СМО<sub>i</sub> (λ<sub>i</sub>)', | ||
| 83 | + 'T' => 'Середній час перебування вимоги у СМО<sub>i</sub> (T<sub>i</sub>)', | ||
| 84 | + 'Q' => 'Середній час очікування у черзі СМО<sub>i</sub> (Q<sub>i</sub>)', | ||
| 85 | + ]; | ||
| 86 | + } | ||
| 87 | + | ||
| 88 | + public function rules() | ||
| 89 | + { | ||
| 90 | + return [ | ||
| 91 | + [ | ||
| 92 | + [ 'b' ], | ||
| 93 | + 'required', | ||
| 94 | + ], | ||
| 95 | + [ | ||
| 96 | + [ | ||
| 97 | + 'N', | ||
| 98 | + ], | ||
| 99 | + 'integer', | ||
| 100 | + 'min' => 1, | ||
| 101 | + ], | ||
| 102 | + [ | ||
| 103 | + [ 'n' ], | ||
| 104 | + 'integer', | ||
| 105 | + 'min' => 2, | ||
| 106 | + 'max' => 3, | ||
| 107 | + 'message' => 'На даний момент допустимі значення кількості СМО лише 2 або 3', | ||
| 108 | + ], | ||
| 109 | + [ | ||
| 110 | + [ | ||
| 111 | + 'p', | ||
| 112 | + 'mu', | ||
| 113 | + ], | ||
| 114 | + 'safe', | ||
| 115 | + ], | ||
| 116 | + [ | ||
| 117 | + [ 'r' ], | ||
| 118 | + 'each', | ||
| 119 | + 'rule' => [ | ||
| 120 | + 'integer', | ||
| 121 | + 'min' => 1, | ||
| 122 | + ], | ||
| 123 | + ], | ||
| 124 | + [ | ||
| 125 | + [ 'mu' ], | ||
| 126 | + 'each', | ||
| 127 | + 'rule' => [ | ||
| 128 | + 'number', | ||
| 129 | + 'min' => 0, | ||
| 130 | + ], | ||
| 131 | + ], | ||
| 132 | + [ | ||
| 133 | + [ 'b' ], | ||
| 134 | + 'integer', | ||
| 135 | + 'min' => 1, | ||
| 136 | + ], | ||
| 137 | + [ | ||
| 138 | + [ 'b' ], | ||
| 139 | + 'compare', | ||
| 140 | + 'compareAttribute' => 'n', | ||
| 141 | + 'operator' => '<=', | ||
| 142 | + ], | ||
| 143 | + [ | ||
| 144 | + [ 'b' ], | ||
| 145 | + 'default', | ||
| 146 | + 'value' => 1, | ||
| 147 | + ], | ||
| 148 | + ]; | ||
| 149 | + } | ||
| 150 | + | ||
| 151 | + public function buildk() | ||
| 152 | + { | ||
| 153 | + if(!empty($this->N)) { | ||
| 154 | + for($i = 1; $i <= $this->N; $i++) { | ||
| 155 | + $this->k[$i] = $i; | ||
| 156 | + } | ||
| 157 | + } | ||
| 158 | + } | ||
| 159 | + | ||
| 160 | + public function buildE($antiloop = true) | ||
| 161 | + { | ||
| 162 | + $this->e[ $this->b ] = 1; | ||
| 163 | + for($k = 1; $k <= $this->n; $k++) { | ||
| 164 | + if($k == $this->b) { | ||
| 165 | + continue; | ||
| 166 | + } else { | ||
| 167 | + $this->e[ $k ] = ''; | ||
| 168 | + } | ||
| 169 | + } | ||
| 170 | + foreach($this->p as $i => $vals) { | ||
| 171 | + foreach($vals as $j => $val) { | ||
| 172 | + if($j == $this->b) { | ||
| 173 | + continue; | ||
| 174 | + } | ||
| 175 | + if($val != 0) { | ||
| 176 | + $this->e[ $j ] .= '{' . $i . '};'; | ||
| 177 | + } | ||
| 178 | + } | ||
| 179 | + } | ||
| 180 | + do { | ||
| 181 | + $iteration = 0; | ||
| 182 | + $found = 0; | ||
| 183 | + foreach($this->e as $i => $val) { | ||
| 184 | + if(!preg_match('/\{\d\}/', $val)) { | ||
| 185 | + foreach($this->e as $j => $value) { | ||
| 186 | + if(preg_match('/\{' . $i . '\}/', $this->e[ $j ])) { | ||
| 187 | + $this->e[ $j ] = preg_replace('/\{' . $i . '\}/', ( $this->p[ $i ][ $j ] * $val ), $this->e[ $j ]); | ||
| 188 | + $found = 1; | ||
| 189 | + } | ||
| 190 | + } | ||
| 191 | + } | ||
| 192 | + } | ||
| 193 | + if($antiloop) { | ||
| 194 | + $iteration++; | ||
| 195 | + } | ||
| 196 | + } while($found && $iteration < 100); | ||
| 197 | + foreach($this->e as $i => $val) { | ||
| 198 | + if(strpos($val, ';') !== false) { | ||
| 199 | + $this->e[ $i ] = array_sum(explode(';', $val)); | ||
| 200 | + } | ||
| 201 | + } | ||
| 202 | + } | ||
| 203 | + | ||
| 204 | + public function buildProbs() | ||
| 205 | + { | ||
| 206 | + for($q = 1; $q <= $this->n; $q++) { | ||
| 207 | + foreach($this->k as $k) { | ||
| 208 | + $prob = pow($this->e[ $q ] * $this->mu[ $q ], $k); | ||
| 209 | + if($k <= $this->r[ $q ]) { | ||
| 210 | + $prob = $prob * 1 / $this->factorial($k); | ||
| 211 | + } else { | ||
| 212 | + $prob = $prob * 1 / $this->factorial($this->r[ $q ]) * pow($this->r[ $q ], ( $k - $this->r[ $q ] )); | ||
| 213 | + } | ||
| 214 | + $this->probs[ $q ][ $k ] = $prob; | ||
| 215 | + unset( $prob ); | ||
| 216 | + } | ||
| 217 | + } | ||
| 218 | + } | ||
| 219 | + | ||
| 220 | + public function factorial($x) | ||
| 221 | + { | ||
| 222 | + $x = intval($x); | ||
| 223 | + if(!is_int($x) || $x < 0) { | ||
| 224 | + throw new Exception('Factorial must be greater than 0'); | ||
| 225 | + } | ||
| 226 | + $res = 1; | ||
| 227 | + for($i = 1; $i <= $x; $i++) { | ||
| 228 | + $res *= $i; | ||
| 229 | + } | ||
| 230 | + return $res; | ||
| 231 | + } | ||
| 232 | + | ||
| 233 | + public function buildC() | ||
| 234 | + { | ||
| 235 | + $result = 0; | ||
| 236 | + if($this->n == 2) { | ||
| 237 | + for($a = 0; $a <= $this->N; $a++) { | ||
| 238 | + $result += $this->probs[1][$a] * $this->probs[2][$this->N - $a]; | ||
| 239 | + } | ||
| 240 | + } elseif($this->n == 3) { | ||
| 241 | + for($a = 0; $a <= $this->N; $a++) { | ||
| 242 | + $sum = 0; | ||
| 243 | + for($b = 0; $b <= ( $this->N - $a ); $b++) { | ||
| 244 | + $sum += $this->findSum($b, $a); | ||
| 245 | + } | ||
| 246 | + $result += $sum * $this->probs[ 1 ][ $a ]; | ||
| 247 | + unset( $sum ); | ||
| 248 | + } | ||
| 249 | + } | ||
| 250 | + $this->C = pow($result, ( -1 )); | ||
| 251 | + } | ||
| 252 | + | ||
| 253 | + public function findSum($b, $a) | ||
| 254 | + { | ||
| 255 | + return $this->probs[ 2 ][ $b ] * $this->probs[ 3 ][ $this->N - $a - $b ]; | ||
| 256 | + } | ||
| 257 | + | ||
| 258 | + public function buildSMO() | ||
| 259 | + { | ||
| 260 | + for($q = 1; $q <= $this->n; $q++) { | ||
| 261 | + foreach($this->k as $k) { | ||
| 262 | + $sum = 0; | ||
| 263 | + if($this->n == 2) { | ||
| 264 | + if($q == 1) { | ||
| 265 | + $sum += $this->probs[1][$k]*$this->probs[2][$this->N - $k]; | ||
| 266 | + } elseif($q == 2) { | ||
| 267 | + $sum += $this->probs[1][$this->N - $k]*$this->probs[2][$k]; | ||
| 268 | + } | ||
| 269 | + } elseif($this->n == 3) { | ||
| 270 | + for($a = 0; $a <= ($this->N - $k); $a++) { | ||
| 271 | + if($q == 1) { | ||
| 272 | + $sum += $this->probs[1][$k]*$this->probs[2][$a]*$this->probs[3][($this->N - $k - $a)]; | ||
| 273 | + } elseif($q == 2) { | ||
| 274 | + $sum += $this->probs[1][$a]*$this->probs[2][$k]*$this->probs[3][($this->N - $k - $a)]; | ||
| 275 | + } elseif($q ===3) { | ||
| 276 | + $sum += $this->probs[1][$a]*$this->probs[2][($this->N - $k - $a)]*$this->probs[3][$k]; | ||
| 277 | + } | ||
| 278 | + } | ||
| 279 | + } | ||
| 280 | + $this->SMO[$q][$k] = $sum*$this->C; | ||
| 281 | + unset($sum); | ||
| 282 | + } | ||
| 283 | + } | ||
| 284 | + } | ||
| 285 | + | ||
| 286 | + public function testSMO() | ||
| 287 | + { | ||
| 288 | + $message = ''; | ||
| 289 | + foreach($this->SMO as $K => $vals) { | ||
| 290 | + $message .= 'SUM of SMO'.$K.': '; | ||
| 291 | + $sum = 0; | ||
| 292 | + foreach($vals as $val) { | ||
| 293 | + $sum += $val; | ||
| 294 | + } | ||
| 295 | + $message .= $sum.'; <br>'; | ||
| 296 | + unset($sum); | ||
| 297 | + } | ||
| 298 | + return $message; | ||
| 299 | + } | ||
| 300 | + | ||
| 301 | + public function buildL() | ||
| 302 | + { | ||
| 303 | + for($i = 1; $i <= $this->n; $i++) { | ||
| 304 | + $sum = 0; | ||
| 305 | + for($j = ($this->r[$i] + 1); $j <= $this->N; $j++) { // Maybe error | ||
| 306 | + $sum += ($j - $this->r[$i]) * $this->SMO[$i][$j]; | ||
| 307 | + } | ||
| 308 | + $this->L[$i] = $sum; | ||
| 309 | + unset($sum); | ||
| 310 | + } | ||
| 311 | + } | ||
| 312 | + | ||
| 313 | + public function buildR() | ||
| 314 | + { | ||
| 315 | + for($i = 1; $i <= $this->n; $i++) { | ||
| 316 | + $sum = 0; | ||
| 317 | + for($j = 0; $j <= ($this->r[$i] - 1); $j++) { | ||
| 318 | + $sum += ($this->r[$i] - $j) * $this->SMO[$i][$j]; | ||
| 319 | + } | ||
| 320 | + $sum = $this->r[$i] - $sum; | ||
| 321 | + $this->R[$i] = $sum; | ||
| 322 | + unset($sum); | ||
| 323 | + } | ||
| 324 | + } | ||
| 325 | + | ||
| 326 | + public function buildM() | ||
| 327 | + { | ||
| 328 | + for($i = 1; $i <= $this->n; $i++) { | ||
| 329 | + $this->M[$i] = $this->L[$i] + $this->R[$i]; | ||
| 330 | + } | ||
| 331 | + } | ||
| 332 | + | ||
| 333 | + public function buildLa() | ||
| 334 | + { | ||
| 335 | + for($i = 1; $i <= $this->n; $i++) { | ||
| 336 | + $this->La[$i] = $this->R[$i] * pow($this->mu[$i], (-1)); | ||
| 337 | + } | ||
| 338 | + } | ||
| 339 | + | ||
| 340 | + public function buildT() | ||
| 341 | + { | ||
| 342 | + for($i = 1; $i <= $this->n; $i++) { | ||
| 343 | + $this->T[$i] = $this->M[$i] / $this->La[$i]; | ||
| 344 | + } | ||
| 345 | + } | ||
| 346 | + | ||
| 347 | + public function buildQ() | ||
| 348 | + { | ||
| 349 | + for($i = 1; $i <= $this->n; $i++) { | ||
| 350 | + $this->Q[$i] = $this->L[$i] / $this->La[$i]; | ||
| 351 | + } | ||
| 352 | + } | ||
| 353 | + } | ||
| 0 | \ No newline at end of file | 354 | \ No newline at end of file |
frontend/views/accounts/_portfolio_form.php
| 1 | <?php | 1 | <?php |
| 2 | /** | 2 | /** |
| 3 | - * @var View $this | ||
| 4 | - * @var Portfolio $portfolio | ||
| 5 | - * @var integer[] $specializations | ||
| 6 | - * @var string[] $galleries | 3 | + * @var View $this |
| 4 | + * @var Portfolio $portfolio | ||
| 5 | + * @var integer[] $specializations | ||
| 6 | + * @var string[] $galleries | ||
| 7 | + * @var PortfolioUser[] $portfolioUsers | ||
| 8 | + * @var PortfolioUser[] $portfolioUsersConfirmed | ||
| 7 | */ | 9 | */ |
| 8 | use common\components\Request; | 10 | use common\components\Request; |
| 9 | use common\models\Option; | 11 | use common\models\Option; |
| 10 | use common\models\Portfolio; | 12 | use common\models\Portfolio; |
| 13 | + use common\models\PortfolioUser; | ||
| 11 | use common\models\Specialization; | 14 | use common\models\Specialization; |
| 12 | use common\modules\file\widgets\ImageUploader; | 15 | use common\modules\file\widgets\ImageUploader; |
| 13 | use common\modules\file\widgets\ImageUploaderInput; | 16 | use common\modules\file\widgets\ImageUploaderInput; |
| @@ -185,21 +188,42 @@ | @@ -185,21 +188,42 @@ | ||
| 185 | <div class="clearfix"></div> | 188 | <div class="clearfix"></div> |
| 186 | 189 | ||
| 187 | <?php | 190 | <?php |
| 188 | - /* == Project add user block == */ | 191 | + /* == Project add user block == */ |
| 189 | ?> | 192 | ?> |
| 190 | <div class="add_project_user_wrapper" id="<?= $form->id ?>_project_user"> | 193 | <div class="add_project_user_wrapper" id="<?= $form->id ?>_project_user"> |
| 191 | <p>Добавить пользователя</p> | 194 | <p>Добавить пользователя</p> |
| 192 | <p><?= Html::a('Добавить', false, [ 'class' => 'add_project_user_link' ]) ?></p> | 195 | <p><?= Html::a('Добавить', false, [ 'class' => 'add_project_user_link' ]) ?></p> |
| 196 | + <p>Отправлено предложение:</p> | ||
| 193 | <div class="add_project_user_list"> | 197 | <div class="add_project_user_list"> |
| 194 | <?php | 198 | <?php |
| 195 | foreach($portfolioUsers as $portfolioUser) { | 199 | foreach($portfolioUsers as $portfolioUser) { |
| 196 | - echo $this->render('@frontend/views/ajax/project_user', ['model' => $portfolioUser, 'user' => $portfolioUser->user]); | ||
| 197 | - } | 200 | + echo $this->render('@frontend/views/ajax/project_user', [ |
| 201 | + 'model' => $portfolioUser, | ||
| 202 | + 'user' => $portfolioUser->user, | ||
| 203 | + ]); | ||
| 204 | + } | ||
| 198 | ?> | 205 | ?> |
| 199 | </div> | 206 | </div> |
| 207 | + <?php | ||
| 208 | + if(!empty( $portfolioUsersConfirmed )) { | ||
| 209 | + ?> | ||
| 210 | + <p class="added_project_user_header">Подтвержденные:</p> | ||
| 211 | + <div class="added_project_user_list"> | ||
| 212 | + <?php | ||
| 213 | + foreach($portfolioUsersConfirmed as $portfolioUserConfirmed) { | ||
| 214 | + echo $this->render('@frontend/views/ajax/project_user', [ | ||
| 215 | + 'model' => $portfolioUserConfirmed, | ||
| 216 | + 'user' => $portfolioUserConfirmed->user, | ||
| 217 | + ]); | ||
| 218 | + } | ||
| 219 | + ?> | ||
| 220 | + </div> | ||
| 221 | + <?php | ||
| 222 | + } | ||
| 223 | + ?> | ||
| 200 | </div> | 224 | </div> |
| 201 | <?php | 225 | <?php |
| 202 | - /* == End of project add user block == */ | 226 | + /* == End of project add user block == */ |
| 203 | ?> | 227 | ?> |
| 204 | 228 | ||
| 205 | </div> | 229 | </div> |
| 1 | +<?php | ||
| 2 | + use common\models\PortfolioUser; | ||
| 3 | + use common\modules\file\widgets\ImageUploader; | ||
| 4 | + use yii\helpers\Html; | ||
| 5 | + use yii\web\View; | ||
| 6 | + use yii\widgets\ActiveForm; | ||
| 7 | + | ||
| 8 | + /** | ||
| 9 | + * @var View $this | ||
| 10 | + * @var PortfolioUser $model | ||
| 11 | + */ | ||
| 12 | + $this->title = 'Редактирование участия в проекте'; | ||
| 13 | + $this->params[ 'breadcrumbs' ][] = $this->title; | ||
| 14 | +?> | ||
| 15 | +<div class="login-left-column-title"><?= $this->title ?></div> | ||
| 16 | +<div> | ||
| 17 | + <p>Редактировать информацию о себе:</p> | ||
| 18 | + <?php | ||
| 19 | + if($model->status != 1) { | ||
| 20 | + ?> | ||
| 21 | + <div class="alert alert-info" role="alert"> | ||
| 22 | + <strong>Внимание:</strong> данным действием Вы подтверждаете свое участие в проекте. | ||
| 23 | + </div> | ||
| 24 | + <?php | ||
| 25 | + } | ||
| 26 | + ?> | ||
| 27 | + <div> | ||
| 28 | + <?php | ||
| 29 | + $form = ActiveForm::begin(); | ||
| 30 | + echo $form->field($model, 'position') | ||
| 31 | + ->textInput(); | ||
| 32 | + echo $form->field($model, 'time') | ||
| 33 | + ->input('number'); | ||
| 34 | + ?> | ||
| 35 | + </div> | ||
| 36 | + <p>Добавить фотографию в личный альбом данного проекта:</p> | ||
| 37 | + <?php | ||
| 38 | + if($model->status == 1 && !empty($model->gallery)) { | ||
| 39 | + echo $form->field($model->portfolioGallery, 'caption')->textInput(); | ||
| 40 | + echo Html::tag('div', ImageUploader::widget([ | ||
| 41 | + 'model' => $model->gallery, | ||
| 42 | + 'field' => 'photo', | ||
| 43 | + 'size' => [ | ||
| 44 | + [ | ||
| 45 | + 'width' => 152, | ||
| 46 | + 'height' => 108, | ||
| 47 | + ], | ||
| 48 | + ], | ||
| 49 | + 'multi' => true, | ||
| 50 | + 'gallery' => $model->gallery->photo, | ||
| 51 | + 'name' => 'Загрузить фото галереи', | ||
| 52 | + ]), [ 'class' => 'admin-gallery-photos-load-wr style' ]); | ||
| 53 | + } else { | ||
| 54 | + echo Html::tag('p', 'Для добавления фотографий Вы должны подтвердить свое участие'); | ||
| 55 | + } | ||
| 56 | + ?> | ||
| 57 | + <p class="text-right"> | ||
| 58 | + <?php | ||
| 59 | + echo Html::a('Вернуться', [ 'accounts/participant' ]); | ||
| 60 | + echo Html::submitButton('Обновить'); | ||
| 61 | + $form->end(); | ||
| 62 | + ?> | ||
| 63 | + </p> | ||
| 64 | +</div> | ||
| 0 | \ No newline at end of file | 65 | \ No newline at end of file |
| 1 | +<?php | ||
| 2 | + /** | ||
| 3 | + * @var View $this | ||
| 4 | + * @var PortfolioUserSearch $searchModel | ||
| 5 | + * @var ActiveDataProvider $dataProvider | ||
| 6 | + */ | ||
| 7 | + use common\models\PortfolioUser; | ||
| 8 | + use common\models\PortfolioUserSearch; | ||
| 9 | + use yii\data\ActiveDataProvider; | ||
| 10 | + use yii\grid\ActionColumn; | ||
| 11 | + use yii\grid\DataColumn; | ||
| 12 | + use yii\grid\GridView; | ||
| 13 | + use yii\helpers\Html; | ||
| 14 | + use yii\web\View; | ||
| 15 | + | ||
| 16 | + $this->title = 'Портфолио участник'; | ||
| 17 | + $this->params[ 'breadcrumbs' ][] = $this->title; | ||
| 18 | +?> | ||
| 19 | +<div class="login-left-column-title"><?= $this->title ?></div> | ||
| 20 | +<div class="admin-table-portfolio"> | ||
| 21 | + <?= GridView::widget([ | ||
| 22 | + 'options' => [ 'class' => 'style admin-all-pages-wr' ], | ||
| 23 | + 'dataProvider' => $dataProvider, | ||
| 24 | + 'filterModel' => $searchModel, | ||
| 25 | + 'columns' => [ | ||
| 26 | + [ | ||
| 27 | + 'attribute' => 'project', | ||
| 28 | + 'content' => function($model, $key, $index, $column) { | ||
| 29 | + /** | ||
| 30 | + * @var PortfolioUser $model | ||
| 31 | + */ | ||
| 32 | + $type = $model->portfolio->user->type; | ||
| 33 | + $type_string = ( $type == 2 ) ? 'company' : 'performer'; | ||
| 34 | + return Html::a($model->portfolio->name, [ | ||
| 35 | + $type_string . '/portfolio-view', | ||
| 36 | + $type_string . '_id' => $model->portfolio->user_id, | ||
| 37 | + 'portfolio_id' => $model->portfolio->portfolio_id, | ||
| 38 | + ], [ | ||
| 39 | + 'target' => '_blank', | ||
| 40 | + ]); | ||
| 41 | + }, | ||
| 42 | + ], | ||
| 43 | + [ | ||
| 44 | + 'attribute' => 'position', | ||
| 45 | + 'value' => function($model, $key, $index, $column) { | ||
| 46 | + /** | ||
| 47 | + * @var PortfolioUser $model | ||
| 48 | + * @var DataColumn $column | ||
| 49 | + * @var int $key | ||
| 50 | + * @var int $index | ||
| 51 | + */ | ||
| 52 | + if(empty( $model[ $column->attribute ] )) { | ||
| 53 | + return NULL; | ||
| 54 | + } else { | ||
| 55 | + return $model[ $column->attribute ]; | ||
| 56 | + } | ||
| 57 | + }, | ||
| 58 | + ], | ||
| 59 | + [ | ||
| 60 | + 'attribute' => 'time', | ||
| 61 | + 'filter' => Html::tag('div', Html::activeInput('text', $searchModel, 'time_from', [ 'class' => 'form-control' ]), [ 'style' => 'width:70px;display:inline-block' ]) . Html::tag('div', Html::tag('i', '', [ | ||
| 62 | + 'class' => 'glyphicon glyphicon-resize-horizontal', | ||
| 63 | + 'style' => 'left:3px', | ||
| 64 | + ]), [ 'style' => 'width:20px;display:inline-block;' ]) . Html::tag('div', Html::activeInput('text', $searchModel, 'time_to', [ 'class' => 'form-control' ]), [ 'style' => 'width:70px;display:inline-block' ]) . ( ( $searchModel->hasErrors('time_from') ) ? Html::error($searchModel, 'time_from', [ 'class' => 'help-block' ]) : '' ) . ( ( $searchModel->hasErrors('time_to') ) ? Html::error($searchModel, 'time_to', [ 'class' => 'help-block' ]) : '' ), | ||
| 65 | + 'filterOptions' => [ | ||
| 66 | + 'class' => ( $searchModel->hasErrors('time_from') || $searchModel->hasErrors('time_to') ) ? 'has-error' : '', | ||
| 67 | + 'style' => 'width: 200px', | ||
| 68 | + ], | ||
| 69 | + ], | ||
| 70 | + [ | ||
| 71 | + 'attribute' => 'status', | ||
| 72 | + 'filter' => [ | ||
| 73 | + 1 => 'Подтверждено', | ||
| 74 | + 2 => 'Ожидание', | ||
| 75 | + ], | ||
| 76 | + 'value' => function($model) { | ||
| 77 | + if($model->status == 1) { | ||
| 78 | + return 'Подтвержден'; | ||
| 79 | + } elseif($model->status == 2) { | ||
| 80 | + return 'В ожидании'; | ||
| 81 | + } else { | ||
| 82 | + return 'Неизвестный'; | ||
| 83 | + } | ||
| 84 | + }, | ||
| 85 | + ], | ||
| 86 | + [ | ||
| 87 | + 'class' => ActionColumn::className(), | ||
| 88 | + 'buttons' => [ | ||
| 89 | + 'confirm' => function($url, $model, $key) { | ||
| 90 | + return ( $model->status == 2 ) ? Html::a(Html::img('/images/tick.png', [ | ||
| 91 | + 'width' => '15px', | ||
| 92 | + 'height' => '15px', | ||
| 93 | + ]), [ | ||
| 94 | + 'accounts/participant-confirm', | ||
| 95 | + 'id' => $model->portfolio_user_id, | ||
| 96 | + ], [ | ||
| 97 | + 'title' => 'Подтвердить', | ||
| 98 | + 'aria-label' => 'Подтвердить', | ||
| 99 | + 'data-confirm' => 'Вы уверены, что хотите подтвердить участие в данном проекте?', | ||
| 100 | + 'data-method' => 'post', | ||
| 101 | + 'data-pjax' => 0, | ||
| 102 | + ]) : ''; | ||
| 103 | + }, | ||
| 104 | + 'edit' => function($url, $model, $key) { | ||
| 105 | + return Html::a(Html::img('/images/ico_pencil.png'), [ | ||
| 106 | + 'accounts/participant-edit', | ||
| 107 | + 'id' => $model->portfolio_user_id, | ||
| 108 | + ], [ | ||
| 109 | + 'title' => 'Редактировать', | ||
| 110 | + 'aria-label' => 'Редактировать', | ||
| 111 | + 'data-pjax' => 0, | ||
| 112 | + ]); | ||
| 113 | + }, | ||
| 114 | + 'deny' => function($url, $model, $key) { | ||
| 115 | + return Html::a(Html::img('/images/delete-ico.png'), [ | ||
| 116 | + 'accounts/participant-delete', | ||
| 117 | + 'id' => $model->portfolio_user_id, | ||
| 118 | + ], [ | ||
| 119 | + 'title' => 'Удалить', | ||
| 120 | + 'aria-label' => 'Удалить', | ||
| 121 | + 'data-confirm' => 'Вы уверены, что хотите отказаться от участия в данном проекте?', | ||
| 122 | + 'data-method' => 'post', | ||
| 123 | + 'data-pjax' => 0, | ||
| 124 | + ]); | ||
| 125 | + }, | ||
| 126 | + ], | ||
| 127 | + 'template' => '{confirm}{edit}{deny}', | ||
| 128 | + ], | ||
| 129 | + ], | ||
| 130 | + ]); ?> | ||
| 131 | +</div> |
frontend/views/ajax/project_user.php
| @@ -10,7 +10,7 @@ | @@ -10,7 +10,7 @@ | ||
| 10 | use yii\web\View; | 10 | use yii\web\View; |
| 11 | 11 | ||
| 12 | ?> | 12 | ?> |
| 13 | -<div class="form-inline project_user_wrapper" data-id="<?=$user->id?>"> | 13 | +<div class="form-inline project_user_wrapper" data-id="<?=$user->id?>" <?php if($model->status == 1) { echo 'data-portfolio="'.$model->portfolio_id.'"'; } ?>> |
| 14 | <div class="error-summary"> | 14 | <div class="error-summary"> |
| 15 | <?=Html::errorSummary($model)?> | 15 | <?=Html::errorSummary($model)?> |
| 16 | </div> | 16 | </div> |
| @@ -18,6 +18,12 @@ | @@ -18,6 +18,12 @@ | ||
| 18 | <label class="sr-only">User name</label> | 18 | <label class="sr-only">User name</label> |
| 19 | <p class="form-control-static"><?=Html::a($user->name, ['performer/common', 'performer_id' => $user->id], ['target' => '_blank'])?></p> | 19 | <p class="form-control-static"><?=Html::a($user->name, ['performer/common', 'performer_id' => $user->id], ['target' => '_blank'])?></p> |
| 20 | <?=Html::activeHiddenInput($model, "[{$user->id}]user_id", ['value' => $user->id])?> | 20 | <?=Html::activeHiddenInput($model, "[{$user->id}]user_id", ['value' => $user->id])?> |
| 21 | + <?php | ||
| 22 | + if($model->status == 1) { | ||
| 23 | + echo Html::activeHiddenInput($model, "[{$user->id}]status", ['value' => $model->status]); | ||
| 24 | + } | ||
| 25 | + ?> | ||
| 26 | + <?=Html::activeHiddenInput($model, "[{$user->id}]user_id", ['value' => $user->id])?> | ||
| 21 | </div> | 27 | </div> |
| 22 | <div class="form-group" style="display: inline-block"> | 28 | <div class="form-group" style="display: inline-block"> |
| 23 | <?=Html::activeLabel($model, 'position', ['label' => Yii::t('app', 'Должность: ')])?> | 29 | <?=Html::activeLabel($model, 'position', ['label' => Yii::t('app', 'Должность: ')])?> |
frontend/views/layouts/admin.php
| @@ -17,7 +17,6 @@ $this->beginContent('@app/views/layouts/main.php'); | @@ -17,7 +17,6 @@ $this->beginContent('@app/views/layouts/main.php'); | ||
| 17 | <div class="login-right-column"> | 17 | <div class="login-right-column"> |
| 18 | <div class="admin-my-page">Моя страница</div> | 18 | <div class="admin-my-page">Моя страница</div> |
| 19 | <?php | 19 | <?php |
| 20 | - | ||
| 21 | $item = [ | 20 | $item = [ |
| 22 | [ | 21 | [ |
| 23 | 'label' => 'Учетные данные', | 22 | 'label' => 'Учетные данные', |
| @@ -55,7 +54,12 @@ $this->beginContent('@app/views/layouts/main.php'); | @@ -55,7 +54,12 @@ $this->beginContent('@app/views/layouts/main.php'); | ||
| 55 | 'url' => ['accounts/portfolio'], | 54 | 'url' => ['accounts/portfolio'], |
| 56 | 'active' => preg_match('/^portfolio.*$/', $this->context->action->id)?true:false, | 55 | 'active' => preg_match('/^portfolio.*$/', $this->context->action->id)?true:false, |
| 57 | ], | 56 | ], |
| 58 | - | 57 | + [ |
| 58 | + 'label' => "Портфолио участник <span class='badge'>{$this->params['portfolio_user_count']}</span>", | ||
| 59 | + 'encode' => false, | ||
| 60 | + 'url' => ['accounts/participant'], | ||
| 61 | + 'active' => preg_match('/^participant.*$/', $this->context->action->id)?true:false, | ||
| 62 | + ], | ||
| 59 | [ | 63 | [ |
| 60 | 'label' => 'Блог', | 64 | 'label' => 'Блог', |
| 61 | 'url' => ['accounts/blog'], | 65 | 'url' => ['accounts/blog'], |
frontend/web/js/script.js
| @@ -1159,10 +1159,7 @@ $(document).ready( | @@ -1159,10 +1159,7 @@ $(document).ready( | ||
| 1159 | ); | 1159 | ); |
| 1160 | $.fancybox.open( | 1160 | $.fancybox.open( |
| 1161 | {href : '/ajax/project-user'}, { | 1161 | {href : '/ajax/project-user'}, { |
| 1162 | - type : 'ajax', | ||
| 1163 | - margin: [70, 20, 30, 20], | ||
| 1164 | - maxWidth : 800, | ||
| 1165 | - ajax : {dataType : 'html', data : {ids : JSON.stringify(ids)}}, | 1162 | + type : 'ajax', margin : [70, 20, 30, 20], maxWidth : 800, ajax : {dataType : 'html', data : {ids : JSON.stringify(ids)}}, |
| 1166 | tpl : {wrap : '<div class="fancybox-wrap" tabIndex="-1" data-model="common\\models\\PortfolioUser" data-component="' + component + '"><div class="fancybox-skin"><div class="fancybox-outer"><div class="fancybox-inner"></div></div></div></div>'} | 1163 | tpl : {wrap : '<div class="fancybox-wrap" tabIndex="-1" data-model="common\\models\\PortfolioUser" data-component="' + component + '"><div class="fancybox-skin"><div class="fancybox-outer"><div class="fancybox-inner"></div></div></div></div>'} |
| 1167 | } | 1164 | } |
| 1168 | ); | 1165 | ); |
| @@ -1197,11 +1194,41 @@ $(document).ready( | @@ -1197,11 +1194,41 @@ $(document).ready( | ||
| 1197 | } | 1194 | } |
| 1198 | ); | 1195 | ); |
| 1199 | $(document).on( | 1196 | $(document).on( |
| 1200 | - 'click', '.project_user_remove', function() | 1197 | + 'click', '.add_project_user_list .project_user_remove', function() |
| 1201 | { | 1198 | { |
| 1202 | $(this).parents('.project_user_wrapper').remove(); | 1199 | $(this).parents('.project_user_wrapper').remove(); |
| 1203 | } | 1200 | } |
| 1204 | ); | 1201 | ); |
| 1202 | + $(document).on( | ||
| 1203 | + 'click', '.added_project_user_list .project_user_remove', function() | ||
| 1204 | + { | ||
| 1205 | + var wrapper = $(this).parents('.project_user_wrapper'); | ||
| 1206 | + var user_id = $(wrapper).data('id'); | ||
| 1207 | + var portfolio_id = $(wrapper).data('portfolio'); | ||
| 1208 | + $.post( | ||
| 1209 | + '/ajax/portfolio-user-remove', {user_id : user_id, portfolio_id : portfolio_id}, function(data) | ||
| 1210 | + { | ||
| 1211 | + if(data.error) { | ||
| 1212 | + alert(data.error); | ||
| 1213 | + } else { | ||
| 1214 | + var element = $('.added_project_user_list .project_user_wrapper[data-id='+data.result.user_id+'][data-portfolio='+data.result.portfolio_id+']'); | ||
| 1215 | + var widget_wrapper = $(element).parents('.add_project_user_wrapper'); | ||
| 1216 | + $(element).remove(); | ||
| 1217 | + var widget_id = $(widget_wrapper).attr('id'); | ||
| 1218 | + checkAddedHeader(widget_id); | ||
| 1219 | + } | ||
| 1220 | + } | ||
| 1221 | + ); | ||
| 1222 | + } | ||
| 1223 | + ); | ||
| 1205 | 1224 | ||
| 1225 | + function checkAddedHeader(id) { | ||
| 1226 | + var count = $('#'+id).find('.added_project_user_list').find('.project_user_wrapper').length; | ||
| 1227 | + if(count <= 0) { | ||
| 1228 | + $('#'+id).find('.added_project_user_header').hide(); | ||
| 1229 | + } else { | ||
| 1230 | + $('#'+id).find('.added_project_user_header').show(); | ||
| 1231 | + } | ||
| 1232 | + } | ||
| 1206 | } | 1233 | } |
| 1207 | ); | 1234 | ); |
| 1208 | \ No newline at end of file | 1235 | \ No newline at end of file |
tests/acceptance/FirstTestCept.php
| @@ -18,5 +18,5 @@ $I->click('Добавить'); | @@ -18,5 +18,5 @@ $I->click('Добавить'); | ||
| 18 | $I->wait(1); | 18 | $I->wait(1); |
| 19 | $I->attachFile('input[type="file"]', 'ViewIllustrator_2001.jpg'); | 19 | $I->attachFile('input[type="file"]', 'ViewIllustrator_2001.jpg'); |
| 20 | $I->fillField('#portfolio-name',''); | 20 | $I->fillField('#portfolio-name',''); |
| 21 | -$I->click('Добавить'); | ||
| 22 | -$I->see('Необходимо заполнить «Название».','div'); | 21 | +$I->click('Добавить', '.input-blocks-wrapper'); |
| 22 | +$I->see('Необходимо заполнить «name».','div'); |