diff --git a/common/services/InterviewRequestService.php b/common/services/InterviewRequestService.php new file mode 100644 index 0000000..2d99e48 --- /dev/null +++ b/common/services/InterviewRequestService.php @@ -0,0 +1,27 @@ +attributes = $attributes; + + $interviewRequest->created_at = time(); + $interviewRequest->user_id = \Yii::$app->user->id; + + if ($interviewRequest->save()) { + \Yii::$app->telegram_bot->sendRenderedMessage('interview_request', $attributes); + } + + return $interviewRequest; + } + +} \ No newline at end of file diff --git a/common/services/ProfileService.php b/common/services/ProfileService.php index fa54657..fc47886 100644 --- a/common/services/ProfileService.php +++ b/common/services/ProfileService.php @@ -4,59 +4,120 @@ namespace common\services; use common\models\Manager; use common\models\ManagerEmployee; +use common\models\UserCard; +use frontend\modules\api\models\ProfileSearchForm; +use Yii; +use yii\web\BadRequestHttpException; +use yii\web\ServerErrorHttpException; class ProfileService { - private $searcherID; - private $id; - - public function __construct($searcherID, $id) + /** + * @throws ServerErrorHttpException + */ + public static function getMainData($user_id): array { - $this->searcherID = $searcherID; - $this->id = $id; + $userCard = UserCard::findOne(['id_user' => $user_id]); + if (empty($userCard)) { + throw new ServerErrorHttpException(json_encode($userCard->errors)); + } + return array('fio' => $userCard->fio, + 'photo' => $userCard->photo, + 'gender' => $userCard->gender, + 'level' => $userCard->level, + 'years_of_exp' => $userCard->years_of_exp, + 'specification' => $userCard->specification, + 'position_name' => $userCard->position->name); } - public function checkReportePermission() + /** + * @throws BadRequestHttpException + */ + public static function getProfile($id, $request)//: ?array { - if ($this->isMyProfile() or $this->isMyEmployee()) { + $searchModel = new ProfileSearchForm(); + $searchModel->attributes = $request; + + if ($id) { + return $searchModel->byId(); + } + return $searchModel->byParams(); + } + + /** + * @throws BadRequestHttpException + */ + public static function getProfileWithReportPermission($user_card_id): ?array + { + if (UserCard::find()->where(['id' => $user_card_id])->exists()) { + + $searchModel = new ProfileSearchForm(); + $searchModel->id = $user_card_id; + $profile = $searchModel->byId(); + + self::addPermission($profile, $user_card_id); + return $profile; + } + throw new BadRequestHttpException(json_encode('There is no user with this id')); + } + + private static function addPermission(&$profile, $user_card_id) + { + $searcherCardID = self::getSearcherCardID(Yii::$app->user->getId()); + if (self::checkReportPermission($user_card_id, $searcherCardID)) { + $profile += ['report_permission' => '1']; + } else { + $profile += ['report_permission' => '0']; + } + } + + private static function getSearcherCardID($user_id): int + { + return UserCard::findOne(['id_user' => $user_id])->id; + } + + private static function checkReportPermission($user_card_id, $searcherCardID): bool + { + if (self::isMyProfile($user_card_id, $searcherCardID) + or self::isMyEmployee($user_card_id, $searcherCardID)) { return true; } return false; } - private function isMyProfile() + private static function isMyProfile($user_card_id, $searcherCardID): bool { - if ($this->id == $this->searcherID) { + if ($user_card_id == $searcherCardID) { return true; } return false; } - private function isMyEmployee() + private static function isMyEmployee($user_card_id, $searcherCardID): bool { - if (!$this->amIManager()) { - return false; - } + if (!self::amIManager($searcherCardID)) { + return false; + } - if ($this->isMyEmploee()) { - return true; - } - return false; - } - - private function amIManager() - { - if (Manager::find()->where(['user_card_id' => $this->searcherID])->exists()) { + if (self::isMyEmployer($user_card_id, $searcherCardID)) { return true; } return false; } - private function isMyEmploee() + private static function amIManager($searcherCardID): bool { - $manager = Manager::find()->where(['user_card_id' => $this->searcherID])->one(); + if (Manager::find()->where(['user_card_id' => $searcherCardID])->exists()) { + return true; + } + return false; + } + + private static function isMyEmployer($user_card_id, $searcherCardID): bool + { + $manager = Manager::find()->where(['user_card_id' => $searcherCardID])->one(); $exist = ManagerEmployee::find() - ->where(['manager_id' => $manager->id, 'user_card_id' => $this->id]) + ->where(['manager_id' => $manager->id, 'user_card_id' => $user_card_id]) ->exists(); if ($exist) { @@ -64,7 +125,4 @@ class ProfileService } return false; } - - - } \ No newline at end of file diff --git a/common/services/UserCardService.php b/common/services/UserCardService.php deleted file mode 100644 index bb743c2..0000000 --- a/common/services/UserCardService.php +++ /dev/null @@ -1,27 +0,0 @@ - $user_id]); - if (empty($userCard)) { - throw new ServerErrorHttpException(json_encode($userCard->errors)); - } - return array('fio' => $userCard->fio, - 'photo' => $userCard->photo, - 'gender' => $userCard->gender, - 'level' => $userCard->level, - 'years_of_exp' => $userCard->years_of_exp, - 'specification' => $userCard->specification, - 'position_name' => $userCard->position->name); - } -} \ No newline at end of file diff --git a/docs/api/interview.md b/docs/api/interview.md new file mode 100644 index 0000000..1cc58ac --- /dev/null +++ b/docs/api/interview.md @@ -0,0 +1,54 @@ +## Интервью +### Пригласить на собеседование +`https://guild.craft-group.xyz/api/interview-request/create-interview-request` + +
+ Для того, отправить приглашение профилю на собеседование, необходимо сделать + POST запрос на URL https://guild.craft-group.xyz/api/interview-request/create-interview-request +
++ Возможные параметры: +
++ Параметры + | ++ Значение + | +
---|---|
+ email* + | ++ Почта пользователя, который хочет пригласить на собеседование. + | +
+ profile_id* + | ++ Идентификатор профиля. + | +
+ phone + | ++ Телефон. + | +
+ comment + | ++ Дополнительные пожелания по собеседованию. + | +
- Для получения списка профилей необходимо отправить GET запрос на URL https://guild.craft-group.xyz/api/profile -
-- Возможные параметры: -
-- Параметры - | -- Значение - | -
---|---|
- get-document-list - | -- Количество профилей, которое вернет сервер при запросе. - | -
- offset - | -- Количество записей на которое нужно отступить в списке профилей. - | -
- skills - | -- Идентификаторы навыков по которым нужно отфильтровать профили. - | -
- Пример запроса: -
- -`https://guild.craft-group.xyz/api/profile?limit=5&offset=5&skills=1,2` - -
- Возвращает массив объектов Профилей.
- Каждый объект Профиля имеет такой вид:
-
- Для того, чтобы получить данные одной записи необходимо отправить GET запрос - на URL https://guild.craft-group.xyz/api/profile/{id} , где id это идентификатор - профиля. -
-- Пример запроса: -
- -`https://guild.craft-group.xyz/api/profile/6` - -
- Возвращает объект Профиля.
- Как выглядит можно посмотреть выше.
-
- Для того, отправить приглашение профилю на собеседование, необходимо сделать - POST запрос на URL https://guild.craft-group.xyz/api/profile/add-to-interview -
-- Возможные параметры: -
-- Параметры - | -- Значение - | -
---|---|
- email* - | -- Почта пользователя, который хочет пригласить на собеседование. - | -
- profile_id* - | -- Идентификатор профиля. - | -
- phone - | -- Телефон. - | -
- comment - | -- Дополнительные пожелания по собеседованию. - | -
Для назначения исполнителя необходимо отправить POST запрос на URL https://guild.craft-group.xyz/api/task-user/set-task-user
diff --git a/docs/api/profile.md b/docs/api/profile.md new file mode 100644 index 0000000..f795fa9 --- /dev/null +++ b/docs/api/profile.md @@ -0,0 +1,308 @@ +# Профиль +## Методы ++ Метод + | ++ Описание + | +
---|---|
+ api/profile + | ++ Возвращает список профилей + | +
+ api/profile/{id} + | ++ Возвращает один профиль + | +
+ profile/profile-with-report-permission + | ++ Получить профиль с флагом прав на просмотр отчётов этого пользователя + | +
+ profile/get-main-data + | ++ Получить получить основные данные профиля + | +
+ Для получения списка профилей необходимо отправить GET запрос на URL https://guild.craft-group.xyz/api/profile +
++ Возможные параметры: +
++ Параметры + | ++ Значение + | +
---|---|
+ get-document-list + | ++ Количество профилей, которое вернет сервер при запросе. + | +
+ offset + | ++ Количество записей на которое нужно отступить в списке профилей. + | +
+ skills + | ++ Идентификаторы навыков по которым нужно отфильтровать профили. + | +
+ Пример запроса: +
+ +`https://guild.craft-group.xyz/api/profile?limit=5&offset=5&skills=1,2` + +
+ Возвращает массив объектов Профилей.
+ Каждый объект Профиля имеет такой вид:
+
+ Для того, чтобы получить данные одной записи необходимо отправить GET запрос + на URL https://guild.craft-group.xyz/api/profile/{id} , где id это идентификатор + профиля. +
++ Пример запроса: +
+ +`https://guild.craft-group.xyz/api/profile/6` + +
+ Возвращает объект Профиля.
+ Как выглядит можно посмотреть выше.
+
+ Для получения профиля пользователя с флагом прав на просмотр отчётов этого пользователя, необходимо сделать + GET запрос на URL https://guild.craft-group.xyz/api/profile/add-to-interview +
++ Возможные параметры: +
++ Параметры + | ++ Значение + | +
---|---|
+ id + | ++ ID профиля пользователя + | +
+ Требуемые параметры: +
++ Параметры + | ++ Значение + | +
---|---|
+ user_id + | ++ Id профиля пользователя + | +
+ Возвращает объект Пользователь.
+ Каждый объект Пользователь имеет такой вид:
+
+ Возвращаемые параметры: +
++ Параметры + | ++ Значение + | +
---|---|
+ fio + | ++ ФИО + | +
+ photo + | ++ Ссылка на фото + | +
+ gender + | ++ Пол + | +
+ level + | ++ Уровень + | +
+ years_of_exp + | ++ Лет опыта + | +
+ position_name + | ++ Должность + | +
+ Метод + | ++ Описание + | +
---|---|
+ questionnaire/questionnaires-list + | ++ Возвращает список анкет + | +
+ questionnaire/questionnaire-completed + | ++ Завершение прохождение анкеты, проверка ответов + | +
+ questionnaire/get-points-number + | ++ Число балов в анкете + | +
+ questionnaire/get-question-number + | ++ Число вопросов в анкете + | +
+ question/get-questions + | ++ Вопросы анкеты + | +
+ answer/get-answers + | ++ Список возможных ответов на вопрос + | +
+ user-response/set-response + | ++ Сохранить ответ пользователя + | +
+ user-response/set-responses + | ++ Сохранить массив ответов пользователя + | +
+ get + | ++ Возвращает менеджера + | +
+ Для получения списка анкет необходимо отправить GET запрос на URL https://guild.craft-group.xyz/api/user-questionnaire/questionnaires-list +
+ ++ Требуемые параметры запроса: +
++ Параметры + | ++ Значение + | +
---|---|
+ user_id + | ++ ID пользователя(int) + | +
+ Пример запроса: +
+ +`https://guild.craft-group.xyz/api/user-questionnaire/questionnaires-list?user_id=1` + +
+ Возвращает массив объектов записи Назначенная анкета.
+ Каждый объектимеет такой вид:
+
+ Возвращаемые параметры объекта анкета: +
++ Параметры + | ++ Значение + | +
---|---|
+ user_id + | ++ ID пользователя(int) + | +
+ uuid + | ++ uuid анкеты пользователя + | +
+ score + | ++ Полученные балы(int) + | +
+ status + | ++ Статус: 0 - не активен; 1 - активен; 2 - завершён; 3 - на проверке; + | +
+ percent_correct_answers + | ++ Процент правильных ответов(float) + | +
+ testing_date + | ++ Дата тестирования + | +
+ questionnaire_title + | ++ Название анкеты + | +
+ Передаваемые параметры объекта вопроса: +
++ Параметры + | ++ Значение + | +
---|---|
+ user_id + | ++ ID пользователя(int) + | +
+ score + | ++ Полученные балы(int) + | +
+ percent_correct_answers + | ++ Процент правильных ответов(float) + | +
+ Если пользователь не найден или у пользователя нет активных анкет будет отправлено следующее сообщение: +
+ +```json5 +{ + "name": "Not Found", + "message": "Active questionnaire not found", + "code": 0, + "status": 404, + "type": "yii\\web\\NotFoundHttpException" +} +``` + +### Проверить ответы в анкете + +`https://guild.craft-group.xyz/api/user-questionnaire/questionnaire-completed` ++ Для выполнения проверки анкеты необходимо отправить GET запрос на URL https://guild.craft-group.xyz/api/user-questionnaire/questionnaire-completed +
+ ++ Требуемые параметры запроса: +
++ Параметры + | ++ Значение + | +
---|---|
+ user_questionnaire_uuid + | ++ UUID анкеты назначеной пользователю + | +
+ Пример запроса: +
+ +`https://guild.craft-group.xyz/api/user-questionnaire/questionnaire-completed?user_questionnaire_uuid=d222f858-60fd-47fb-8731-dc9d5fc384c5` + +
+ Возвращает массив объектов Вопросов.
+ Каждый объект Вопрос имеет такой вид:
+
+ Для максимального числа балов в анкеты необходимо отправить GET запрос на URL https://guild.craft-group.xyz/api/user-questionnaire/get-points-number +
+ ++ Требуемые параметры запроса: +
++ Параметры + | ++ Значение + | +
---|---|
+ user_questionnaire_uuid + | ++ UUID анкеты назначеной пользователю + | +
+ Пример запроса: +
+ +`https://guild.craft-group.xyz/api/user-questionnaire/get-points-number?user_questionnaire_uuid=d222f858-60fd-47fb-8731-dc9d5fc384c5` + +
+ Возвращает максимально возможное число балов за анкету b>.
+ Объект Ответа имеет такой вид:
+
+ Для числа вопросов в анкете необходимо отправить GET запрос на URL https://guild.craft-group.xyz/api/user-questionnaire/get-question-number +
+ ++ Требуемые параметры запроса: +
++ Параметры + | ++ Значение + | +
---|---|
+ user_questionnaire_uuid + | ++ UUID анкеты назначеной пользователю + | +
+ Пример запроса: +
+ +`https://guild.craft-group.xyz/api/user-questionnaire/get-question-number?user_questionnaire_uuid=d222f858-60fd-47fb-8731-dc9d5fc384c5` + +
+ Возвращает число вопросов в анкете b>.
+ Объект Ответа имеет такой вид:
+
+ Для получения вопросов анкеты необходимо отправить GET запрос на URL https://guild.craft-group.xyz/api/question/get-questions +
+ ++ Требуемые параметры запроса: +
++ Параметры + | ++ Значение + | +
---|---|
+ uuid + | ++ UUID анкеты назначеной пользователю + | +
+ Пример запроса: +
+ +`https://guild.craft-group.xyz/api/question/get-questions?uuid=d222f858-60fd-47fb-8731-dc9d5fc384c5` + +
+ Возвращает массив объектов Вопросов.
+ Каждый объект Вопрос имеет такой вид:
+
+ Передаваемые параметры объекта вопроса: +
++ Параметры + | ++ Значение + | +
---|---|
+ id + | ++ ID вопроса(int) + | +
+ question_type_id + | ++ ID типа вопроса(int) + | +
+ question_body + | ++ Вопрос(string) + | +
+ question_priority + | ++ Приоритет вопроса(int)(не используется) + | +
+ next_question + | ++ Следующий вопрос(int)(не используется) + | +
+ time_limit + | ++ Ограничение времени на ответ(time) + | +
+ Если вопрос не найден или не предпологает передачу ответов будет отправлено следующее сообщение: +
+ +```json5 +{ + "name": "Not Found", + "message": "Questions not found", + "code": 0, + "status": 404, + "type": "yii\\web\\NotFoundHttpException" +} +``` + +### Ответы на вопрос + +`https://guild.craft-group.xyz/api/answer/get-answers` ++ Для получения вариантов ответов на вопрос анкеты нужно сделать GET запрос на URL https://guild.craft-group.xyz/api/answer/get-answers +
+ ++ Требуемые параметры: +
++ Параметры + | ++ Значение + | +
---|---|
+ question_id + | ++ ID вопроса + | +
+ Пример запроса: +
+ +`https://guild.craft-group.xyz/api/answer/get-answers?question_id=7` + +
+ Возвращает массив объектов Ответов.
+ Каждый объект Ответа имеет такой вид:
+
+ Передаваемые параметры объекта вопроса: +
++ Параметры + | ++ Значение + | +
---|---|
+ id + | ++ ID вопроса(int) + | +
+ question_id + | ++ ID вопроса(int) + | +
+ answer_body + | ++ Ответ(string) + | +
+ Если ответы не найдены или вопрос не предпологает их наличие(открытый вопрос) будет отправлено следующее сообщение: +
+ +```json5 +{ + "name": "Not Found", + "message": "Answer not found or question inactive", + "code": 0, + "status": 404, + "type": "yii\\web\\NotFoundHttpException" +} +``` + +### Один ответ пользователя + +`https://guild.craft-group.xyz/api/user-response/set-response` ++ Для добавления ответа на вопрос от пользователя необходимо сделать POST запрос на URL https://guild.craft-group.xyz/api/user-response/set-response +
+ ++ Тело запроса содержит: +
++ Параметры + | ++ Значение + | +
---|---|
+ user_id + | ++ ID пользователя + | +
+ question_id + | ++ ID вопроса(int) + | +
+ response_body + | ++ Ответ пользователя(string 255) + | +
+ user_questionnaire_uuid + | ++ UUID анкеты назначенной пользователю(string 36) + | +
+ Пример тела запроса: +
+ +```json5 +{ + "user_id": "1", + "question_id": "7", + "response_body": "oooooooooooo111111111", + "user_questionnaire_uuid": "d222f858-60fd-47fb-8731-dc9d5fc384c5" +} +``` + +`https://guild.craft-group.xyz/api/user-response/set-response` + +
+ Возвращает объект Ответа.
+ Объект Ответа имеет такой вид:
+
+ Ответ содержит: +
++ Параметры + | ++ Значение + | +
---|---|
+ user_id + | ++ ID пользователя + | +
+ question_id + | ++ ID вопроса(int) + | +
+ response_body + | ++ Ответ пользователя(string 255) + | +
+ user_questionnaire_uuid + | ++ UUID анкеты назначенной пользователю(string 36) + | +
+ answer_flag + | ++ Флаг ответа(1 - верно, 0 - ложно). Если отправлен ответ на открытый вопрос, флаг ответа не будет возвращаться до момента проверки в админ панели. + | +
+ В случаии ошибки в запросе будет отправлено сообщение следующего вида: +
+ +```json5 +{ + "name": "Bad Request", + "message": "{\"question_id\":[\"\В\о\п\р\о\с is invalid.\"]}", + "code": 0, + "status": 400, + "type": "yii\\web\\BadRequestHttpException" +} +``` + +### Массив ответов пользователя + +`https://guild.craft-group.xyz/api/user-response/set-responses` ++ Для добавления массива ответов на вопросы от пользователя необходимо сделать POST запрос на URL https://guild.craft-group.xyz/api/user-response/set-responses +
+ ++ Тело запроса содержит JSON c массивом ответов со следующими параметрами: +
++ Параметры + | ++ Значение + | +
---|---|
+ user_id + | ++ ID пользователя + | +
+ question_id + | ++ ID вопроса(int) + | +
+ response_body + | ++ Ответ пользователя(string 255) + | +
+ user_questionnaire_uuid + | ++ UUID анкеты назначенной пользователю(string 36) + | +
+ Пример тела запроса: +
+ +```json5 +{ + "userResponses": [ + { + "user_id": "1", + "question_id": "7", + "response_body": "oooooooooooo111111111", + "user_questionnaire_uuid": "d222f858-60fd-47fb-8731-dc9d5fc384c5" + }, + { + "user_id": "1", + "question_id": "4", + "response_body": "oooooooooooo2222222", + "user_questionnaire_uuid": "d222f858-60fd-47fb-8731-dc9d5fc384c5" + } + ] +} +``` + +
+ Возвращает массив объектов ОтветПользователя.
+ Пример:
+
+ Ответ содержит: +
++ Параметры + | ++ Значение + | +
---|---|
+ user_id + | ++ ID пользователя + | +
+ question_id + | ++ ID вопроса(int) + | +
+ response_body + | ++ Ответ пользователя(string 255) + | +
+ user_questionnaire_uuid + | ++ UUID анкеты назначенной пользователю(string 36) + | +
+ answer_flag + | ++ Флаг ответа(1 - верно, 0 - ложно) + | +
+ В случаии ошибки в запросе будет отправлено сообщение следующего вида: +
+ +```json5 +{ + "name": "Bad Request", + "message": "{\"question_id\":[\"\В\о\п\р\о\с is invalid.\"]}", + "code": 0, + "status": 400, + "type": "yii\\web\\BadRequestHttpException" +} +``` diff --git a/docs/api/reports.md b/docs/api/reports.md new file mode 100644 index 0000000..97fe3dc --- /dev/null +++ b/docs/api/reports.md @@ -0,0 +1,434 @@ +## Отчеты +## Методы ++ Метод + | ++ Описание + | +
---|---|
+ api/reports + | ++ Список отчётов + | +
+ api/reports/{id} + | ++ Один отчёт + | +
+ find-by-date + | ++ Отчёт по дате + | +
+ create + | ++ Создать отчёт + | +
+ delete + | ++ Удалить отчёт + | +
+ update + | ++ Изменить отчёт + | +
+ Для получения списка отчетов необходимо отправить GET запрос на URL https://guild.craft-group.xyz/api/reports +
+ ++ Возможные параметры: +
++ Параметры + | ++ Значение + | +
---|---|
+ fromDate* + | ++ Дата (yyyy-mm-dd) начала поиска отчетов. + | +
+ toDate + | ++ Дата (yyyy-mm-dd) окончания поиска отчетов. + | +
+ limit + | ++ Количество отчетов, которое вернет сервер при запросе (по умолчанию 10). + | +
+ offset + | ++ Количество записей на которое нужно отступить в списке отчетов. + | +
+ user_id + | ++ Идентификатор карточки пользователя отчета. + | +
+ Пример запроса: +
+ +`https://guild.craft-group.xyz/api/reports/index?fromDate=2021-08-01&toDate=2021-08-31&user_id=2&limit=3&offset=2` + +### Один отчет +`https://guild.craft-group.xyz/api/reports/{id}` ++ Для получения отчета необходимо отправить GET запрос на URL https://guild.craft-group.xyz/api/reports/{id} +
+ ++ Параметры: +
++ Параметры + | ++ Значение + | +
---|---|
+ id* + | ++ ID отчета. + | +
+ Пример запроса на просмотр отчета с ID 13: +
+ +`https://guild.craft-group.xyz/api/reports/13` + +### Отчёт по дате +`https://guild.craft-group.xyz/api/reports/find-by-date` ++ Для получения отчета необходимо отправить GET запрос на URL https://guild.craft-group.xyz/api/reports/find-by-date +
+ ++ Требуемые параметры: +
++ Параметры + | ++ Значение + | +
---|---|
+ user_card_id* + | ++ ID профиля пользователя + | +
+ date* + | ++ Дата в формате: Y-m-d + | +
+ Пример запроса : +
+ +`https://guild.craft-group.xyz/api/reports/find-by-date?user_card_id=17&date=2022-02-14` + ++ Пример ответа: +
+ +```json5 +[ + { + "id": "1", + "created_at": "2022-02-14", + "today": null, + "difficulties": "", + "tomorrow": "", + "status": null, + "user_card_id": "17", + "task": [ + { + "id": "1", + "report_id": "1", + "task": "dfghjkl", + "hours_spent": "2", + "created_at": "1644842433", + "status": "1", + "minutes_spent": "4" + } + ] + }, + { + "id": "2", + "created_at": "2022-02-14", + "today": "dxvxv", + "difficulties": "сложности возникли", + "tomorrow": "завтра", + "status": null, + "user_card_id": "17", + "task": [ + { + "id": "2", + "report_id": "2", + "task": "54651513", + "hours_spent": "4", + "created_at": "1644842630", + "status": "1", + "minutes_spent": "2" + } + ] + } +] +``` + +### Создать отчет +`https://guild.craft-group.xyz/api/reports/create` + ++ Для того, отправить приглашение профилю на собеседование, необходимо сделать + POST запрос на URL https://guild.craft-group.xyz/api/reports/create +
++ Возможные параметры: +
++ Параметры + | ++ Значение + | +
---|---|
+ created_at* + | ++ Дата (yyyy-mm-dd) создания. + | +
+ user_card_id* + | ++ Идентификатор карточки пользователя. + | +
+ tasks* + | +
+ JSON массив содержащий объекты задач
++[{ + "task" : "Рефакторинг", + "created_at": 1638260728, + "status": 1, + "minutes_spent": 26, + "hours_spent" : 3 +}] ++ |
+
+ difficulties + | ++ Сложности. + | +
+ tomorrow + | ++ Планы на завтра. + | +
+ status + | ++ Номер статуса. + | +
+ Для удаления отчета необходимо отправить GET запрос на URL https://guild.craft-group.xyz/api/reports/delete +
+ ++ Возможные параметры: +
++ Параметры + | ++ Значение + | +
---|---|
+ id* + | ++ Идентификатор отчета. + | +
+ Пример запроса: +
+ +`https://guild.craft-group.xyz/api/reports/delete?id=17` +### Обновить отчет + +`https://guild.craft-group.xyz/api/reports/update` + ++ Для удаления отчета необходимо отправить GET запрос на URL https://guild.craft-group.xyz/api/reports/update +
+ ++ Возможные параметры: +
++ Параметры + | ++ Значение + | +
---|---|
+ id* + | ++ Идентификатор отчета. + | +
+ created_at + | ++ Дата (yyyy-mm-dd) создания. + | +
+ today + | ++ Сделанное сегодня. + | +
+ difficulties + | ++ Сложности. + | +
+ tomorrow + | ++ Планы на завтра. + | +
+ status + | ++ Номер статуса. + | +
+ Пример запроса: +
+ +`https://guild.craft-group.xyz/api/reports/update?id=18&created_at=2021-09-17&today=0&difficulties=diff&tomorrow=new task&status=1` diff --git a/docs/api/skills.md b/docs/api/skills.md new file mode 100644 index 0000000..6e21422 --- /dev/null +++ b/docs/api/skills.md @@ -0,0 +1,6 @@ +## Навыки +### Популярные навыки +`https://guild.craft-group.xyz/api/skills/skills-on-main-page` ++ Чтобы получить популярные навыки нужно сделать GET запрос на URL https://guild.craft-group.xyz/api/skills/skills-on-main-page +
diff --git a/docs/api/task-user.md b/docs/api/task-user.md new file mode 100644 index 0000000..a21e905 --- /dev/null +++ b/docs/api/task-user.md @@ -0,0 +1,200 @@ +## Исполнители задачи +## Методы ++ Метод + | ++ Описание + | +
---|---|
+ get-task-users + | ++ Список исплнителей задачи + | +
+ set-task-users + | ++ Назначить исполнителя на задачу + | +
+ Для получения списка исполнителей необходимо отправить GET запрос на URL https://guild.craft-group.xyz/api/task-user/get-task-users +
+ ++ Требуемые параметры: +
++ Параметры + | ++ Значение + | +
---|---|
+ task_id + | ++ ID задачи + | +
+ Пример запроса: +
+ +`https://guild.craft-group.xyz/api/task-user/get-task-users?task_id=10` + +
+ Возвращает массив сотрудников проекта закреплённых за задачей.
+ Каждый ответ имеет такой вид:
+
+ Параметры объекта Исполнитель: +
++ Параметры + | ++ Значение + | +
---|---|
+ id + | ++ ID исполнителя задачи(int) + | +
+ task_id + | ++ ID задачи(int) + | +
+ project_user_id + | ++ ID сотрудника на проекте(int) + | +
+ Если задача не найдена будет отправлено следующее сообщение: +
+ +```json5 +{ + "name": "Not Found", + "message": "The task does not exist or there are no employees for it", + "code": 0, + "status": 404, + "type": "yii\\web\\NotFoundHttpException" +} +``` +### Назначить сотрудника на задачу +`https://guild.craft-group.xyz/api/task-user/set-task-users` ++ Для назначения исполнителя необходимо отправить POST запрос на URL https://guild.craft-group.xyz/api/task-user/set-task-user +
+ ++ Требуемые параметры: +
++ Параметры + | ++ Значение + | +
---|---|
+ task_id + | ++ ID задачи + | +
+ project_user_id + | ++ ID сотрудника на проекте + | +
+ Пример запроса: +
+ +`https://guild.craft-group.xyz/api/task-user/set-task-user` + +
+ Возвращает объект Исполнителя задачи.
+ Каждый ответ имеет такой вид:
+
+ Если задача не найдена будет отправлено следующее сообщение: +
+ +```json5 +{ + "name": "Bad Request", + "message": "{\"task_id\":[\"\З\а\д\а\ч\а is invalid.\"]}", + "code": 0, + "status": 400, + "type": "yii\\web\\BadRequestHttpException" +} +``` \ No newline at end of file diff --git a/docs/api/task.md b/docs/api/task.md index a3f39b7..2e84803 100644 --- a/docs/api/task.md +++ b/docs/api/task.md @@ -236,7 +236,7 @@ } ``` -## Обновить документ +## Обновить задачу `https://guild.craft-group.xyz/api/task/update`diff --git a/frontend/modules/api/controllers/InterviewRequestController.php b/frontend/modules/api/controllers/InterviewRequestController.php new file mode 100644 index 0000000..8ffd2f6 --- /dev/null +++ b/frontend/modules/api/controllers/InterviewRequestController.php @@ -0,0 +1,33 @@ + ['post'] + ]; + } + + /** + * @throws InvalidConfigException + * @throws ServerErrorHttpException + */ + public function actionCreateInterviewRequest(): InterviewRequest + { + $InterviewRequestModel = InterviewRequestService::createInterviewRequest(Yii::$app->getRequest()->getBodyParams()); + if ($InterviewRequestModel->errors) { + throw new ServerErrorHttpException(json_encode($InterviewRequestModel->errors)); + } + return $InterviewRequestModel; + } +} \ No newline at end of file diff --git a/frontend/modules/api/controllers/ManagerController.php b/frontend/modules/api/controllers/ManagerController.php index 6d75aff..b31a385 100644 --- a/frontend/modules/api/controllers/ManagerController.php +++ b/frontend/modules/api/controllers/ManagerController.php @@ -2,7 +2,6 @@ namespace frontend\modules\api\controllers; - use common\services\ManagerService; use yii\web\NotFoundHttpException; @@ -24,7 +23,7 @@ class ManagerController extends ApiController { $managers = ManagerService::getManagerList(); - if(empty($managers)) { + if (empty($managers)) { throw new NotFoundHttpException('Managers are not assigned'); } @@ -36,14 +35,13 @@ class ManagerController extends ApiController */ public function actionGetManagerEmployeesList($manager_id): array { - if(empty($manager_id) or !is_numeric($manager_id)) - { + if (empty($manager_id) or !is_numeric($manager_id)) { throw new NotFoundHttpException('Incorrect manager ID'); } $managerEmployeesList = ManagerService::getManagerEmployeesList($manager_id); - if(empty($managerEmployeesList)) { + if (empty($managerEmployeesList)) { throw new NotFoundHttpException('Managers are not assigned or employees are not assigned to him'); } @@ -55,14 +53,13 @@ class ManagerController extends ApiController */ public function actionGetManager($manager_id): array { - if(empty($manager_id) or !is_numeric($manager_id)) - { + if (empty($manager_id) or !is_numeric($manager_id)) { throw new NotFoundHttpException('Incorrect manager ID'); } $manager = ManagerService::getManager($manager_id); - if(empty($manager)) { + if (empty($manager)) { throw new NotFoundHttpException('There is no such manager'); } diff --git a/frontend/modules/api/controllers/ProfileController.php b/frontend/modules/api/controllers/ProfileController.php index 027b435..70c3a7c 100755 --- a/frontend/modules/api/controllers/ProfileController.php +++ b/frontend/modules/api/controllers/ProfileController.php @@ -2,117 +2,38 @@ namespace frontend\modules\api\controllers; -use common\behaviors\GsCors; -use common\classes\Debug; -use common\models\InterviewRequest; -use common\models\User; -use common\models\UserCard; use common\services\ProfileService; -use frontend\modules\api\models\ProfileSearchForm; -use kavalar\BotNotificationTemplateProcessor; -use kavalar\TelegramBotService; -use Yii; -use yii\filters\auth\CompositeAuth; -use yii\filters\auth\HttpBearerAuth; -use yii\filters\auth\QueryParamAuth; -use yii\filters\ContentNegotiator; -use yii\helpers\ArrayHelper; use yii\web\BadRequestHttpException; -use yii\web\Response; - +use yii\web\ServerErrorHttpException; class ProfileController extends ApiController { - - public function behaviors() + public function verbs(): array { - $parent = parent::behaviors(); - $b = [ - [ - 'class' => ContentNegotiator::className(), - 'formats' => [ - 'application/json' => Response::FORMAT_JSON, - ], - ], - 'authenticator' => [ - 'class' => CompositeAuth::class, - 'authMethods' => [ - HttpBearerAuth::class, - ], - ] + return [ + '' => ['get'], + 'profile-with-report-permission' => ['post', 'patch'] ]; - - return array_merge($parent, $b); } - public function actionIndex($id = null) + public function actionIndex($id = null): ?array { - $searchModel = new ProfileSearchForm(); - $searchModel->attributes = \Yii::$app->request->get(); - - if ($id) { - return $searchModel->byId(); - } - - return $searchModel->byParams(); + return ProfileService::getProfile($id, \Yii::$app->request->get()); } - public function actionProfileWithReportPermission($id) + /** + * @throws BadRequestHttpException + */ + public function actionProfileWithReportPermission($id): ?array { - $searchModel = new ProfileSearchForm(); - $searchModel->attributes = \Yii::$app->request->get(); - - $searcherUser = Yii::$app->user->getId(); - $searcherProfileId = UserCard::findOne($searcherUser)->id; - - if ($id && $searcherProfileId) { - if(!UserCard::find()->where(['id' => $id])->exists()) - { - throw new BadRequestHttpException(json_encode('There is no user with this id')); - } - $profile = $searchModel->byId(); - - $profileService = new ProfileService($searcherProfileId, $id); - - if($profileService->checkReportePermission()) { - $profile += ['report_permission' => '1']; - } - else { - $profile += ['report_permission' => '0']; - } - return $profile; - } - - throw new BadRequestHttpException(json_encode('Missing required parameter')); + return ProfileService::getProfileWithReportPermission($id); } - public function actionAddToInterview() + /** + * @throws ServerErrorHttpException + */ + public function actionGetMainData($user_id): array { - if (\Yii::$app->request->isPost) { - $attributes = \Yii::$app->request->post(); - - $model = new InterviewRequest(); - $model->attributes = $attributes; - $model->created_at = time(); - $model->user_id = \Yii::$app->user->id; - if ($model->save()) { - \Yii::$app->telegram_bot->sendRenderedMessage('interview_request', $attributes); - return ['status' => 'success']; - } - - \Yii::$app->response->statusCode = 400; - return ['status' => 'error', 'errors' => $model->errors]; - } + return ProfileService::getMainData($user_id); } - - public function actionMe() - { - if(isset(\Yii::$app->user->id)){ - $user = User::find()->with('userCard')->where(['id' => \Yii::$app->user->id])->one(); - } - - \Yii::$app->response->statusCode = 401; - return ['status' => 'error', 'errors' => 'No authorized']; - } - -} +} \ No newline at end of file diff --git a/frontend/modules/api/controllers/TaskController.php b/frontend/modules/api/controllers/TaskController.php index 62749ce..dd9a3ef 100644 --- a/frontend/modules/api/controllers/TaskController.php +++ b/frontend/modules/api/controllers/TaskController.php @@ -31,7 +31,6 @@ class TaskController extends ApiController if ($taskModel->errors) { throw new ServerErrorHttpException(json_encode($taskModel->errors)); } - return $taskModel; } @@ -39,23 +38,19 @@ class TaskController extends ApiController /** * @throws NotFoundHttpException */ - public function actionGetTaskList($project_id = null): array + public function actionGetTaskList($project_id = null): array { $tasks = array(); - if ($project_id) - { - if(empty($project_id) or !is_numeric($project_id)) - { + if ($project_id) { + if (empty($project_id) or !is_numeric($project_id)) { throw new NotFoundHttpException('Incorrect project ID'); } $tasks = TaskService::getTaskListByProject($project_id); - } - else - { + } else { $tasks = TaskService::getTaskList($project_id); } - if(empty($tasks)) { + if (empty($tasks)) { throw new NotFoundHttpException('The project does not exist or there are no tasks for it'); } return $tasks; @@ -66,13 +61,12 @@ class TaskController extends ApiController */ public function actionGetTask($task_id): Task { - if(empty($task_id) or !is_numeric($task_id)) - { + if (empty($task_id) or !is_numeric($task_id)) { throw new NotFoundHttpException('Incorrect task ID'); } $task = TaskService::getTask($task_id); - if(empty($task)) { + if (empty($task)) { throw new NotFoundHttpException('The task does not exist'); } @@ -87,8 +81,7 @@ class TaskController extends ApiController public function actionUpdate(): ?Task { $params = Yii::$app->request->getBodyParams(); - if (empty ($params['task_id']) or !TaskService::taskExists($params['task_id'])) - { + if (empty ($params['task_id']) or !TaskService::taskExists($params['task_id'])) { throw new NotFoundHttpException('The task does not exist'); } diff --git a/frontend/modules/api/controllers/TaskUserController.php b/frontend/modules/api/controllers/TaskUserController.php index 4cdb3eb..60951a8 100644 --- a/frontend/modules/api/controllers/TaskUserController.php +++ b/frontend/modules/api/controllers/TaskUserController.php @@ -9,19 +9,8 @@ use yii\rest\Controller; use yii\web\BadRequestHttpException; use yii\web\NotFoundHttpException; -class TaskUserController extends Controller +class TaskUserController extends ApiController { - public function behaviors(): array - { - $behaviors = parent::behaviors(); - - $behaviors['authenticator']['authMethods'] = [ - HttpBearerAuth::className(), - ]; - - return $behaviors; - } - public function verbs(): array { return [ diff --git a/frontend/modules/api/controllers/UserCardController.php b/frontend/modules/api/controllers/UserCardController.php deleted file mode 100644 index bdbebdd..0000000 --- a/frontend/modules/api/controllers/UserCardController.php +++ /dev/null @@ -1,24 +0,0 @@ - ['get'], - ]; - } - - /** - * @throws ServerErrorHttpException - */ - public function actionGetUserCard($user_id): array - { - return UserCardService::getUserCard($user_id); - } -} \ No newline at end of file