task users, set priority at column and task, timer entity
This commit is contained in:
parent
c50dc189a7
commit
5da6746cc4
@ -106,7 +106,9 @@ class Project extends \yii\db\ActiveRecord
|
|||||||
*/
|
*/
|
||||||
public function getColumns()
|
public function getColumns()
|
||||||
{
|
{
|
||||||
return $this->hasMany(ProjectColumn::class, ['project_id' => 'id'])->with('tasks')->where(['status' => ProjectColumn::STATUS_ACTIVE]);
|
return $this->hasMany(ProjectColumn::class, ['project_id' => 'id'])
|
||||||
|
->with('tasks')
|
||||||
|
->where(['status' => ProjectColumn::STATUS_ACTIVE])->orderBy('priority');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -126,6 +126,9 @@ class ProjectColumn extends \yii\db\ActiveRecord
|
|||||||
*/
|
*/
|
||||||
public function getTasks()
|
public function getTasks()
|
||||||
{
|
{
|
||||||
return $this->hasMany(ProjectTask::class, ['column_id' => 'id'])->with('taskUsers')->where(['status' => ProjectTask::STATUS_ACTIVE]);
|
return $this->hasMany(ProjectTask::class, ['column_id' => 'id'])
|
||||||
|
->with('taskUsers')
|
||||||
|
->where(['status' => ProjectTask::STATUS_ACTIVE])
|
||||||
|
->orderBy('priority');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -116,7 +116,7 @@ class ProjectTask extends ActiveRecord
|
|||||||
'executor_id',
|
'executor_id',
|
||||||
'priority',
|
'priority',
|
||||||
'executor' => function () {
|
'executor' => function () {
|
||||||
if ($this->executor){
|
if ($this->executor) {
|
||||||
return [
|
return [
|
||||||
"fio" => $this->executor->userCard->fio ?? $this->executor->username,
|
"fio" => $this->executor->userCard->fio ?? $this->executor->username,
|
||||||
"avatar" => $this->executor->userCard->photo ?? '',
|
"avatar" => $this->executor->userCard->photo ?? '',
|
||||||
@ -125,10 +125,11 @@ class ProjectTask extends ActiveRecord
|
|||||||
|
|
||||||
return null;
|
return null;
|
||||||
},
|
},
|
||||||
'comment_count' => function(){
|
'comment_count' => function () {
|
||||||
return Comment::find()->where(['entity_id' => $this->id, 'entity_type' => 2, 'status' => Comment::STATUS_ACTIVE])->count();
|
return Comment::find()->where(['entity_id' => $this->id, 'entity_type' => 2, 'status' => Comment::STATUS_ACTIVE])->count();
|
||||||
},
|
},
|
||||||
'taskUsers',
|
'taskUsers',
|
||||||
|
'timers',
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -191,6 +192,11 @@ class ProjectTask extends ActiveRecord
|
|||||||
return $this->hasMany(ProjectTaskUser::className(), ['task_id' => 'id']);
|
return $this->hasMany(ProjectTaskUser::className(), ['task_id' => 'id']);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function getTimers()
|
||||||
|
{
|
||||||
|
return $this->hasMany(Timer::class, ['entity_id' => 'id'])->where(['status' => Timer::STATUS_ACTIVE]);
|
||||||
|
}
|
||||||
|
|
||||||
public static function usersByTaskArr($task_id): array
|
public static function usersByTaskArr($task_id): array
|
||||||
{
|
{
|
||||||
return ArrayHelper::map(
|
return ArrayHelper::map(
|
||||||
|
117
common/models/Timer.php
Normal file
117
common/models/Timer.php
Normal file
@ -0,0 +1,117 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace common\models;
|
||||||
|
|
||||||
|
use common\classes\Debug;
|
||||||
|
use Yii;
|
||||||
|
use yii\behaviors\TimestampBehavior;
|
||||||
|
use yii\db\Expression;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This is the model class for table "timer".
|
||||||
|
*
|
||||||
|
* @property int $id
|
||||||
|
* @property string $created_at
|
||||||
|
* @property string $stopped_at
|
||||||
|
* @property int $user_id
|
||||||
|
* @property int $entity_type
|
||||||
|
* @property int $entity_id
|
||||||
|
* @property int $status
|
||||||
|
*/
|
||||||
|
class Timer extends \yii\db\ActiveRecord
|
||||||
|
{
|
||||||
|
const STATUS_ACTIVE = 1;
|
||||||
|
const STATUS_DISABLE = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public static function tableName()
|
||||||
|
{
|
||||||
|
return 'timer';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function rules()
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
[['created_at', 'stopped_at'], 'safe'],
|
||||||
|
[['user_id', 'entity_type', 'entity_id'], 'required'],
|
||||||
|
[['user_id', 'entity_type', 'entity_id', 'status'], 'integer'],
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function attributeLabels()
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'id' => 'ID',
|
||||||
|
'created_at' => 'Created At',
|
||||||
|
'stopped_at' => 'Stopped At',
|
||||||
|
'user_id' => 'User ID',
|
||||||
|
'entity_type' => 'Entity Type',
|
||||||
|
'entity_id' => 'Entity ID',
|
||||||
|
'status' => 'Status',
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function fields(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'id',
|
||||||
|
'user_id',
|
||||||
|
'created_at',
|
||||||
|
'stopped_at',
|
||||||
|
'entity_id',
|
||||||
|
'entity_type',
|
||||||
|
'delta' => function(){
|
||||||
|
return $this->getDelta();
|
||||||
|
},
|
||||||
|
'deltaSeconds' => function(){
|
||||||
|
return $this->getDeltaSeconds();
|
||||||
|
},
|
||||||
|
'status',
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return \DateInterval|false
|
||||||
|
*/
|
||||||
|
public function getDelta()
|
||||||
|
{
|
||||||
|
$create = date_create($this->created_at);
|
||||||
|
$stopped = date_create($this->stopped_at);
|
||||||
|
|
||||||
|
return date_diff($create, $stopped);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
public function getDeltaSeconds(): int
|
||||||
|
{
|
||||||
|
$create = date_create($this->created_at);
|
||||||
|
$stopped = date_create($this->stopped_at);
|
||||||
|
|
||||||
|
return $stopped->getTimestamp() - $create->getTimestamp();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return string[]
|
||||||
|
*/
|
||||||
|
public static function getStatusList(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
self::STATUS_ACTIVE => "Активен",
|
||||||
|
self::STATUS_DISABLE => "Не активен",
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
33
console/migrations/m230522_211727_create_timer_table.php
Normal file
33
console/migrations/m230522_211727_create_timer_table.php
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use yii\db\Migration;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handles the creation of table `{{%timer}}`.
|
||||||
|
*/
|
||||||
|
class m230522_211727_create_timer_table extends Migration
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function safeUp()
|
||||||
|
{
|
||||||
|
$this->createTable('{{%timer}}', [
|
||||||
|
'id' => $this->primaryKey(),
|
||||||
|
'created_at' => $this->dateTime(),
|
||||||
|
'stopped_at' => $this->dateTime(),
|
||||||
|
'user_id' => $this->integer(11)->notNull(),
|
||||||
|
'entity_type' => $this->integer(2)->notNull(),
|
||||||
|
'entity_id' => $this->integer(11)->notNull(),
|
||||||
|
'status' => $this->integer(1)->defaultValue(1),
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function safeDown()
|
||||||
|
{
|
||||||
|
$this->dropTable('{{%timer}}');
|
||||||
|
}
|
||||||
|
}
|
@ -2,9 +2,11 @@
|
|||||||
|
|
||||||
namespace frontend\modules\api\controllers;
|
namespace frontend\modules\api\controllers;
|
||||||
|
|
||||||
|
use common\classes\Debug;
|
||||||
use common\models\ProjectColumn;
|
use common\models\ProjectColumn;
|
||||||
use frontend\modules\api\models\Project;
|
use frontend\modules\api\models\Project;
|
||||||
use yii\web\BadRequestHttpException;
|
use yii\web\BadRequestHttpException;
|
||||||
|
use yii\web\NotFoundHttpException;
|
||||||
|
|
||||||
class ProjectColumnController extends ApiController
|
class ProjectColumnController extends ApiController
|
||||||
{
|
{
|
||||||
@ -15,6 +17,7 @@ class ProjectColumnController extends ApiController
|
|||||||
'get-column' => ['get'],
|
'get-column' => ['get'],
|
||||||
'get-column-list' => ['get'],
|
'get-column-list' => ['get'],
|
||||||
'create-column' => ['post'],
|
'create-column' => ['post'],
|
||||||
|
'set-priority' => ['post'],
|
||||||
'update-column' => ['put', 'patch'],
|
'update-column' => ['put', 'patch'],
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
@ -197,7 +200,7 @@ class ProjectColumnController extends ApiController
|
|||||||
|
|
||||||
$column->load($put, '');
|
$column->load($put, '');
|
||||||
|
|
||||||
if (!$column->validate()){
|
if (!$column->validate()) {
|
||||||
throw new BadRequestHttpException(json_encode($column->errors));
|
throw new BadRequestHttpException(json_encode($column->errors));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -206,4 +209,71 @@ class ProjectColumnController extends ApiController
|
|||||||
return $column;
|
return $column;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @OA\Post(path="/project-column/set-priority",
|
||||||
|
* summary="Установить приоритет колонок",
|
||||||
|
* description="Метод для установления приоритета колонок в проекте",
|
||||||
|
* security={
|
||||||
|
* {"bearerAuth": {}}
|
||||||
|
* },
|
||||||
|
* tags={"TaskManager"},
|
||||||
|
*
|
||||||
|
* @OA\RequestBody(
|
||||||
|
* @OA\MediaType(
|
||||||
|
* mediaType="multipart/form-data",
|
||||||
|
* @OA\Schema(
|
||||||
|
* required={"project_id", "data"},
|
||||||
|
* @OA\Property(
|
||||||
|
* property="project_id",
|
||||||
|
* type="integer",
|
||||||
|
* description="Идентификатор проекта",
|
||||||
|
* ),
|
||||||
|
* @OA\Property(
|
||||||
|
* property="data",
|
||||||
|
* type="string",
|
||||||
|
* description="Данные для обновления приоритета. Пример: [{"column_id":1,"priority":2},{"column_id":2,"priority":3}]",
|
||||||
|
* ),
|
||||||
|
* ),
|
||||||
|
* ),
|
||||||
|
* ),
|
||||||
|
* @OA\Response(
|
||||||
|
* response=200,
|
||||||
|
* description="Возвращает объект проекта",
|
||||||
|
* @OA\MediaType(
|
||||||
|
* mediaType="application/json",
|
||||||
|
* @OA\Schema(ref="#/components/schemas/Project"),
|
||||||
|
* ),
|
||||||
|
* ),
|
||||||
|
* )
|
||||||
|
*
|
||||||
|
* @return array|Project|\yii\db\ActiveRecord
|
||||||
|
* @throws BadRequestHttpException
|
||||||
|
*/
|
||||||
|
public function actionSetPriority()
|
||||||
|
{
|
||||||
|
$request = \Yii::$app->request->post();
|
||||||
|
$data = $request['data'];
|
||||||
|
|
||||||
|
$project = Project::findOne($request['project_id']);
|
||||||
|
if (empty($project)) {
|
||||||
|
throw new NotFoundHttpException('The project not found');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$data = json_decode($data, true)) {
|
||||||
|
throw new BadRequestHttpException('No valid JSON');
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ($data as $datum) {
|
||||||
|
$model = ProjectColumn::findOne($datum['column_id']);
|
||||||
|
$model->priority = $datum['priority'];
|
||||||
|
if (!$model->validate()){
|
||||||
|
throw new BadRequestHttpException($model->errors);
|
||||||
|
}
|
||||||
|
$model->save();
|
||||||
|
}
|
||||||
|
|
||||||
|
return $project;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -4,9 +4,13 @@ namespace frontend\modules\api\controllers;
|
|||||||
|
|
||||||
use common\classes\Debug;
|
use common\classes\Debug;
|
||||||
use common\models\ProjectTask;
|
use common\models\ProjectTask;
|
||||||
|
use common\models\ProjectTaskUser;
|
||||||
|
use common\models\User;
|
||||||
use common\services\TaskService;
|
use common\services\TaskService;
|
||||||
|
use frontend\modules\api\models\ProjectColumn;
|
||||||
use Yii;
|
use Yii;
|
||||||
use yii\base\InvalidConfigException;
|
use yii\base\InvalidConfigException;
|
||||||
|
use yii\web\BadRequestHttpException;
|
||||||
use yii\web\NotFoundHttpException;
|
use yii\web\NotFoundHttpException;
|
||||||
use yii\web\ServerErrorHttpException;
|
use yii\web\ServerErrorHttpException;
|
||||||
|
|
||||||
@ -20,6 +24,8 @@ class TaskController extends ApiController
|
|||||||
'get-user-tasks' => ['get'],
|
'get-user-tasks' => ['get'],
|
||||||
'create-task' => ['post'],
|
'create-task' => ['post'],
|
||||||
'update-task' => ['put', 'patch'],
|
'update-task' => ['put', 'patch'],
|
||||||
|
'add-user-to-task' => ['post'],
|
||||||
|
'del-user' => ['delete'],
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -92,7 +98,7 @@ class TaskController extends ApiController
|
|||||||
public function actionCreateTask(): ProjectTask
|
public function actionCreateTask(): ProjectTask
|
||||||
{
|
{
|
||||||
$request = Yii::$app->getRequest()->getBodyParams();
|
$request = Yii::$app->getRequest()->getBodyParams();
|
||||||
if(!isset($request['user_id']) or $request['user_id'] == null){
|
if (!isset($request['user_id']) or $request['user_id'] == null) {
|
||||||
$request['user_id'] = Yii::$app->user->id;
|
$request['user_id'] = Yii::$app->user->id;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -325,4 +331,203 @@ class TaskController extends ApiController
|
|||||||
|
|
||||||
return $modelTask;
|
return $modelTask;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @OA\Post(path="/task/add-user-to-task",
|
||||||
|
* summary="Добавить пользователя в задачу",
|
||||||
|
* description="Метод для добавления пользователя в задачу",
|
||||||
|
* security={
|
||||||
|
* {"bearerAuth": {}}
|
||||||
|
* },
|
||||||
|
* tags={"TaskManager"},
|
||||||
|
*
|
||||||
|
* @OA\RequestBody(
|
||||||
|
* @OA\MediaType(
|
||||||
|
* mediaType="multipart/form-data",
|
||||||
|
* @OA\Schema(
|
||||||
|
* required={"user_id", "task_id"},
|
||||||
|
* @OA\Property(
|
||||||
|
* property="user_id",
|
||||||
|
* type="integer",
|
||||||
|
* description="Идентификатор пользователя",
|
||||||
|
* ),
|
||||||
|
* @OA\Property(
|
||||||
|
* property="task_id",
|
||||||
|
* type="integer",
|
||||||
|
* description="Идентификатор задачи",
|
||||||
|
* ),
|
||||||
|
* ),
|
||||||
|
* ),
|
||||||
|
* ),
|
||||||
|
* @OA\Response(
|
||||||
|
* response=200,
|
||||||
|
* description="Возвращает объект связи задачи и пользователя",
|
||||||
|
* @OA\MediaType(
|
||||||
|
* mediaType="application/json",
|
||||||
|
* @OA\Schema(ref="#/components/schemas/ProjectTaskUser"),
|
||||||
|
* ),
|
||||||
|
* ),
|
||||||
|
* )
|
||||||
|
*
|
||||||
|
* @return ProjectTaskUser
|
||||||
|
* @throws NotFoundHttpException
|
||||||
|
* @throws ServerErrorHttpException
|
||||||
|
*/
|
||||||
|
public function actionAddUserToTask(): ProjectTaskUser
|
||||||
|
{
|
||||||
|
$request = \Yii::$app->request->post();
|
||||||
|
|
||||||
|
$user = User::findOne($request['user_id']);
|
||||||
|
if (!$user) {
|
||||||
|
throw new NotFoundHttpException('User not found');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (empty ($request['task_id']) or !TaskService::taskExists($request['task_id'])) {
|
||||||
|
throw new NotFoundHttpException('The task does not exist');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ProjectTaskUser::find()->where(['user_id' => $request['user_id'], 'task_id' => $request['task_id']])->exists()) {
|
||||||
|
throw new ServerErrorHttpException('The user has already been added');
|
||||||
|
}
|
||||||
|
|
||||||
|
$model = new ProjectTaskUser();
|
||||||
|
$model->load($request, '');
|
||||||
|
|
||||||
|
if (!$model->validate()) {
|
||||||
|
throw new ServerErrorHttpException($model->errors);
|
||||||
|
}
|
||||||
|
|
||||||
|
$model->save();
|
||||||
|
|
||||||
|
return $model;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @OA\Delete(path="/task/del-user",
|
||||||
|
* summary="Удаление пользователя из задачи",
|
||||||
|
* description="Метод для Удаления пользователя из задачи",
|
||||||
|
* security={
|
||||||
|
* {"bearerAuth": {}}
|
||||||
|
* },
|
||||||
|
* tags={"TaskManager"},
|
||||||
|
*
|
||||||
|
* @OA\RequestBody(
|
||||||
|
* @OA\MediaType(
|
||||||
|
* mediaType="application/x-www-form-urlencoded",
|
||||||
|
* @OA\Schema(
|
||||||
|
* required={"task_id", "user_id"},
|
||||||
|
* @OA\Property(
|
||||||
|
* property="task_id",
|
||||||
|
* type="integer",
|
||||||
|
* description="Идентификатор задачи",
|
||||||
|
* ),
|
||||||
|
* @OA\Property(
|
||||||
|
* property="user_id",
|
||||||
|
* type="integer",
|
||||||
|
* description="Идентификатор пользователя",
|
||||||
|
* ),
|
||||||
|
* ),
|
||||||
|
* ),
|
||||||
|
* ),
|
||||||
|
* @OA\Response(
|
||||||
|
* response=200,
|
||||||
|
* description="Возвращает объект задачи",
|
||||||
|
* @OA\MediaType(
|
||||||
|
* mediaType="application/json",
|
||||||
|
* @OA\Schema(ref="#/components/schemas/ProjectTask"),
|
||||||
|
* ),
|
||||||
|
* ),
|
||||||
|
* )
|
||||||
|
*
|
||||||
|
* @return ProjectTask|null
|
||||||
|
* @throws InvalidConfigException
|
||||||
|
* @throws NotFoundHttpException
|
||||||
|
*/
|
||||||
|
public function actionDelUser(): ?ProjectTask
|
||||||
|
{
|
||||||
|
$request = Yii::$app->request->getBodyParams();
|
||||||
|
|
||||||
|
$user = User::findOne($request['user_id']);
|
||||||
|
if (!$user) {
|
||||||
|
throw new NotFoundHttpException('User not found');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (empty ($request['task_id']) or !TaskService::taskExists($request['task_id'])) {
|
||||||
|
throw new NotFoundHttpException('The task does not exist');
|
||||||
|
}
|
||||||
|
|
||||||
|
ProjectTaskUser::deleteAll(['task_id' => $request['task_id'], 'user_id' => $request['user_id']]);
|
||||||
|
|
||||||
|
return TaskService::getTask($request['task_id']);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @OA\Post(path="/task/set-priority",
|
||||||
|
* summary="Установить приоритет задач",
|
||||||
|
* description="Метод для установления приоритета задач в колонке",
|
||||||
|
* security={
|
||||||
|
* {"bearerAuth": {}}
|
||||||
|
* },
|
||||||
|
* tags={"TaskManager"},
|
||||||
|
*
|
||||||
|
* @OA\RequestBody(
|
||||||
|
* @OA\MediaType(
|
||||||
|
* mediaType="multipart/form-data",
|
||||||
|
* @OA\Schema(
|
||||||
|
* required={"column_id", "data"},
|
||||||
|
* @OA\Property(
|
||||||
|
* property="column_id",
|
||||||
|
* type="integer",
|
||||||
|
* description="Идентификатор проекта",
|
||||||
|
* ),
|
||||||
|
* @OA\Property(
|
||||||
|
* property="data",
|
||||||
|
* type="string",
|
||||||
|
* description="Данные для обновления приоритета. Пример: [{"task_id":3,"priority":2},{"task_id":4,"priority":3}]",
|
||||||
|
* ),
|
||||||
|
* ),
|
||||||
|
* ),
|
||||||
|
* ),
|
||||||
|
* @OA\Response(
|
||||||
|
* response=200,
|
||||||
|
* description="Возвращает объект колонки",
|
||||||
|
* @OA\MediaType(
|
||||||
|
* mediaType="application/json",
|
||||||
|
* @OA\Schema(ref="#/components/schemas/ProjectColumn"),
|
||||||
|
* ),
|
||||||
|
* ),
|
||||||
|
* )
|
||||||
|
*
|
||||||
|
* @return ProjectColumn
|
||||||
|
* @throws BadRequestHttpException
|
||||||
|
* @throws NotFoundHttpException
|
||||||
|
*/
|
||||||
|
public function actionSetPriority(): ProjectColumn
|
||||||
|
{
|
||||||
|
$request = \Yii::$app->request->post();
|
||||||
|
$data = $request['data'];
|
||||||
|
|
||||||
|
if (!$data = json_decode($data, true)) {
|
||||||
|
throw new BadRequestHttpException('No valid JSON');
|
||||||
|
}
|
||||||
|
|
||||||
|
$column = ProjectColumn::findOne($request['column_id']);
|
||||||
|
if (empty($column)) {
|
||||||
|
throw new NotFoundHttpException('The column not found');
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ($data as $datum) {
|
||||||
|
$model = ProjectTask::findOne($datum['task_id']);
|
||||||
|
$model->priority = $datum['priority'];
|
||||||
|
if (!$model->validate()){
|
||||||
|
throw new BadRequestHttpException($model->errors);
|
||||||
|
}
|
||||||
|
$model->save();
|
||||||
|
}
|
||||||
|
|
||||||
|
return $column;
|
||||||
|
}
|
||||||
}
|
}
|
237
frontend/modules/api/controllers/TimerController.php
Normal file
237
frontend/modules/api/controllers/TimerController.php
Normal file
@ -0,0 +1,237 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace frontend\modules\api\controllers;
|
||||||
|
|
||||||
|
use common\classes\Debug;
|
||||||
|
use frontend\modules\api\models\Timer;
|
||||||
|
use yii\web\BadRequestHttpException;
|
||||||
|
use yii\web\NotFoundHttpException;
|
||||||
|
|
||||||
|
class TimerController extends ApiController
|
||||||
|
{
|
||||||
|
|
||||||
|
public function verbs(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'create' => ['post'],
|
||||||
|
'update' => ['put'],
|
||||||
|
'get-by-entity' => ['get'],
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @OA\Post(path="/timer/create",
|
||||||
|
* summary="Добавить таймер",
|
||||||
|
* description="Метод для создания таймера",
|
||||||
|
* security={
|
||||||
|
* {"bearerAuth": {}}
|
||||||
|
* },
|
||||||
|
* tags={"Timer"},
|
||||||
|
*
|
||||||
|
* @OA\RequestBody(
|
||||||
|
* @OA\MediaType(
|
||||||
|
* mediaType="multipart/form-data",
|
||||||
|
* @OA\Schema(
|
||||||
|
* required={"entity_type", "entity_id", "created_at"},
|
||||||
|
* @OA\Property(
|
||||||
|
* property="entity_type",
|
||||||
|
* type="integer",
|
||||||
|
* description="Тип сущности",
|
||||||
|
* ),
|
||||||
|
* @OA\Property(
|
||||||
|
* property="entity_id",
|
||||||
|
* type="integer",
|
||||||
|
* description="Идентификатор сущности",
|
||||||
|
* ),
|
||||||
|
* @OA\Property(
|
||||||
|
* property="created_at",
|
||||||
|
* type="datetime",
|
||||||
|
* description="Время запуска. Формат (Год-месяц-день Час:минута:секунда). Пример: 2023-05-22 21:36:55",
|
||||||
|
* example="2023-05-22 21:36:55",
|
||||||
|
* ),
|
||||||
|
* @OA\Property(
|
||||||
|
* property="status",
|
||||||
|
* type="integer",
|
||||||
|
* description="Статус комментария",
|
||||||
|
* ),
|
||||||
|
* ),
|
||||||
|
* ),
|
||||||
|
* ),
|
||||||
|
* @OA\Response(
|
||||||
|
* response=200,
|
||||||
|
* description="Возвращает объект комментария",
|
||||||
|
* @OA\MediaType(
|
||||||
|
* mediaType="application/json",
|
||||||
|
* @OA\Schema(ref="#/components/schemas/Timer"),
|
||||||
|
* ),
|
||||||
|
* ),
|
||||||
|
* )
|
||||||
|
*
|
||||||
|
* @return Timer
|
||||||
|
* @throws BadRequestHttpException
|
||||||
|
*/
|
||||||
|
public function actionCreate(): Timer
|
||||||
|
{
|
||||||
|
$request = \Yii::$app->request->post();
|
||||||
|
|
||||||
|
$user_id = \Yii::$app->user->id;
|
||||||
|
if (!$user_id) {
|
||||||
|
throw new BadRequestHttpException('User not found');
|
||||||
|
}
|
||||||
|
|
||||||
|
$request = array_diff($request, [null, '']);
|
||||||
|
|
||||||
|
//Закрываем предыдущие таймеры
|
||||||
|
$oldTimers = Timer::find()->where(['entity_id' => $request['entity_id'], 'entity_type' => $request['entity_type']])->all();
|
||||||
|
if ($oldTimers){
|
||||||
|
foreach ($oldTimers as $oldTimer){
|
||||||
|
if ($oldTimer->stopped_at == null){
|
||||||
|
$oldTimer->stopped_at = date("Y-m-d H:i:s");
|
||||||
|
$oldTimer->save();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$model = new Timer();
|
||||||
|
$model->load($request, '');
|
||||||
|
$model->user_id = $user_id;
|
||||||
|
$model->created_at = date("Y-m-d H:i:s");
|
||||||
|
|
||||||
|
if (!$model->validate()) {
|
||||||
|
throw new BadRequestHttpException(json_encode($model->errors));
|
||||||
|
}
|
||||||
|
|
||||||
|
$model->save();
|
||||||
|
|
||||||
|
return $model;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @OA\Put(path="/timer/update",
|
||||||
|
* summary="Редактировать таймер",
|
||||||
|
* description="Метод для редактирования таймера",
|
||||||
|
* security={
|
||||||
|
* {"bearerAuth": {}}
|
||||||
|
* },
|
||||||
|
* tags={"Timer"},
|
||||||
|
*
|
||||||
|
* @OA\RequestBody(
|
||||||
|
* @OA\MediaType(
|
||||||
|
* mediaType="application/x-www-form-urlencoded",
|
||||||
|
* @OA\Schema(
|
||||||
|
* required={"timer_id"},
|
||||||
|
* @OA\Property(
|
||||||
|
* property="timer_id",
|
||||||
|
* type="integer",
|
||||||
|
* description="Идентификатор таймера",
|
||||||
|
* ),
|
||||||
|
* @OA\Property(
|
||||||
|
* property="stopped_at",
|
||||||
|
* type="datetime",
|
||||||
|
* description="Время завершения работы таймера",
|
||||||
|
* ),
|
||||||
|
* @OA\Property(
|
||||||
|
* property="status",
|
||||||
|
* type="integer",
|
||||||
|
* description="статус",
|
||||||
|
* ),
|
||||||
|
* ),
|
||||||
|
* ),
|
||||||
|
* ),
|
||||||
|
* @OA\Response(
|
||||||
|
* response=200,
|
||||||
|
* description="Возвращает объект Таймера",
|
||||||
|
* @OA\MediaType(
|
||||||
|
* mediaType="application/json",
|
||||||
|
* @OA\Schema(ref="#/components/schemas/Timer"),
|
||||||
|
* ),
|
||||||
|
* ),
|
||||||
|
* )
|
||||||
|
*
|
||||||
|
* @return Timer
|
||||||
|
* @throws BadRequestHttpException
|
||||||
|
* @throws \yii\base\InvalidConfigException
|
||||||
|
*/
|
||||||
|
public function actionUpdate(): Timer
|
||||||
|
{
|
||||||
|
$user_id = \Yii::$app->user->id;
|
||||||
|
if (!$user_id) {
|
||||||
|
throw new BadRequestHttpException(json_encode(['User not found']));
|
||||||
|
}
|
||||||
|
|
||||||
|
$timer_id = \Yii::$app->request->getBodyParam('timer_id');
|
||||||
|
$model = Timer::findOne($timer_id);
|
||||||
|
if (!$model) {
|
||||||
|
throw new BadRequestHttpException(json_encode(['Timer not found']));
|
||||||
|
}
|
||||||
|
|
||||||
|
$put = array_diff(\Yii::$app->request->getBodyParams(), [null, '']);
|
||||||
|
$model->load($put, '');
|
||||||
|
|
||||||
|
if(!$model->validate()){
|
||||||
|
throw new BadRequestHttpException($model->errors);
|
||||||
|
}
|
||||||
|
$model->save();
|
||||||
|
|
||||||
|
return $model;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @OA\Get(path="/timer/get-by-entity",
|
||||||
|
* summary="Получить таймер по идентификатору сущности",
|
||||||
|
* description="Метод для получения таймера по идентификатору сущности.",
|
||||||
|
* security={
|
||||||
|
* {"bearerAuth": {}}
|
||||||
|
* },
|
||||||
|
* tags={"Timer"},
|
||||||
|
* @OA\Parameter(
|
||||||
|
* name="entity_id",
|
||||||
|
* in="query",
|
||||||
|
* required=true,
|
||||||
|
* @OA\Schema(
|
||||||
|
* type="integer",
|
||||||
|
* default=null
|
||||||
|
* )
|
||||||
|
* ),
|
||||||
|
*
|
||||||
|
* @OA\Parameter(
|
||||||
|
* name="entity_type",
|
||||||
|
* in="query",
|
||||||
|
* required=true,
|
||||||
|
* @OA\Schema(
|
||||||
|
* type="integer",
|
||||||
|
* default=null
|
||||||
|
* )
|
||||||
|
* ),
|
||||||
|
*
|
||||||
|
* @OA\Response(
|
||||||
|
* response=200,
|
||||||
|
* description="Возвращает массив объектов Таймера",
|
||||||
|
* @OA\MediaType(
|
||||||
|
* mediaType="application/json",
|
||||||
|
* @OA\Schema(ref="#/components/schemas/TimerExample"),
|
||||||
|
* ),
|
||||||
|
* ),
|
||||||
|
* )
|
||||||
|
*
|
||||||
|
* @param int $entity_type
|
||||||
|
* @param int $entity_id
|
||||||
|
* @return array
|
||||||
|
* @throws NotFoundHttpException
|
||||||
|
*/
|
||||||
|
public function actionGetByEntity(int $entity_type, int $entity_id): array
|
||||||
|
{
|
||||||
|
$model = Timer::find()->where(['entity_type' => $entity_type, 'entity_id' => $entity_id, 'status' => Timer::STATUS_ACTIVE])->all();
|
||||||
|
|
||||||
|
if (!$model) {
|
||||||
|
throw new NotFoundHttpException('The timer not found');
|
||||||
|
}
|
||||||
|
|
||||||
|
return $model;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -52,20 +52,32 @@ namespace frontend\modules\api\models;
|
|||||||
* "taskUsers": {
|
* "taskUsers": {
|
||||||
* {"id": 2, "task_id": 95, "user_id": 2, "fio": "Сапронов Антон Викторович", "avatar": "/profileava/m8.png"},
|
* {"id": 2, "task_id": 95, "user_id": 2, "fio": "Сапронов Антон Викторович", "avatar": "/profileava/m8.png"},
|
||||||
* {"id": 3, "task_id": 95, "user_id": 3, "fio": "Иванов Иван Иванович", "avatar": "/profileava/m2.png"},
|
* {"id": 3, "task_id": 95, "user_id": 3, "fio": "Иванов Иван Иванович", "avatar": "/profileava/m2.png"},
|
||||||
|
* },
|
||||||
|
* "timers": {
|
||||||
|
* {"id": 12, "created_at": "2023-04-07 02:09:42", "stopped_at": "2023-04-10 16:20:48", "user_id": 19, "entity_type": 2, "entity_id": 95, "deltaSeconds": 456, "status": 1}
|
||||||
* }
|
* }
|
||||||
* },
|
* },
|
||||||
* {"id": 96, "title": "Простая задача", "project_id": 44, "column_id": 1, "user_id": 19, "description": "Описание простой задачи", "status": 1, "comment_count": 4,
|
* {"id": 96, "title": "Простая задача", "project_id": 44, "column_id": 1, "user_id": 19, "description": "Описание простой задачи", "status": 1, "comment_count": 4,
|
||||||
* "taskUsers": {
|
* "taskUsers": {
|
||||||
* {"id": 3, "task_id": 96, "user_id": 3, "fio": "Иванов Иван Иванович", "avatar": "/profileava/m2.png"},
|
* {"id": 3, "task_id": 96, "user_id": 3, "fio": "Иванов Иван Иванович", "avatar": "/profileava/m2.png"},
|
||||||
* {"id": 4, "task_id": 96, "user_id": 4, "fio": "Петров Петр Петрович", "avatar": "/profileava/m7.png"},
|
* {"id": 4, "task_id": 96, "user_id": 4, "fio": "Петров Петр Петрович", "avatar": "/profileava/m7.png"},
|
||||||
|
* },
|
||||||
|
* "timers": {
|
||||||
|
* {"id": 13, "created_at": "2023-04-08 02:09:42", "stopped_at": "2023-04-09 16:20:48", "user_id": 19, "entity_type": 2, "entity_id": 96, "deltaSeconds": 654, "status": 1}
|
||||||
* }
|
* }
|
||||||
* }
|
* }
|
||||||
* }
|
* }
|
||||||
* },
|
* },
|
||||||
* {"id": 2, "title": "Новые задачи", "project_id": 95, "status": 1, "priority": 2,
|
* {"id": 2, "title": "Новые задачи", "project_id": 95, "status": 1, "priority": 2,
|
||||||
* "tasks": {
|
* "tasks": {
|
||||||
* {"id": 97, "title": "Очень Сложная задача", "project_id": 44, "column_id": 2, "user_id": 19, "description": "Описание простой задачи", "status": 1, "comment_count": 2},
|
* {"id": 97, "title": "Очень Сложная задача", "project_id": 44, "column_id": 2, "user_id": 19, "description": "Описание простой задачи", "status": 1, "comment_count": 2,
|
||||||
* {"id": 98, "title": "Очень Простая задача", "project_id": 44, "column_id": 2, "user_id": 19, "description": "Описание очень простой задачи", "status": 1, "comment_count": 3}
|
* "taskUsers": {},
|
||||||
|
* "timers": {}
|
||||||
|
* },
|
||||||
|
* {"id": 98, "title": "Очень Простая задача", "project_id": 44, "column_id": 2, "user_id": 19, "description": "Описание очень простой задачи", "status": 1, "comment_count": 3,
|
||||||
|
* "taskUsers": {},
|
||||||
|
* "timers": {}
|
||||||
|
* }
|
||||||
* }
|
* }
|
||||||
* }
|
* }
|
||||||
* },
|
* },
|
||||||
|
@ -80,6 +80,10 @@ namespace frontend\modules\api\models;
|
|||||||
* property="taskUsers",
|
* property="taskUsers",
|
||||||
* ref="#/components/schemas/ProjectTaskUsersExample",
|
* ref="#/components/schemas/ProjectTaskUsersExample",
|
||||||
* ),
|
* ),
|
||||||
|
* @OA\Property(
|
||||||
|
* property="timers",
|
||||||
|
* ref="#/components/schemas/TimerExample",
|
||||||
|
* ),
|
||||||
*)
|
*)
|
||||||
*
|
*
|
||||||
* @OA\Schema(
|
* @OA\Schema(
|
||||||
|
27
frontend/modules/api/models/ProjectTaskUser.php
Normal file
27
frontend/modules/api/models/ProjectTaskUser.php
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace frontend\modules\api\models;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @OA\Schema(
|
||||||
|
* schema="ProjectTaskUser",
|
||||||
|
* @OA\Property(
|
||||||
|
* property="user_id",
|
||||||
|
* type="int",
|
||||||
|
* example=19,
|
||||||
|
* description="Идентификатор пользователя"
|
||||||
|
* ),
|
||||||
|
* @OA\Property(
|
||||||
|
* property="task_user",
|
||||||
|
* type="int",
|
||||||
|
* example=23,
|
||||||
|
* description="Идентификатор задачи"
|
||||||
|
* ),
|
||||||
|
*)
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
class ProjectTaskUser extends \common\models\ProjectTaskUser
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
70
frontend/modules/api/models/Timer.php
Normal file
70
frontend/modules/api/models/Timer.php
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace frontend\modules\api\models;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @OA\Schema(
|
||||||
|
* schema="Timer",
|
||||||
|
* @OA\Property(
|
||||||
|
* property="id",
|
||||||
|
* type="int",
|
||||||
|
* example=12,
|
||||||
|
* description="Идентификатор таймера"
|
||||||
|
* ),
|
||||||
|
* @OA\Property(
|
||||||
|
* property="created_at",
|
||||||
|
* type="datetime",
|
||||||
|
* example="2023-04-07 02:09:42",
|
||||||
|
* description="Дата и время создания"
|
||||||
|
* ),
|
||||||
|
* @OA\Property(
|
||||||
|
* property="stopped_at",
|
||||||
|
* type="datetime",
|
||||||
|
* example="2023-04-10 16:20:48",
|
||||||
|
* description="Дата и время остановки"
|
||||||
|
* ),
|
||||||
|
* @OA\Property(
|
||||||
|
* property="user_id",
|
||||||
|
* type="integer",
|
||||||
|
* example=19,
|
||||||
|
* description="Идентификатор пользователя"
|
||||||
|
* ),
|
||||||
|
* @OA\Property(
|
||||||
|
* property="entity_type",
|
||||||
|
* type="int",
|
||||||
|
* example=2,
|
||||||
|
* description="Идентификатор типа сущности таймера"
|
||||||
|
* ),
|
||||||
|
* @OA\Property(
|
||||||
|
* property="entity_id",
|
||||||
|
* type="int",
|
||||||
|
* example=2,
|
||||||
|
* description="Идентификатор сущности таймера"
|
||||||
|
* ),
|
||||||
|
* @OA\Property(
|
||||||
|
* property="deltaSeconds",
|
||||||
|
* type="int",
|
||||||
|
* example=547,
|
||||||
|
* description="Время между началом и завершением таймера в секундах"
|
||||||
|
* ),
|
||||||
|
* @OA\Property(
|
||||||
|
* property="status",
|
||||||
|
* type="integer",
|
||||||
|
* example="1",
|
||||||
|
* description="Статус"
|
||||||
|
* ),
|
||||||
|
*)
|
||||||
|
*
|
||||||
|
* @OA\Schema(
|
||||||
|
* schema="TimerExample",
|
||||||
|
* type="array",
|
||||||
|
* @OA\Items(
|
||||||
|
* ref="#/components/schemas/Timer",
|
||||||
|
* ),
|
||||||
|
*)
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
class Timer extends \common\models\Timer
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user