diff --git a/backend/modules/document/controllers/DocumentController.php b/backend/modules/document/controllers/DocumentController.php index 0133384..a552bc2 100644 --- a/backend/modules/document/controllers/DocumentController.php +++ b/backend/modules/document/controllers/DocumentController.php @@ -2,6 +2,8 @@ namespace backend\modules\document\controllers; +use PhpOffice\PhpWord\Exception\CopyFileException; +use PhpOffice\PhpWord\Exception\CreateTemporaryFileException; use Yii; use backend\modules\document\models\Document; use backend\modules\document\models\DocumentSearch; @@ -10,7 +12,8 @@ use yii\web\Controller; use yii\web\NotFoundHttpException; use yii\filters\VerbFilter; -use common\services\DocumentService; +use common\services\DocumentFileService; +use yii\web\Response; /** * DocumentController implements the CRUD actions for Document model. @@ -142,10 +145,15 @@ class DocumentController extends Controller } - public function actionCreateDocument($id) + /** + * @throws CopyFileException + * @throws NotFoundHttpException + * @throws CreateTemporaryFileException + */ + public function actionCreateDocument($id): Response { if(!empty($this->findModel($id)->template->template_file_name)){ - $documentService = new DocumentService($id); + $documentService = new DocumentFileService($id); $documentService->setFields(); $documentService->downloadDocument(); } diff --git a/backend/modules/questionnaire/models/UserQuestionnaireSearch.php b/backend/modules/questionnaire/models/UserQuestionnaireSearch.php index 5ac1383..7242665 100644 --- a/backend/modules/questionnaire/models/UserQuestionnaireSearch.php +++ b/backend/modules/questionnaire/models/UserQuestionnaireSearch.php @@ -4,7 +4,6 @@ namespace backend\modules\questionnaire\models; use yii\base\Model; use yii\data\ActiveDataProvider; -use backend\modules\questionnaire\models\UserQuestionnaire; /** * UserQuestionnaireSearch represents the model behind the search form of `backend\modules\questionnaire\models\UserQuestionnaire`. @@ -18,7 +17,7 @@ class UserQuestionnaireSearch extends UserQuestionnaire { return [ [['id', 'questionnaire_id', 'user_id', 'score', 'status'], 'integer'], - [['uuid', 'created_at', 'updated_at'], 'safe'], + [['uuid', 'created_at', 'updated_at', 'testing_date'], 'safe'], [['percent_correct_answers'], 'number'], ]; } @@ -67,6 +66,7 @@ class UserQuestionnaireSearch extends UserQuestionnaire 'score' => $this->score, 'status' => $this->status, 'percent_correct_answers' => $this->percent_correct_answers, + 'testing_date' => $this->testing_date, ]); $query->andFilterWhere(['like', 'uuid', $this->uuid]); diff --git a/backend/modules/questionnaire/views/user-questionnaire/_search.php b/backend/modules/questionnaire/views/user-questionnaire/_search.php index f7abd5d..1d84d05 100644 --- a/backend/modules/questionnaire/views/user-questionnaire/_search.php +++ b/backend/modules/questionnaire/views/user-questionnaire/_search.php @@ -33,6 +33,8 @@ use yii\widgets\ActiveForm; field($model, 'percent_correct_answers') ?> + field($model, 'testing_date') ?> +
'btn btn-primary']) ?> 'btn btn-default']) ?> diff --git a/backend/modules/questionnaire/views/user-questionnaire/index.php b/backend/modules/questionnaire/views/user-questionnaire/index.php index e4dcc07..7b64d76 100644 --- a/backend/modules/questionnaire/views/user-questionnaire/index.php +++ b/backend/modules/questionnaire/views/user-questionnaire/index.php @@ -53,6 +53,7 @@ $this->params['breadcrumbs'][] = $this->title; ], 'created_at', 'updated_at', + 'testing_date', ['class' => 'yii\grid\ActionColumn'], ], diff --git a/backend/modules/questionnaire/views/user-questionnaire/view.php b/backend/modules/questionnaire/views/user-questionnaire/view.php index 7b303c9..9ae3e09 100644 --- a/backend/modules/questionnaire/views/user-questionnaire/view.php +++ b/backend/modules/questionnaire/views/user-questionnaire/view.php @@ -77,6 +77,7 @@ YiiAsset::register($this); ], 'created_at', 'updated_at', + 'testing_date', ], ]) ?> diff --git a/common/models/Document.php b/common/models/Document.php index 7cf3874..e95f8f0 100644 --- a/common/models/Document.php +++ b/common/models/Document.php @@ -110,13 +110,4 @@ class Document extends \yii\db\ActiveRecord { return $this->hasMany(DocumentFieldValue::className(), ['document_id' => 'id']); } - - public static function getDocument($document_id) - { - return self::find() - ->joinWith(['documentFieldValues.field']) - ->where(['document.id' => $document_id]) - ->asArray() - ->all(); - } } diff --git a/common/models/Template.php b/common/models/Template.php index e186a73..c114401 100644 --- a/common/models/Template.php +++ b/common/models/Template.php @@ -123,4 +123,10 @@ class Template extends \yii\db\ActiveRecord { return $this->title; } + + public function getFields() + { + return $this->hasMany(DocumentField::className(), ['id' => 'field_id']) + ->via('templateDocumentFields'); + } } diff --git a/common/models/UserQuestionnaire.php b/common/models/UserQuestionnaire.php index 9150bfc..ec875cd 100644 --- a/common/models/UserQuestionnaire.php +++ b/common/models/UserQuestionnaire.php @@ -63,7 +63,7 @@ class UserQuestionnaire extends ActiveRecord [['questionnaire_id', 'user_id', 'status'], 'required'], [['questionnaire_id', 'user_id', 'score', 'status'], 'integer'], [['percent_correct_answers'], 'number'], - [['created_at', 'updated_at'], 'safe'], + [['created_at', 'updated_at', 'testing_date'], 'safe'], [['uuid'], 'string', 'max' => 36], [['uuid'], 'unique'], [['questionnaire_id'], 'exist', 'skipOnError' => true, 'targetClass' => Questionnaire::className(), 'targetAttribute' => ['questionnaire_id' => 'id']], @@ -74,8 +74,7 @@ class UserQuestionnaire extends ActiveRecord public function beforeSave($insert) { if (parent::beforeSave($insert)) { - if (empty($this->uuid)) - { + if (empty($this->uuid)) { $this->uuid = UUIDHelper::v4(); } return true; @@ -98,6 +97,7 @@ class UserQuestionnaire extends ActiveRecord 'status' => 'Статус', 'created_at' => 'Дата создания', 'updated_at' => 'Дата обновления', + 'testing_date' => 'Дата тестирования', 'percent_correct_answers' => 'Процент правильных ответов', ]; } @@ -178,8 +178,18 @@ class UserQuestionnaire extends ActiveRecord public static function findActiveUserQuestionnaires($user_id): array { - return self::find()->where(['user_id' => $user_id]) - ->andWhere(['status' => '1']) + $models = self::find() + ->where(['user_id' => $user_id]) + ->andWhere(['user_questionnaire.status' => '1']) ->all(); + + $modelsArr = array(); + foreach ($models as $model) { + $modelsArr[] = array_merge($model->toArray(), [ + 'questionnaire_title' => $model->getQuestionnaireTitle() + ]); + } + + return $modelsArr; } } diff --git a/common/services/DocumentFileService.php b/common/services/DocumentFileService.php new file mode 100644 index 0000000..d5fa8bc --- /dev/null +++ b/common/services/DocumentFileService.php @@ -0,0 +1,74 @@ +model = Document::findOne($modelID); + + $this->initDocument(); + } + + /** + * @throws CopyFileException + * @throws CreateTemporaryFileException + */ + private function initDocument() + { + $this->file_title = $this->model->title . '.docx'; + + $template_title = $this->model->template->template_file_name; + $this->document = new TemplateProcessor( + Yii::getAlias('@templates') . "/$template_title"); + + $this->documentFieldValuesArr = $this->model->documentFieldValues; + } + + public function setFields() + { + foreach ($this->documentFieldValuesArr as $docFieldValue) { + $this->document->setValue( + $docFieldValue->field->field_template, + $docFieldValue->value + ); + } + } + + public function downloadDocument() + { + $this->document->saveAs($this->file_title); + + // Имя скачиваемого файла + $downloadFile = $this->file_title; + // Контент-тип означающий скачивание + header("Content-Type: application/octet-stream"); + // Размер в байтах + header("Accept-Ranges: bytes"); + // Размер файла + header("Content-Length: ".filesize($downloadFile)); + // Расположение скачиваемого файла + header("Content-Disposition: attachment; filename=".$downloadFile); + +// Прочитать файл + readfile($downloadFile); + unlink($this->file_title); + } +} \ No newline at end of file diff --git a/common/services/DocumentService.php b/common/services/DocumentService.php index 6e1713a..3d3bea2 100644 --- a/common/services/DocumentService.php +++ b/common/services/DocumentService.php @@ -2,73 +2,27 @@ namespace common\services; - use common\models\Document; -use PhpOffice\PhpWord\Exception\CopyFileException; -use PhpOffice\PhpWord\Exception\CreateTemporaryFileException; -use PhpOffice\PhpWord\TemplateProcessor; -use Yii; class DocumentService { - private $model; - private $document; - private $file_title; - private $documentFieldValuesArr; - - /** - * @throws CopyFileException - * @throws CreateTemporaryFileException - */ - public function __construct($modelID) + public static function getDocumentList($document_type): array { - $this->model = Document::findOne($modelID); - - $this->initDocument(); - } - - /** - * @throws CopyFileException - * @throws CreateTemporaryFileException - */ - private function initDocument() - { - $this->file_title = $this->model->title . '.docx'; - - $template_title = $this->model->template->template_file_name; - $this->document = new TemplateProcessor( - Yii::getAlias('@templates') . "/$template_title"); - - $this->documentFieldValuesArr = $this->model->documentFieldValues; - } - - public function setFields() - { - foreach ($this->documentFieldValuesArr as $docFieldValue) { - $this->document->setValue( - $docFieldValue->field->field_template, - $docFieldValue->value - ); + if (!empty($document_type)) { + return Document::find()->joinWith('template') + ->where(['document_type' => $document_type])->asArray()->all(); + } + else { + return Document::find()->asArray()->all(); } } - public function downloadDocument() + public static function getDocument($document_id) { - $this->document->saveAs($this->file_title); + return Document::find() + ->joinWith(['documentFieldValues.field']) + ->where(['document.id' => $document_id]) + ->asArray()->all(); - // Имя скачиваемого файла - $downloadFile = $this->file_title; - // Контент-тип означающий скачивание - header("Content-Type: application/octet-stream"); - // Размер в байтах - header("Accept-Ranges: bytes"); - // Размер файла - header("Content-Length: ".filesize($downloadFile)); - // Расположение скачиваемого файла - header("Content-Disposition: attachment; filename=".$downloadFile); - -// Прочитать файл - readfile($downloadFile); - unlink($this->file_title); } } \ No newline at end of file diff --git a/common/services/ManagerService.php b/common/services/ManagerService.php new file mode 100644 index 0000000..18d4bce --- /dev/null +++ b/common/services/ManagerService.php @@ -0,0 +1,35 @@ +select(['fio','manager.id' , 'email']) + ->joinWith('manager')->where(['NOT',['manager.user_card_id' => null]])->all(); + } + + public static function getManager($manager_id) + { + return UserCard::find() + ->select(['manager.id', 'fio', 'email', 'photo', 'gender']) + ->joinWith([ + 'manager' => function ($query) { $query->select(['id']); } + ]) + ->where(['manager.id' => $manager_id]) + ->asArray() + ->one(); + } + + public static function getManagerEmployeesList($manager_id) + { + return UserCard::find() + ->select(['user_card.id', 'user_card.fio', 'user_card.email']) + ->joinWith('managerEmployee') + ->where(['manager_employee.manager_id' => $manager_id]) + ->all(); + } +} \ No newline at end of file diff --git a/common/services/TaskService.php b/common/services/TaskService.php new file mode 100644 index 0000000..f837a62 --- /dev/null +++ b/common/services/TaskService.php @@ -0,0 +1,46 @@ +load($taskParams, ''); + $task->save(); + return $task; + } + + public static function getTask($task_id): ?Task + { + return Task::findOne($task_id); + } + + public static function getTaskList($task_id): array + { + return Task::find()->asArray()->all(); + } + + public static function getTaskListByProject($project_id): array + { + return Task::find()->where(['project_id' => $project_id])->asArray()->all(); + } + + public static function updateTask($task_params): ?Task + { + $modelTask = Task::findOne($task_params['task_id']); + + $modelTask->load($task_params, ''); + $modelTask->save(); + + return $modelTask; + } + + public static function taskExists($task_id): bool + { + return Task::find()->where(['id' => $task_id])->exists(); + } +} \ No newline at end of file diff --git a/common/services/TemplateService.php b/common/services/TemplateService.php new file mode 100644 index 0000000..d9b928a --- /dev/null +++ b/common/services/TemplateService.php @@ -0,0 +1,38 @@ +where(['document_type' => $document_type])->asArray()->all(); + } + else { + return Template::find()->asArray()->all(); + } + } + + public static function getTemplateWithFields($template_id): array + { + return Template::find() +// ->select('title') + ->joinWith('templateDocumentFields.field') +// ->with([ +// 'fields' => function ($query) { $query->select(['id', 'title', 'field_template']); } +// ]) + ->where(['template.id' => $template_id]) + ->asArray() + ->one(); + } + + public static function getTemplate($template_id): array + { + return Template::find()->where(['template.id' => $template_id]) + ->asArray() + ->one(); + } +} \ No newline at end of file diff --git a/console/migrations/m220214_143240_add_column_testing_date_to_user_questionnaire_table.php b/console/migrations/m220214_143240_add_column_testing_date_to_user_questionnaire_table.php new file mode 100644 index 0000000..7e914bd --- /dev/null +++ b/console/migrations/m220214_143240_add_column_testing_date_to_user_questionnaire_table.php @@ -0,0 +1,40 @@ +addColumn('user_questionnaire', 'testing_date', $this->dateTime()->defaultValue(null)); + } + + /** + * {@inheritdoc} + */ + public function safeDown() + { + $this->dropColumn('user_questionnaire', 'testing_date'); + } + + /* + // Use up()/down() to run migration code without a transaction. + public function up() + { + + } + + public function down() + { + echo "m220214_143240_add_column_testing_date_to_user_questionnaire_table cannot be reverted.\n"; + + return false; + } + */ +} diff --git a/docs/api/document.md b/docs/api/document.md new file mode 100644 index 0000000..ded9b41 --- /dev/null +++ b/docs/api/document.md @@ -0,0 +1,329 @@ +# Документы + +## Методы + + + + + + + + + + + + + + + + + +
+ Метод + + Описание +
+ get-document-list + + Возвращает список документов +
+ get-document + + Возвращает документ +
+ create-document + + Создание документа +
+ +## Список документов + +`https://guild.craft-group.xyz/api/document/get-document-list?document_type=1` +

+ Параметры: +

+ + + + + + + + + +
+ Параметры + + Значение +
+ document_type + + Тип документа. Возможные значения: 1 - Акт; 2 - Договор +
+

+ Без передачи параметра возвращает массив объектов Документ . С параметром document_type, +метод возвращает объекты Документ определённого типа(1 - Акт; 2 - Договор). + При отсутствии документов возвращает ошибку: "Not Found". +

+ +

+ Возвращает массив объектов Документ.
+ Каждый объект Документ имеет такой вид: +

+ +```json5 +[ + { + "id": "88", + "title": "Act2", + "created_at": "2022-01-12 16:39:41", + "updated_at": "2022-01-12 16:39:41", + "template_id": "94", + "manager_id": "5", + "template": { + "id": "94", + "title": "Акт", + "created_at": "2022-01-11 11:47:11", + "updated_at": null, + "template_file_name": null, + "document_type": "2" + } + }, + '...' +] +``` +

+ Пример ошибки: +

+ +```json5 +{ + "name": "Not Found", + "message": "Documents not found", + "code": 0, + "status": 404, + "type": "yii\\web\\NotFoundHttpException" +} +``` + +## Получить документ + +`https://guild.craft-group.xyz/api/document/get-document?document_id=88` +

+ Параметры: +

+ + + + + + + + + +
+ Параметры + + Значение +
+ document_id + + Id документа +
+ +

+ Возвращает объект Документ.
+ Каждый объект Документ имеет такой вид: +

+ +```json5 +[ + { + "id": "88", + "title": "Act2", + "created_at": "2022-01-12 16:39:41", + "updated_at": "2022-01-12 16:39:41", + "template_id": "94", + "manager_id": "5", + "documentFieldValues": [ + { + "id": "105", + "field_id": "43", + "document_id": "88", + "value": "№ документа111", + "field": { + "id": "43", + "title": "№ документа", + "field_template": "№ dokumenta" + } + }, + { + "id": "106", + "field_id": "44", + "document_id": "88", + "value": "от111", + "field": { + "id": "44", + "title": "от", + "field_template": "ot" + } + }, + { + "id": "107", + "field_id": "45", + "document_id": "88", + "value": "Сумма с НДС111", + "field": { + "id": "45", + "title": "Сумма с НДС", + "field_template": "Summa s NDS" + } + }, + { + "id": "108", + "field_id": "46", + "document_id": "88", + "value": "НДС111", + "field": { + "id": "46", + "title": "НДС", + "field_template": "NDS" + } + }, + { + "id": "109", + "field_id": "47", + "document_id": "88", + "value": "Основание111", + "field": { + "id": "47", + "title": "Основание", + "field_template": "Osnovaniye" + } + } + ] + } +] +``` +

+ Пример ошибки: +

+ +```json5 +{ + "name": "Not Found", + "message": "There is no such document", + "code": 0, + "status": 404, + "type": "yii\\web\\NotFoundHttpException" +} +``` + +## Создать документ + +`https://guild.craft-group.xyz/api/document/create-document` +

+ Параметры: +

+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ Параметры + + Значение +
+ title + + Название документа +
+ template_id + + Id шаблона +
+ manager_id + + Id менеджера +
+ field_id + + Id поля +
+ value + + Значение поля +
+ +

+ Создаёт Документ. Требует передачи POST запроса с соответствующими +параметрами документа и полей документа +

+ +

+ Пример передаваемого объекта: +

+ +```json5 +{ + "title": "Act64", + "template_id": "94", + "manager_id": "5", + "documentFieldValues": [ + { + "field_id": "43", + "value": "№ документа111" + }, + { + "field_id": "44", + "value": "от111" + }, + { + "field_id": "45", + "value": "Сумма с НДС111" + }, + { + "field_id": "46", + "value": "НДС111" + }, + { + "field_id": "47", + "value": "Основание111" + } + ] +} +``` +

+ В случае указания не верных параметров буде возвращена соответствующая ошибка. Пример ошибки: +

+ +```json5 +{ + "name": "Bad Request", + "message": "{\"template_id\":[\"\Ш\а\б\л\о\н cannot be blank.\"]}", + "code": 0, + "status": 400, + "type": "yii\\web\\BadRequestHttpException" +} +``` \ No newline at end of file diff --git a/docs/api/main.md b/docs/api/main.md index 40a381d..68314ad 100755 --- a/docs/api/main.md +++ b/docs/api/main.md @@ -27,7 +27,7 @@ - limit + get-document-list Количество профилей, которое вернет сервер при запросе. @@ -256,7 +256,7 @@ Пример запроса:

-`https://guild.craft-group.xyz/api/reports/index?fromDate=2021-08-01&toDate=2021-08-31&user_id=2limit=3&offset=2` +`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}` @@ -291,6 +291,96 @@ `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` diff --git a/docs/api/manager.md b/docs/api/manager.md new file mode 100644 index 0000000..e82588b --- /dev/null +++ b/docs/api/manager.md @@ -0,0 +1,141 @@ +# Менеджеры + +## Методы + + + + + + + + + + + + + + + + + +
+ Метод + + Описание +
+ get-manager-list + + Возвращает список менеджеров +
+ get-manager-employees-list + + Возвращает список сотрудников менеджера +
+ get-manager + + Возвращает менеджера +
+ +## Список менеджеров + +`https://guild.craft-group.xyz/api/manager/get-manager-list` + +

+ Возвращает массив объектов Менеджер.
+ Каждый объект Менеджер имеет такой вид: +

+ +```json5 +[ + { + "fio": "Иванов Иван Иванович", + "id": 5, + "email": "testmail@mail.com" + }, + '...' +] +``` + +## Получить менеджера + +`https://guild.craft-group.xyz/api/manager/get-manager?manager_id=5` +

+ Параметры: +

+ + + + + + + + + +
+ Параметры + + Значение +
+ manager_id + + Id менеджера +
+ +

+ Возвращает объект Менеджер.
+ Каждый объект Менеджер имеет такой вид: +

+ +```json5 +{ + "id": "5", + "fio": "Иванов Иван Иванович", + "email": "testmail@mail.com", + "photo": "", + "gender": "0", + "manager": { + "id": "3" + } +} +``` + +## Получить сотрудников менеджера + +`https://guild.craft-group.xyz/api/manager/get-manager-employees-list?manager_id=5` +

+ Параметры: +

+ + + + + + + + + +
+ Параметры + + Значение +
+ manager_id + + Id менеджера +
+ +

+ Возвращает массив объектов Профиль сотрудников, что закреплены за менеджером.
+ Каждый объект Профиль имеет такой вид: +

+ +```json5 +[ + { + "id": 2, + "fio": "тусыавт2", + "email": "jnjhbdhvf@mail.com" + }, + '...' +] +``` diff --git a/docs/api/task.md b/docs/api/task.md new file mode 100644 index 0000000..a3f39b7 --- /dev/null +++ b/docs/api/task.md @@ -0,0 +1,321 @@ +# Задачи + +## Методы + + + + + + + + + + + + + + + + + + + + + +
+ Метод + + Описание +
+ get-task-list + + Возвращает список задач +
+ get-task + + Возвращает задачу +
+ create-task + + Создаёт задачу +
+ update + + Обновить задачу +
+ +## Список задач + +`https://guild.craft-group.xyz/api/task/get-task-list?project_id=1` +

+ Параметры: +

+ + + + + + + + + +
+ Параметры + + Значение +
+ project_id + + Id проекта +
+

+ Без передачи параметра возвращает массив объектов Задача . С параметром project_id, +метод возвращает объекты Задача определённого проекта. +

+ +

+ Возвращает массив объектов Задача.
+ Каждый объект Задача имеет такой вид: +

+ +```json5 +[ + { + "id": "6", + "project_id": "74", + "title": "Название задачи", + "status": "1", + "created_at": "2021-12-20 16:29:39", + "updated_at": "2021-12-20 17:35:04", + "description": "Описание задачи", + "card_id_creator": "1", + "card_id": "3" + }, + '...' +] +``` + +## Получить документ + +`https://guild.craft-group.xyz/api/task/get-task?task_id=15` +

+ Параметры: +

+ + + + + + + + + +
+ Параметры + + Значение +
+ task_id + + Id задачи +
+ +

+ Возвращает объект Задача.
+ Каждый объект Задача имеет такой вид: +

+ +```json5 +{ + "id": 15, + "project_id": 74, + "title": "4324238888", + "status": 1, + "created_at": "2022-01-05 17:37:37", + "updated_at": "2022-01-05 17:46:10", + "description": "888", + "card_id_creator": 1, + "card_id": null +} +``` +

+ Пример ошибки: +

+ +```json5 +{ + "name": "Not Found", + "message": "The task does not exist", + "code": 0, + "status": 404, + "type": "yii\\web\\NotFoundHttpException" +} +``` + +## Создать документ + +`https://guild.craft-group.xyz/api/document/create-document` +

+ Параметры: +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ Параметры + + Значение +
+ title + + Название задачи +
+ project_id + + Id проекта +
+ status + + статус задачи +
+ card_id_creator + + Id профиля создателя +
+ card_id + + Id профиля наблюдателя(не обязательный параметр) +
+ description + + Описание +
+ +

+ Создаёт Задача. Требует передачи POST запроса с соответствующими +параметрами +

+ +

+ В случае указания не верных параметров буде возвращена соответствующая ошибка. Пример ошибки: +

+ +```json5 +{ + "name": "Internal Server Error", + "message": "{\"project_id\":[\"\П\р\о\е\к\т is invalid.\"]}", + "code": 0, + "status": 500, + "type": "yii\\web\\ServerErrorHttpException" +} +``` + +## Обновить документ + +`https://guild.craft-group.xyz/api/task/update` +

+ Параметры: +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ Параметры + + Значение +
+ title + + Название задачи +
+ project_id + + Id проекта +
+ status + + статус задачи +
+ card_id_creator + + Id профиля создателя +
+ card_id + + Id профиля наблюдателя(не обязательный параметр) +
+ description + + Описание +
+ +

+ Обновляет объект Задача. Требует передачи POST запроса с соответствующими +параметрами +

+ +

+ В случае указания не верных параметров буде возвращена соответствующая ошибка. Пример ошибки: +

+ +```json5 +{ + "name": "Not Found", + "message": "The task does not exist", + "code": 0, + "status": 404, + "type": "yii\\web\\NotFoundHttpException" +} +``` \ No newline at end of file diff --git a/docs/api/template.md b/docs/api/template.md new file mode 100644 index 0000000..5da0198 --- /dev/null +++ b/docs/api/template.md @@ -0,0 +1,219 @@ +# Шаблоны + +## Методы + + + + + + + + + + + + + + + + + +
+ Метод + + Описание +
+ get-template-list + + Возвращает список шаблонов +
+ get-template-fields + + Возвращает поля шаблона +
+ get-template + + Возвращает шаблон +
+ +## Список шаблонов + +`https://guild.craft-group.xyz/api/template/get-template-list?document_type=1` +

+ Параметры: +

+ + + + + + + + + +
+ Параметры + + Значение +
+ document_type + + Тип документа. Возможные значения: 1 - Акт; 2 - Договор +
+

+ Без передачи параметра возвращает массив объектов Шаблон . С параметром document_type, +метод возвращает объекты Шаблон определённого типа(1 - Акт; 2 - Договор). +

+ +

+ Возвращает массив объектов Шаблон.
+ Каждый объект Шаблон имеет такой вид: +

+ +```json5 +[ + { + "id": "94", + "title": "Акт", + "created_at": "2022-01-11 11:47:11", + "updated_at": null, + "template_file_name": null, + "document_type": "2" + }, + '...' +] +``` + +## Получить шаблон + +`https://guild.craft-group.xyz/api/template/get-template?template_id=94` +

+ Параметры: +

+ + + + + + + + + +
+ Параметры + + Значение +
+ template_id + + Id шаблона +
+ +

+ Возвращает объект Шаблон.
+ Каждый объект Шаблон имеет такой вид: +

+ +```json5 +{ + "id": "94", + "title": "Акт", + "created_at": "2022-01-11 11:47:11", + "updated_at": null, + "template_file_name": null, + "document_type": "2" +} +``` + +## Получить поля шаблона + +`https://guild.craft-group.xyz/api/template/get-template-fields?template_id=94` +

+ Параметры: +

+ + + + + + + + + +
+ Параметры + + Значение +
+ template_id + + Id шаблона +
+ +

+ Возвращает объект Шаблон.
+ Каждый объект Шаблон имеет такой вид: +

+ +```json5 +{ + "id": "94", + "title": "Акт", + "created_at": "2022-01-11 11:47:11", + "updated_at": null, + "template_file_name": null, + "document_type": "2", + "templateDocumentFields": [ + { + "id": "159", + "template_id": "94", + "field_id": "43", + "field": { + "id": "43", + "title": "№ документа", + "field_template": "№ dokumenta" + } + }, + { + "id": "160", + "template_id": "94", + "field_id": "44", + "field": { + "id": "44", + "title": "от", + "field_template": "ot" + } + }, + { + "id": "161", + "template_id": "94", + "field_id": "45", + "field": { + "id": "45", + "title": "Сумма с НДС", + "field_template": "Summa s NDS" + } + }, + { + "id": "162", + "template_id": "94", + "field_id": "46", + "field": { + "id": "46", + "title": "НДС", + "field_template": "NDS" + } + }, + { + "id": "163", + "template_id": "94", + "field_id": "47", + "field": { + "id": "47", + "title": "Основание", + "field_template": "Osnovaniye" + } + } + ] +} +``` diff --git a/frontend/modules/api/controllers/DocumentController.php b/frontend/modules/api/controllers/DocumentController.php index 49e11bd..f556b4e 100644 --- a/frontend/modules/api/controllers/DocumentController.php +++ b/frontend/modules/api/controllers/DocumentController.php @@ -4,14 +4,10 @@ namespace frontend\modules\api\controllers; use common\models\Document; use common\models\DocumentFieldValue; -use common\models\Template; -use common\models\TemplateDocumentField; -use Exception; +use common\services\DocumentService; use Yii; -use yii\filters\auth\HttpBearerAuth; use yii\web\BadRequestHttpException; use yii\web\NotFoundHttpException; -use yii\rest\Controller; use yii\web\ServerErrorHttpException; class DocumentController extends ApiController @@ -20,33 +16,37 @@ class DocumentController extends ApiController public function verbs(): array { return [ -// 'get-task' => ['get'], 'get-document-list' => ['get'], + 'get-document' => ['get'], 'create-document' => ['post'], -// 'update-task' => ['put', 'patch'], ]; } - public function actionGetDocumentList(): array + /** + * @throws NotFoundHttpException + */ + public function actionGetDocumentList($document_type = null): array { - $documents = Document::find()->select(['id','title', 'manager_id'])->all(); + $documents = DocumentService::getDocumentList($document_type); if(empty($documents)) { - throw new NotFoundHttpException('Documents are not assigned'); + throw new NotFoundHttpException('Documents not found'); } return $documents; } - public function actionGetDocument(): array + /** + * @throws NotFoundHttpException + */ + public function actionGetDocument($document_id): array { - $document_id = Yii::$app->request->get('document_id'); if(empty($document_id) or !is_numeric($document_id)) { throw new NotFoundHttpException('Incorrect document ID'); } - $document = Document::getDocument($document_id); + $document = DocumentService::getDocument($document_id); if(empty($document)) { throw new NotFoundHttpException('There is no such document'); @@ -58,10 +58,7 @@ class DocumentController extends ApiController public function actionCreateDocument() { $document = Yii::$app->getRequest()->getBodyParams(); - $documentFieldValues = Yii::$app->getRequest()->getBodyParams()['documentFieldValues']; - - $tmp = TemplateDocumentField::find()->select('field_id') - ->where(['template_id' => 94])->asArray()->all(); + $documentFieldValues = $document['documentFieldValues']; $modelDocument = new Document(); if ($modelDocument->load($document, '') && $modelDocument->save()) { @@ -79,7 +76,7 @@ class DocumentController extends ApiController } Yii::$app->getResponse()->setStatusCode(201); - return Document::getDocument($modelDocument->id); + return DocumentService::getDocument($modelDocument->id); } private function createDocimentFields($documentFieldValues , $document_id, $template_id) diff --git a/frontend/modules/api/controllers/ManagerController.php b/frontend/modules/api/controllers/ManagerController.php index cba667a..6d75aff 100644 --- a/frontend/modules/api/controllers/ManagerController.php +++ b/frontend/modules/api/controllers/ManagerController.php @@ -2,28 +2,12 @@ namespace frontend\modules\api\controllers; -use common\models\ManagerEmployee; -use common\models\User; -use common\models\UserCard; -use Yii; -use yii\filters\auth\HttpBearerAuth; -use yii\helpers\ArrayHelper; + +use common\services\ManagerService; use yii\web\NotFoundHttpException; -use yii\rest\Controller; -class ManagerController extends Controller +class ManagerController extends ApiController { - public function behaviors(): array - { - $behaviors = parent::behaviors(); - - $behaviors['authenticator']['authMethods'] = [ - HttpBearerAuth::className(), - ]; - - return $behaviors; - } - public function verbs(): array { return [ @@ -33,10 +17,12 @@ class ManagerController extends Controller ]; } + /** + * @throws NotFoundHttpException + */ public function actionGetManagerList(): array { - $managers = UserCard::find()->select(['fio','manager.id' , 'email']) - ->joinWith('manager')->where(['NOT',['manager.user_card_id' => null]])->all(); + $managers = ManagerService::getManagerList(); if(empty($managers)) { throw new NotFoundHttpException('Managers are not assigned'); @@ -48,43 +34,33 @@ class ManagerController extends Controller /** * @throws NotFoundHttpException */ - public function actionGetEmployeesManager() + public function actionGetManagerEmployeesList($manager_id): array { - $manager_id = Yii::$app->request->get('manager_id'); if(empty($manager_id) or !is_numeric($manager_id)) { throw new NotFoundHttpException('Incorrect manager ID'); } - $users_list = UserCard::find() - ->select(['manager_employee.id', 'user_card.fio', 'user_card.email']) - ->joinWith('managerEmployee') - ->where(['manager_employee.manager_id' => $manager_id]) - ->all(); + $managerEmployeesList = ManagerService::getManagerEmployeesList($manager_id); - if(empty($users_list)) { + if(empty($managerEmployeesList)) { throw new NotFoundHttpException('Managers are not assigned or employees are not assigned to him'); } - return $users_list; + return $managerEmployeesList; } /** * @throws NotFoundHttpException */ - public function actionGetManager(): array + public function actionGetManager($manager_id): array { - $manager_id = Yii::$app->request->get('manager_id'); if(empty($manager_id) or !is_numeric($manager_id)) { throw new NotFoundHttpException('Incorrect manager ID'); } - $manager = UserCard::find() - ->select(['manager.id', 'fio', 'email', 'photo', 'gender']) - ->joinWith('manager')->where(['manager.id' => $manager_id]) - ->all(); - + $manager = ManagerService::getManager($manager_id); if(empty($manager)) { throw new NotFoundHttpException('There is no such manager'); diff --git a/frontend/modules/api/controllers/ReportsController.php b/frontend/modules/api/controllers/ReportsController.php index 46dbc3d..ded88ef 100755 --- a/frontend/modules/api/controllers/ReportsController.php +++ b/frontend/modules/api/controllers/ReportsController.php @@ -69,6 +69,27 @@ class ReportsController extends ApiController return array_merge($report->toArray(), ['tasks' => $report->_task]); } + /** + * @throws NotFoundHttpException + */ + public function actionFindByDate(): array + { + $reportsModel = new ReportSearchForm(); + + $params = Yii::$app->request->get(); + if(!isset($params['user_card_id']) or !isset($params['date'])){ + throw new NotFoundHttpException('Required parameter are missing!'); + } + + $reportsModel->attributes = $params; + $reportsModel->byDate = true; + + if(!$reportsModel->validate()){ + return $reportsModel->errors; + } + return $reportsModel->byParams(); + } + public function actionCreate() { $params = Yii::$app->request->post(); diff --git a/frontend/modules/api/controllers/TaskController.php b/frontend/modules/api/controllers/TaskController.php index 4769685..62749ce 100644 --- a/frontend/modules/api/controllers/TaskController.php +++ b/frontend/modules/api/controllers/TaskController.php @@ -3,27 +3,14 @@ namespace frontend\modules\api\controllers; use common\models\Task; +use common\services\TaskService; use Yii; use yii\base\InvalidConfigException; -use yii\filters\auth\HttpBearerAuth; -use yii\rest\Controller; -use yii\web\BadRequestHttpException; use yii\web\NotFoundHttpException; use yii\web\ServerErrorHttpException; -class TaskController extends Controller +class TaskController extends ApiController { - public function behaviors(): array - { - $behaviors = parent::behaviors(); - - $behaviors['authenticator']['authMethods'] = [ - HttpBearerAuth::className(), - ]; - - return $behaviors; - } - public function verbs(): array { return [ @@ -37,113 +24,79 @@ class TaskController extends Controller /** * @throws InvalidConfigException * @throws ServerErrorHttpException - * @throws NotFoundHttpException - */ - public function actionUpdate(): ?Task - { - $model = $this->findModelTask(Yii::$app->request->post('task_id')); - if(empty($model)) { - throw new NotFoundHttpException('The task does not exist'); - } - - $model->load(Yii::$app->request->getBodyParams(), ''); - if ($model->save() === false && !$model->hasErrors()) { - throw new ServerErrorHttpException('Failed to update the object for unknown reason.'); - } - - return $model; - } - - - - /** - * @throws InvalidConfigException - * @throws BadRequestHttpException - * @throws ServerErrorHttpException */ public function actionCreateTask(): Task { - $task = Yii::$app->getRequest()->getBodyParams(); + $taskModel = TaskService::createTask(Yii::$app->getRequest()->getBodyParams()); + if ($taskModel->errors) { + throw new ServerErrorHttpException(json_encode($taskModel->errors)); + } - $model = new Task(); - $model->load($task, ''); - - $this->validateTaskModel($model); - $this->saveModel($model); - - return $model; + return $taskModel; } + /** - * @throws ServerErrorHttpException + * @throws NotFoundHttpException */ - protected function saveModel($model) + public function actionGetTaskList($project_id = null): array { - if ($model->save()) { - $task = Yii::$app->getResponse(); - $task->setStatusCode(201); - } elseif (!$model->hasErrors()) { - throw new ServerErrorHttpException('Failed to create the object for unknown reason.'); - } - } - - /** - * @throws BadRequestHttpException - */ - protected function validateTaskModel($model) - { - if(!$model->validate()) { - throw new BadRequestHttpException(json_encode($model->errors)); - } - - if (empty($model->project_id)or empty($model->status) - or empty($model->description) or empty($model->title) or empty($model->card_id_creator)) { - throw new BadRequestHttpException(json_encode($model->errors)); - } - } - - public function actionGetTaskList(): array - { - $project_id = Yii::$app->request->get('project_id'); - if(empty($project_id) or !is_numeric($project_id)) + $tasks = array(); + if ($project_id) { - throw new NotFoundHttpException('Incorrect project ID'); + if(empty($project_id) or !is_numeric($project_id)) + { + throw new NotFoundHttpException('Incorrect project ID'); + } + $tasks = TaskService::getTaskListByProject($project_id); + } + else + { + $tasks = TaskService::getTaskList($project_id); } - - $tasks = $this->findModelsById($project_id); if(empty($tasks)) { throw new NotFoundHttpException('The project does not exist or there are no tasks for it'); } - return $tasks; } - public function actionGetTask(): Task + /** + * @throws NotFoundHttpException + */ + public function actionGetTask($task_id): Task { - $task_id = Yii::$app->request->get('task_id'); if(empty($task_id) or !is_numeric($task_id)) { throw new NotFoundHttpException('Incorrect task ID'); } - $task = $this->findModelTask($task_id); - + $task = TaskService::getTask($task_id); if(empty($task)) { throw new NotFoundHttpException('The task does not exist'); } return $task; - } - private function findModelTask($task_id): ?Task + /** + * @throws InvalidConfigException + * @throws ServerErrorHttpException + * @throws NotFoundHttpException + */ + public function actionUpdate(): ?Task { - return Task::findOne($task_id); - } + $params = Yii::$app->request->getBodyParams(); + if (empty ($params['task_id']) or !TaskService::taskExists($params['task_id'])) + { + throw new NotFoundHttpException('The task does not exist'); + } - private function findModelsById($project_id): array - { - return Task::find()->where(['project_id' => $project_id])->all(); + $modelTask = TaskService::updateTask($params); + if (!empty($modelTask->hasErrors())) { + throw new ServerErrorHttpException(json_encode('Bad params')); + } + + return $modelTask; } } \ No newline at end of file diff --git a/frontend/modules/api/controllers/TemplateController.php b/frontend/modules/api/controllers/TemplateController.php index 5524f67..1eb3e1d 100644 --- a/frontend/modules/api/controllers/TemplateController.php +++ b/frontend/modules/api/controllers/TemplateController.php @@ -2,14 +2,8 @@ namespace frontend\modules\api\controllers; -use common\models\Document; -use common\models\Template; -use Yii; -use yii\filters\auth\CompositeAuth; -use yii\filters\auth\HttpBearerAuth; -use yii\filters\ContentNegotiator; +use common\services\TemplateService; use yii\web\NotFoundHttpException; -use yii\web\Response; class TemplateController extends ApiController { @@ -19,44 +13,57 @@ class TemplateController extends ApiController return [ 'get-template-list' => ['get'], 'get-template-fields' => ['get'], + 'get-template' => ['get'], ]; } - public function actionGetTemplateList(): array + /** + * @throws NotFoundHttpException + */ + public function actionGetTemplateList($document_type = null): array { - $document_type = Yii::$app->request->get('document_type'); + $templateList = TemplateService::getTemplateList($document_type); - if (!empty($document_type)) { - $template = Template::find()->where(['document_type' => $document_type])->asArray()->all(); - } - else { - $template = Template::find()->asArray()->all(); + if (empty($templateList)) { + throw new NotFoundHttpException('No templates found'); } - if (empty($template)) { - throw new NotFoundHttpException('Documents are not assigned'); - } - - return $template; + return $templateList; } - public function actionGetTemplateFields(): array + /** + * @throws NotFoundHttpException + */ + public function actionGetTemplateFields($template_id): array { - $template_id = Yii::$app->request->get('template_id'); if (empty($template_id) or !is_numeric($template_id)) { throw new NotFoundHttpException('Incorrect template ID'); } - $templates = Template::find() - ->joinWith('templateDocumentFields.field') - ->where(['template.id' => $template_id]) - ->asArray() - ->all(); + $templateWithFields = TemplateService::getTemplateWithFields($template_id); - if (empty($templates)) { - throw new NotFoundHttpException('Documents are not assigned'); + if (empty($templateWithFields)) { + throw new NotFoundHttpException('No template found'); } - return $templates; + return $templateWithFields; + } + + /** + * @throws NotFoundHttpException + */ + public function actionGetTemplate($template_id): array + { + if (empty($template_id) or !is_numeric($template_id)) { + throw new NotFoundHttpException('Incorrect template ID'); + } + + $template = TemplateService::getTemplate($template_id); + + if (empty($template)) { + throw new NotFoundHttpException('No template found'); + } + + return $template; } } diff --git a/frontend/modules/api/controllers/UserQuestionnaireController.php b/frontend/modules/api/controllers/UserQuestionnaireController.php index 3f54047..7d665c5 100644 --- a/frontend/modules/api/controllers/UserQuestionnaireController.php +++ b/frontend/modules/api/controllers/UserQuestionnaireController.php @@ -31,7 +31,7 @@ class UserQuestionnaireController extends ApiController /** * @throws NotFoundHttpException */ - public function actionQuestionnairesList(): array + public function actionQuestionnairesList()//: array { $user_id = Yii::$app->request->get('user_id'); @@ -40,20 +40,20 @@ class UserQuestionnaireController extends ApiController throw new NotFoundHttpException('Incorrect user ID'); } - $userQuestionnaireModel = UserQuestionnaire::findActiveUserQuestionnaires($user_id); - if(empty($userQuestionnaireModel)) { + $userQuestionnaireModels = UserQuestionnaire::findActiveUserQuestionnaires($user_id); + if(empty($userQuestionnaireModels)) { throw new NotFoundHttpException('Active questionnaire not found'); } - array_walk( $userQuestionnaireModel, function(&$arr){ + array_walk( $userQuestionnaireModels, function(&$arr){ unset( $arr['questionnaire_id'], - $arr['created_at'], - $arr['updated_at'], +// $arr['created_at'], +// $arr['updated_at'], $arr['id'], ); }); - return $userQuestionnaireModel; + return $userQuestionnaireModels; } } diff --git a/frontend/modules/api/models/ReportSearchForm.php b/frontend/modules/api/models/ReportSearchForm.php index d1104d1..4d0a783 100755 --- a/frontend/modules/api/models/ReportSearchForm.php +++ b/frontend/modules/api/models/ReportSearchForm.php @@ -18,6 +18,7 @@ class ReportSearchForm extends Model * @var false */ public $byDate; + public $date; public function __construct($config = []) { @@ -27,6 +28,7 @@ class ReportSearchForm extends Model $this->toDate = date('Y-m-d', time()); $this->fromDate = date('Y-m-01', time()); + $this->date = date('Y-m-d'); $this->byDate = false; parent::__construct($config); @@ -36,7 +38,7 @@ class ReportSearchForm extends Model { return [ [['byDate'], 'safe'], - [['fromDate', 'toDate'], 'date', 'format' => 'php:Y-m-d'], + [['fromDate', 'toDate', 'date'], 'date', 'format' => 'php:Y-m-d'], [['limit', 'offset', 'user_id'], 'integer', 'min' => 0], ]; } @@ -47,7 +49,7 @@ class ReportSearchForm extends Model ->with('task'); if ($this->byDate) { - $queryBuilder->andWhere(['reports.created_at' => $this->byDate]); + $queryBuilder->andWhere(['reports.created_at' => $this->date]); } else { $queryBuilder->andWhere(['between', 'reports.created_at', $this->fromDate, $this->toDate]); }