diff --git a/backend/modules/document/controllers/DocumentController.php b/backend/modules/document/controllers/DocumentController.php index c0934bb..a7e9183 100644 --- a/backend/modules/document/controllers/DocumentController.php +++ b/backend/modules/document/controllers/DocumentController.php @@ -4,9 +4,11 @@ namespace backend\modules\document\controllers; use backend\modules\company\models\CompanyManager; use backend\modules\document\models\Document; +use backend\modules\document\models\DocumentFieldValue; use backend\modules\document\models\DocumentSearch; use common\services\DocumentService; use Yii; +use yii\data\ActiveDataProvider; use yii\filters\VerbFilter; use yii\web\Controller; use yii\web\NotFoundHttpException; @@ -55,8 +57,17 @@ class DocumentController extends Controller */ public function actionView($id) { + $model = $this->findModel($id); + $documentFieldValuesDataProvider = new ActiveDataProvider([ + 'query' => $model->getDocumentFieldValues(), + 'pagination' => [ + 'pageSize' => 20, + ], + ]); + return $this->render('view', [ - 'model' => $this->findModel($id), + 'model' => $model, + 'documentFieldValuesDataProvider' => $documentFieldValuesDataProvider ]); } @@ -68,11 +79,24 @@ class DocumentController extends Controller public function actionCreate() { $model = new Document(); + $model->scenario = Document::SCENARIO_PARTICIPANTS_OF_THE_TRANSACTION; - if ($model->load(Yii::$app->request->post()) && $model->validate()) { + if ($model->load(Yii::$app->request->post())) { DocumentService::generateDocumentBody($model); - $model->save(false); - return $this->redirect(['view', 'id' => $model->id]); + + if ($model->validate()) { + $model->save(false); + + if (!$model->getBlankFields()) { + return $this->redirect(['view', 'id' => $model->id]); + } + + return $this->redirect([ + 'document-field-value/create-multiple', + 'document_id' => $model->id, + 'fieldNames' => $model->getBlankFields(), + ]); + } } return $this->render('create', [ @@ -90,9 +114,24 @@ class DocumentController extends Controller public function actionUpdate($id) { $model = $this->findModel($id); + $model->scenario = Document::SCENARIO_PARTICIPANTS_OF_THE_TRANSACTION; - if ($model->load(Yii::$app->request->post()) && $model->save()) { - return $this->redirect(['view', 'id' => $model->id]); + if ($model->load(Yii::$app->request->post())) { + if ($model->isAttributeChanged('template_id', false)) { + DocumentService::generateDocumentBody($model); + } + + if ($model->save()) { + if (!$model->getBlankFields()) { + return $this->redirect(['view', 'id' => $model->id]); + } + + return $this->redirect([ + 'document-field-value/create-multiple', + 'document_id' => $model->id, + 'fieldNames' => $model->getBlankFields(), + ]); + } } return $this->render('update', [ @@ -130,54 +169,20 @@ class DocumentController extends Controller throw new NotFoundHttpException('The requested page does not exist.'); } - public function actionDownload($id): string - { - return $this->render('download', [ - 'model' => Document::findOne($id) - ]); - } - - /** - * @param integer $id - * @throws NotFoundHttpException - */ - public function actionUpdateDocumentBody($id): string - { - $model = $this->findModel($id); - $model->scenario = $model::SCENARIO_UPDATE_DOCUMENT_BODY; - - if ($model->load(Yii::$app->request->post()) && $model->validate()) { - $model->updated_at = date('Y-m-d h:i:s'); - $model->save(); - } - - return $this->render('download', [ - 'model' => $model - ]); - } - - public function actionDownloadPdf($id): string + public function actionDownload($id, $fileType = null): string { $model = $this->findModel($id); $model->scenario = $model::SCENARIO_DOWNLOAD_DOCUMENT; - if ($model->validate()) { - DocumentService::downloadPdf($id); - } - - Yii::$app->session->setFlash('error', $model->getFirstError('body')); - return $this->render('download', [ - 'model' => Document::findOne($id) - ]); - } - - public function actionDownloadDocx($id): string - { - $model = $this->findModel($id); - $model->scenario = $model::SCENARIO_DOWNLOAD_DOCUMENT; - - if ($model->validate()) { - DocumentService::downloadDocx($id); + if ($fileType && $model->validate()) { + switch ($fileType) { + case 'pdf': + DocumentService::downloadPdf($id); + break; + case 'docx': + DocumentService::downloadDocx($id); + break; + } } Yii::$app->session->setFlash('error', $model->getFirstError('body')); @@ -207,4 +212,36 @@ class DocumentController extends Controller } return ['output'=>'', 'selected'=>'']; } + + public function actionWriteFields($id) + { + $model = $this->findModel($id); + + /** @var DocumentFieldValue[] $documentFieldsValue */ + $documentFieldsValue = $model->getDocumentFieldValues()->all(); + + foreach ($documentFieldsValue as $fieldValue) { + $model->body = str_replace($fieldValue->documentField->field_template, $fieldValue->value, $model->body); + } + + $model->save(false); + + return $this->redirect([ + 'document/view', + 'id' => $id, + ]); + } + + public function actionUpdateBody($documentId, $oldValue, $newValue) + { + $model = $this->findModel($documentId); + + $model->body = str_replace($oldValue, $newValue, $model->body); + $model->save(false); + + return $this->redirect([ + 'document/view', + 'id' => $documentId, + ]); + } } diff --git a/backend/modules/document/controllers/DocumentFieldValueController.php b/backend/modules/document/controllers/DocumentFieldValueController.php new file mode 100644 index 0000000..0f02980 --- /dev/null +++ b/backend/modules/document/controllers/DocumentFieldValueController.php @@ -0,0 +1,203 @@ + [ + 'class' => VerbFilter::className(), + 'actions' => [ + 'delete' => ['POST'], + ], + ], + ]; + } + + /** + * Lists all DocumentFieldValue models. + * @return mixed + */ + public function actionIndex() + { + $searchModel = new DocumentFieldValueSearch(); + $dataProvider = $searchModel->search(Yii::$app->request->queryParams); + + return $this->render('index', [ + 'searchModel' => $searchModel, + 'dataProvider' => $dataProvider, + ]); + } + + /** + * Displays a single DocumentFieldValue model. + * @param integer $id + * @return mixed + * @throws NotFoundHttpException if the model cannot be found + */ + public function actionView($id) + { + return $this->render('view', [ + 'model' => $this->findModel($id), + ]); + } + + /** + * Creates a new DocumentFieldValue model. + * If creation is successful, the browser will be redirected to the 'view' page. + * @return mixed + */ + public function actionCreate() + { + $model = new DocumentFieldValue(); + + if ($model->load(Yii::$app->request->post()) && $model->save()) { + return $this->redirect(['view', 'id' => $model->id]); + } + + return $this->render('create', [ + 'model' => $model, + ]); + } + + /** + * Creates a new DocumentFieldValue model. + * If creation is successful, the browser will be redirected to the 'view' page. + * @return mixed + */ + public function actionCreateMultiple() + { + $document_id = Yii::$app->request->get('document_id'); + $fieldNames = Yii::$app->request->get('fieldNames'); + + // fields ID that should be saved in the document + $documentFieldsIdList = ArrayHelper::getColumn( + DocumentField::find() + ->where(['in', 'field_template', $fieldNames]) + ->all(), + 'id'); + //already saved fields ID + $fieldsValuesIdList = ArrayHelper::getColumn( + DocumentFieldValue::find()->where(['document_id' => $document_id]) ->all(), 'document_field_id' + ); + $fieldsIdList = array_diff($documentFieldsIdList, $fieldsValuesIdList); + + $fieldsWithError = []; + $documentFieldValues = []; + if (empty($fieldsIdList)) { + return $this->redirect([ + 'document/view', + 'id' => $document_id, + ]); + } + else { + foreach ($fieldsIdList as $id){ + $docFieldValue = new DocumentFieldValue(); + $docFieldValue->document_id = $document_id; + $docFieldValue->document_field_id = $id; + + $documentFieldValues[] = $docFieldValue; + } + + if (Model::loadMultiple($documentFieldValues, Yii::$app->request->post())) { + foreach ($documentFieldValues as $documentFieldValue) { + if (!$documentFieldValue->save()) { + $fieldsWithError[] = $documentFieldValue; + } + } + + if (!$fieldsWithError) { + return $this->redirect([ + 'document/write-fields', + 'id' => $document_id, + ]); + } + $documentFieldValues = $fieldsWithError; + } + } + + return $this->render('_form_multiple', [ + 'documentFieldValues' => $documentFieldValues, + ]); + } + + + /** + * Updates an existing DocumentFieldValue model. + * If update is successful, the browser will be redirected to the 'view' page. + * @param integer $id + * @return mixed + * @throws NotFoundHttpException if the model cannot be found + */ + public function actionUpdate($id, $fromDocument = null) + { + $model = $this->findModel($id); + $oldValue = $model->value; + + if ($model->load(Yii::$app->request->post()) && $model->save()) { + if ($fromDocument) { + return $this->redirect([ + 'document/update-body', + 'documentId' => $model->document_id, + 'oldValue' => $oldValue, + 'newValue' => $model->value + ]); + } + + return $this->redirect(['view', 'id' => $model->id]); + } + + return $this->render('update', [ + 'model' => $model, + 'fromDocument' =>$fromDocument, + ]); + } + + /** + * Deletes an existing DocumentFieldValue model. + * If deletion is successful, the browser will be redirected to the 'index' page. + * @param integer $id + * @return mixed + * @throws NotFoundHttpException if the model cannot be found + */ + public function actionDelete($id) + { + $this->findModel($id)->delete(); + + return $this->redirect(['index']); + } + + /** + * Finds the DocumentFieldValue model based on its primary key value. + * If the model is not found, a 404 HTTP exception will be thrown. + * @param integer $id + * @return DocumentFieldValue the loaded model + * @throws NotFoundHttpException if the model cannot be found + */ + protected function findModel($id) + { + if (($model = DocumentFieldValue::findOne($id)) !== null) { + return $model; + } + + throw new NotFoundHttpException('The requested page does not exist.'); + } +} diff --git a/backend/modules/document/models/DocumentFieldValue.php b/backend/modules/document/models/DocumentFieldValue.php new file mode 100644 index 0000000..6f2ff55 --- /dev/null +++ b/backend/modules/document/models/DocumentFieldValue.php @@ -0,0 +1,8 @@ + $query, + ]); + + $this->load($params); + + if (!$this->validate()) { + // uncomment the following line if you do not want to return any records when validation fails + // $query->where('0=1'); + return $dataProvider; + } + + // grid filtering conditions + $query->andFilterWhere([ + 'id' => $this->id, + 'document_field_id' => $this->document_field_id, + 'document_id' => $this->document_id, + ]); + + $query->andFilterWhere(['like', 'value', $this->value]); + + return $dataProvider; + } +} diff --git a/backend/modules/document/views/document-field-value/_form.php b/backend/modules/document/views/document-field-value/_form.php new file mode 100644 index 0000000..640f5af --- /dev/null +++ b/backend/modules/document/views/document-field-value/_form.php @@ -0,0 +1,40 @@ + + +
+ + + + field($model, 'document_field_id')->dropDownList( + ArrayHelper::map(DocumentField::find()->all(), 'id', 'title'), + ['prompt' => '...'] + ); + echo $form->field($model, 'document_id')->dropDownList( + ArrayHelper::map(Document::find()->all(), 'id', 'title'), + ['prompt' => '...'] + ); + } + ?> + + field($model, 'value')->textInput(['maxlength' => true]) ?> + +
+ 'btn btn-success']) ?> +
+ + + +
diff --git a/backend/modules/document/views/document-field-value/_form_multiple.php b/backend/modules/document/views/document-field-value/_form_multiple.php new file mode 100644 index 0000000..e282b2b --- /dev/null +++ b/backend/modules/document/views/document-field-value/_form_multiple.php @@ -0,0 +1,36 @@ +title = 'Заполнение полей документа: ' . $model->document->title; +$this->params['breadcrumbs'][] = ['label' => 'Значения полей документа', 'url' => ['index']]; +$this->params['breadcrumbs'][] = $model->document->title; +?> + +
+ + + + $documentFieldValue) { ?> + + field($documentFieldValue, "[$index]value") + ->textInput(['maxlength' => true]) + ->label(ArrayHelper::getValue($documentFieldValue,'documentField.title') + ) ?> + + + +
+ 'btn btn-success']) ?> +
+ + + +
\ No newline at end of file diff --git a/backend/modules/document/views/document-field-value/_search.php b/backend/modules/document/views/document-field-value/_search.php new file mode 100644 index 0000000..4832457 --- /dev/null +++ b/backend/modules/document/views/document-field-value/_search.php @@ -0,0 +1,33 @@ + + + diff --git a/backend/modules/document/views/document-field-value/create.php b/backend/modules/document/views/document-field-value/create.php new file mode 100644 index 0000000..aae165c --- /dev/null +++ b/backend/modules/document/views/document-field-value/create.php @@ -0,0 +1,20 @@ +title = 'Create Document Field Value'; +$this->params['breadcrumbs'][] = ['label' => 'Document Field Values', 'url' => ['index']]; +$this->params['breadcrumbs'][] = $this->title; +?> +
+ +

title) ?>

+ + render('_form', [ + 'model' => $model, + ]) ?> + +
diff --git a/backend/modules/document/views/document-field-value/index.php b/backend/modules/document/views/document-field-value/index.php new file mode 100644 index 0000000..ff90a35 --- /dev/null +++ b/backend/modules/document/views/document-field-value/index.php @@ -0,0 +1,36 @@ +title = 'Document Field Values'; +$this->params['breadcrumbs'][] = $this->title; +?> +
+ +

title) ?>

+ render('_search', ['model' => $searchModel]); ?> + +

+ 'btn btn-success']) ?> +

+ + $dataProvider, + 'filterModel' => $searchModel, + 'columns' => [ + ['class' => 'yii\grid\SerialColumn'], + + 'id', + 'document_field_id', + 'document_id', + 'value', + + ['class' => 'yii\grid\ActionColumn'], + ], + ]); ?> +
diff --git a/backend/modules/document/views/document-field-value/update.php b/backend/modules/document/views/document-field-value/update.php new file mode 100644 index 0000000..754b4fb --- /dev/null +++ b/backend/modules/document/views/document-field-value/update.php @@ -0,0 +1,21 @@ +title = 'Изменить значение поля документа: ' . $model->id; +$this->params['breadcrumbs'][] = ['label' => 'Document Field Values', 'url' => ['index']]; +$this->params['breadcrumbs'][] = ['label' => $model->id, 'url' => ['view', 'id' => $model->id]]; +$this->params['breadcrumbs'][] = 'Update'; +?> +
+ + render('_form', [ + 'model' => $model, + 'fromDocument' => $fromDocument + ]) ?> + +
diff --git a/backend/modules/document/views/document-field-value/view.php b/backend/modules/document/views/document-field-value/view.php new file mode 100644 index 0000000..07d10d2 --- /dev/null +++ b/backend/modules/document/views/document-field-value/view.php @@ -0,0 +1,39 @@ +title = $model->id; +$this->params['breadcrumbs'][] = ['label' => 'Document Field Values', 'url' => ['index']]; +$this->params['breadcrumbs'][] = $this->title; +\yii\web\YiiAsset::register($this); +?> +
+ +

title) ?>

+ +

+ $model->id], ['class' => 'btn btn-primary']) ?> + $model->id], [ + 'class' => 'btn btn-danger', + 'data' => [ + 'confirm' => 'Are you sure you want to delete this item?', + 'method' => 'post', + ], + ]) ?> +

+ + $model, + 'attributes' => [ + 'id', + 'document_field_id', + 'document_id', + 'value', + ], + ]) ?> + +
diff --git a/backend/modules/document/views/document-template/view.php b/backend/modules/document/views/document-template/view.php index a69a41e..19716d2 100644 --- a/backend/modules/document/views/document-template/view.php +++ b/backend/modules/document/views/document-template/view.php @@ -1,5 +1,6 @@ params['breadcrumbs'][] = $this->title; ], [ 'attribute' => 'Переменные в шаблоне', - 'value' => function($model){ - preg_match_all('/(\${\w+})/', $model->template_body,$out); - return implode(",", $out[0]); + 'value' => function(DocumentTemplate $model){ + return implode(", ", $model->getFields()); }, ], ], diff --git a/backend/modules/document/views/document/_form.php b/backend/modules/document/views/document/_form.php index c1effaa..a7ad635 100644 --- a/backend/modules/document/views/document/_form.php +++ b/backend/modules/document/views/document/_form.php @@ -53,15 +53,14 @@ use yii\widgets\ActiveForm; ] ); ?> - field($model, 'contractor_company_id')->widget(Select2::class, + field($model, 'contractor_company_id')->dropDownList( + Company::find()->select(['name', 'id'])->indexBy('id')->column(), [ - 'data' => Company::find()->select(['name', 'id'])->indexBy('id')->column(), - 'options' => ['id' => 'contractor-company-id','placeholder' => '...','class' => 'form-control'], - 'pluginOptions' => [ - 'allowClear' => true - ], + 'id' => 'contractor-company-id', + 'prompt' => 'Выберите' ] - ); ?> + ); + ?> field($model, 'contractor_manager_id')->widget(DepDrop::className(), [ diff --git a/backend/modules/document/views/document/download.php b/backend/modules/document/views/document/download.php index de40f1e..48a6b68 100644 --- a/backend/modules/document/views/document/download.php +++ b/backend/modules/document/views/document/download.php @@ -24,7 +24,6 @@ $this->params['breadcrumbs'][] = 'Загрузить'; 'update-resume-text-form', - 'action' => Url::to(['document/update-document-body', 'id' => $model->id]), 'options' => ['method' => 'post']]) ?> @@ -35,16 +34,12 @@ $this->params['breadcrumbs'][] = 'Загрузить'; ], ]); ?> -
- 'btn btn-primary']) ?> -
-

- $model->id], ['class' => 'btn btn-success']) ?> - $model->id], ['class' => 'btn btn-success']) ?> + $model->id, 'fileType' => 'docx'], ['class' => 'btn btn-success']) ?> + $model->id, 'fileType' => 'pdf'], ['class' => 'btn btn-success']) ?>

\ No newline at end of file diff --git a/backend/modules/document/views/document/index.php b/backend/modules/document/views/document/index.php index efbc01a..d2fe77e 100644 --- a/backend/modules/document/views/document/index.php +++ b/backend/modules/document/views/document/index.php @@ -1,6 +1,7 @@ params['breadcrumbs'][] = $this->title; ['class' => 'yii\grid\SerialColumn'], 'title', -// 'body:ntext', [ 'attribute' => 'company_id', 'filter' => Company::find()->select(['name', 'id'])->indexBy('id')->column(), @@ -38,24 +38,18 @@ $this->params['breadcrumbs'][] = $this->title; ], [ 'attribute' => 'manager_id', - 'filter' => Manager::find()->select(['fio', 'manager.id']) - ->joinWith('userCard')->indexBy('manager.id')->column(), + 'filter' => false, 'value' => 'manager.userCard.fio' ], [ 'attribute' => 'contractor_manager_id', - 'filter' => Manager::find()->select(['fio', 'manager.id']) - ->joinWith('userCard')->indexBy('manager.id')->column(), + 'filter' => false, 'value' => 'manager.userCard.fio' ], - //'title', - //'body:ntext', - //'created_at', - //'updated_at', [ 'class' => 'yii\grid\ActionColumn', - 'template' => '{view} {update} {download}', + 'template' => '{view} {update} {download} {delete}', 'buttons' => [ 'download' => function($url, $model) { return Html::a( @@ -67,4 +61,5 @@ $this->params['breadcrumbs'][] = $this->title; ] ], ]); ?> + diff --git a/backend/modules/document/views/document/view.php b/backend/modules/document/views/document/view.php index fb7d7cf..84d03a2 100644 --- a/backend/modules/document/views/document/view.php +++ b/backend/modules/document/views/document/view.php @@ -1,13 +1,13 @@ title = $model->title; $this->params['breadcrumbs'][] = ['label' => 'Documents', 'url' => ['index']]; @@ -49,7 +49,7 @@ $this->params['breadcrumbs'][] = $this->title; ], [ 'attribute' => 'contractor_manager_id', - 'value' => ArrayHelper::getValue($model, 'manager.userCard.fio'), + 'value' => ArrayHelper::getValue($model, 'contractorManager.userCard.fio'), ], [ 'attribute' => 'body', @@ -61,4 +61,37 @@ $this->params['breadcrumbs'][] = $this->title; ], ]) ?> +
+

+ +

+
+ + $documentFieldValuesDataProvider, + 'columns' => [ + ['class' => 'yii\grid\SerialColumn'], + + [ + 'attribute' => 'document_field_id', + 'value' => 'documentField.title' + ], + 'attribute' => 'value', + + [ + 'class' => 'yii\grid\ActionColumn', + 'template' => '{update}',//'{view} {update} {delete}', + 'controller' => 'document-field-value', + 'buttons' => [ + + 'update' => function ($url,$model) { + return Html::a( + '', + ['document-field-value/update', 'id' => $model['id'], 'fromDocument' => true]); + }, + ], + ], + ], + ]); ?> + diff --git a/backend/views/layouts/left.php b/backend/views/layouts/left.php index 16789bc..4e81dd9 100755 --- a/backend/views/layouts/left.php +++ b/backend/views/layouts/left.php @@ -41,7 +41,7 @@ 'visible' => Yii::$app->user->can('confidential_information') ], [ - 'label' => 'Профили', 'icon' => 'address-book-o', 'url' => '#', //'active' => \Yii::$app->controller->id == 'user-card', + 'label' => 'Профили', 'icon' => 'address-book-o', 'url' => '#', 'items' => $menuItems, 'visible' => Yii::$app->user->can('confidential_information') ], diff --git a/common/models/Company.php b/common/models/Company.php index 7c74d00..2de567f 100755 --- a/common/models/Company.php +++ b/common/models/Company.php @@ -2,7 +2,6 @@ namespace common\models; -use Yii; use yii\behaviors\TimestampBehavior; use yii\db\Expression; @@ -104,4 +103,9 @@ class Company extends \yii\db\ActiveRecord { return $this->hasOne(Project::class, ['company_id' => 'id']); } + + public static function getTitle($id) + { + return self::findOne($id)->name; + } } diff --git a/common/models/CompanyManager.php b/common/models/CompanyManager.php index 2f13bf5..1a9bf3f 100644 --- a/common/models/CompanyManager.php +++ b/common/models/CompanyManager.php @@ -2,9 +2,6 @@ namespace common\models; -use Yii; -use yii\helpers\ArrayHelper; - /** * This is the model class for table "company_manager". * @@ -71,4 +68,9 @@ class CompanyManager extends \yii\db\ActiveRecord { return self::find()->where(['company_id' => $company_id])->all(); } + + public static function getName($id) + { + return self::findOne($id)->userCard->fio; + } } diff --git a/common/models/Document.php b/common/models/Document.php index d84b0af..7120071 100644 --- a/common/models/Document.php +++ b/common/models/Document.php @@ -3,7 +3,9 @@ namespace common\models; use yii\behaviors\TimestampBehavior; +use yii\db\ActiveQuery; use yii\db\Expression; +use yii\db\StaleObjectException; /** * This is the model class for table "document". @@ -24,11 +26,21 @@ use yii\db\Expression; * @property CompanyManager $contractorManager * @property DocumentTemplate $template * @property CompanyManager $manager + * @property DocumentFieldValue[] $documentFieldsValue */ class Document extends \yii\db\ActiveRecord { const SCENARIO_UPDATE_DOCUMENT_BODY = 'update_document_body'; const SCENARIO_DOWNLOAD_DOCUMENT = 'download_document'; + const SCENARIO_PARTICIPANTS_OF_THE_TRANSACTION = "contract_participants"; + + private $notRequiredFieldsSignature = [ + 'company_id' => '${company}', + 'contractor_company_id' => '${contractor_company}', + 'manager_id' => '${manager}', + 'contractor_manager_id' => '${contractor_manager}', + ]; + private $fieldPattern = '/\${(№?\s*\w*|(\w*\s?)*)}/'; /** * {@inheritdoc} @@ -50,6 +62,63 @@ class Document extends \yii\db\ActiveRecord ]; } + /** + * @throws StaleObjectException + * @throws \Throwable + */ + public function beforeDelete() + { + $documentFieldsValue = $this->getDocumentFieldValues()->all(); + if ($documentFieldsValue) { + foreach ($documentFieldsValue as $fieldValue){ + $fieldValue->delete(); + } + } + return parent::beforeDelete(); + } + + public function beforeSave($insert): bool + { + if (parent::beforeSave($insert)) { + $upAttributes = $this->getDirtyAttributes(['company_id', 'contractor_company_id', 'manager_id', 'contractor_manager_id', 'title']); + $oldAttributes = $this->oldAttributes; + + + //update dirty attributes in document body + if ($oldAttributes && $upAttributes) { + foreach ($upAttributes as $key => $value) { + if ($value != $oldAttributes[$key]) { + + if ($key == 'company_id' || $key == 'contractor_company_id') { + $newValue = Company::getTitle($value); + $oldValue = $oldAttributes[$key] ? Company::getTitle($oldAttributes[$key]) : $key; + } elseif ($key == 'manager_id' || $key == 'contractor_manager_id') { + $newValue = CompanyManager::getName($value); + $oldValue = $oldAttributes[$key] ? CompanyManager::getName($oldAttributes[$key]) : $key; + } else { + $newValue = $this->title; + $oldValue = $oldAttributes[$key] ?? $key; + } + + $this->body = str_replace($oldValue, $newValue, $this->body); + } + } + } + + + //deleting fields value + if ($this->isAttributeChanged('template_id', false)) { + $documentFieldsValue = $this->getDocumentFieldValues()->all(); + foreach ($documentFieldsValue as $fieldValue){ + $fieldValue->delete(); + } + } + return true; + } else { + return false; + } + } + /** * {@inheritdoc} */ @@ -58,7 +127,6 @@ class Document extends \yii\db\ActiveRecord return [ [['title', 'template_id'], 'required'], [['company_id', 'contractor_company_id', 'manager_id', 'contractor_manager_id', 'template_id'], 'integer'], - [['body'], 'string'], [['created_at', 'updated_at'], 'safe'], [['title'], 'string', 'max' => 255], [['company_id'], 'exist', 'skipOnError' => true, 'targetClass' => Company::className(), 'targetAttribute' => ['company_id' => 'id']], @@ -67,16 +135,44 @@ class Document extends \yii\db\ActiveRecord [['template_id'], 'exist', 'skipOnError' => true, 'targetClass' => DocumentTemplate::className(), 'targetAttribute' => ['template_id' => 'id']], [['manager_id'], 'exist', 'skipOnError' => true, 'targetClass' => CompanyManager::className(), 'targetAttribute' => ['manager_id' => 'id']], ['body', 'required', 'on' => self::SCENARIO_UPDATE_DOCUMENT_BODY], - ['body', function ($attribute, $params) { - preg_match_all('/\${(\w+|№|№+w)}/', $this->$attribute,$out); - if (!empty($out[0])) { - $this->addError('body', 'В теле документа все переменные должны быть заменены!'); - } - }, 'on' => self::SCENARIO_DOWNLOAD_DOCUMENT - ], + ['body', 'checkBlankFields', 'on' => self::SCENARIO_DOWNLOAD_DOCUMENT ], + [['company_id', 'contractor_company_id', 'manager_id', 'contractor_manager_id'], 'checkContractParticipants', 'skipOnEmpty'=> false, 'on' => self::SCENARIO_PARTICIPANTS_OF_THE_TRANSACTION], + [['company_id', 'contractor_company_id'], 'checkCompanies', 'skipOnEmpty'=> false, 'on' => self::SCENARIO_PARTICIPANTS_OF_THE_TRANSACTION], + [['contractor_manager_id', 'manager_id'], 'checkManagers', 'skipOnEmpty'=> false, 'on' => self::SCENARIO_PARTICIPANTS_OF_THE_TRANSACTION], ]; } + public function checkCompanies() + { + if ($this->company_id === $this->contractor_company_id && $this->company_id) { + $this->addError('company_id', 'Компании и компания контрагент должны быть различны '); + $this->addError('contractor_company_id', 'Компании и компания контрагент должны быть различны '); + } + } + + public function checkManagers() + { + if ($this->manager_id && $this->manager->userCard->id == $this->contractorManager->userCard->id) { + $this->addError('manager_id', 'Менеджер и менеджер контрагент должны быть различными лицами'); + $this->addError('contractor_manager_id', 'Менеджер и менеджер контрагент должны быть различны лицами'); + } + } + + public function checkBlankFields($attribute) + { + preg_match_all($this->fieldPattern, $this->$attribute,$out); + if (!empty($out[0])) { + $this->addError('body', 'В теле документа все переменные должны быть заменены!'); + } + } + + public function checkContractParticipants($attribute) + { + if (str_contains($this->body, $this->notRequiredFieldsSignature[$attribute])) { + $this->addError($attribute, 'Шаблоном требуется заполнить это поле'); + } + } + /** * {@inheritdoc} */ @@ -97,7 +193,7 @@ class Document extends \yii\db\ActiveRecord } /** - * @return \yii\db\ActiveQuery + * @return ActiveQuery */ public function getTemplate() { @@ -105,7 +201,7 @@ class Document extends \yii\db\ActiveRecord } /** - * @return \yii\db\ActiveQuery + * @return ActiveQuery */ public function getCompany() { @@ -113,7 +209,7 @@ class Document extends \yii\db\ActiveRecord } /** - * @return \yii\db\ActiveQuery + * @return ActiveQuery */ public function getContractorCompany() { @@ -121,7 +217,7 @@ class Document extends \yii\db\ActiveRecord } /** - * @return \yii\db\ActiveQuery + * @return ActiveQuery */ public function getContractorManager() { @@ -129,10 +225,24 @@ class Document extends \yii\db\ActiveRecord } /** - * @return \yii\db\ActiveQuery + * @return ActiveQuery */ public function getManager() { return $this->hasOne(CompanyManager::className(), ['id' => 'manager_id']); } + + /** + * @return ActiveQuery + */ + public function getDocumentFieldValues(): ActiveQuery + { + return $this->hasMany(DocumentFieldValue::className(), ['document_id' => 'id']); + } + + public function getBlankFields() + { + preg_match_all($this->fieldPattern, $this->body,$out); + return $out[0]; + } } diff --git a/common/models/DocumentField.php b/common/models/DocumentField.php index ee22381..5d34f26 100644 --- a/common/models/DocumentField.php +++ b/common/models/DocumentField.php @@ -2,7 +2,6 @@ namespace common\models; -use Yii; use yii\helpers\ArrayHelper; /** @@ -29,6 +28,7 @@ class DocumentField extends \yii\db\ActiveRecord { return [ [['title', 'field_template'], 'string', 'max' => 255], + ['field_template', 'string', 'max' => 255], ]; } diff --git a/common/models/DocumentFieldValue.php b/common/models/DocumentFieldValue.php new file mode 100644 index 0000000..d780207 --- /dev/null +++ b/common/models/DocumentFieldValue.php @@ -0,0 +1,69 @@ + 255], + ['value', 'unique', 'targetAttribute' => ['document_id', 'value'], 'message'=>'Значение каждого поля должно быть уникально в пределах документа'], // + [['document_id'], 'exist', 'skipOnError' => true, 'targetClass' => Document::className(), 'targetAttribute' => ['document_id' => 'id']], + [['document_field_id'], 'exist', 'skipOnError' => true, 'targetClass' => DocumentField::className(), 'targetAttribute' => ['document_field_id' => 'id']], + ]; + } + + /** + * {@inheritdoc} + */ + public function attributeLabels() + { + return [ + 'id' => 'ID', + 'document_field_id' => 'Поле', + 'document_id' => 'Документ', + 'value' => 'Значение', + ]; + } + + /** + * @return \yii\db\ActiveQuery + */ + public function getDocument() + { + return $this->hasOne(Document::className(), ['id' => 'document_id']); + } + + /** + * @return \yii\db\ActiveQuery + */ + public function getDocumentField() + { + return $this->hasOne(DocumentField::className(), ['id' => 'document_field_id']); + } +} diff --git a/common/models/DocumentTemplate.php b/common/models/DocumentTemplate.php index 14f6c28..4639f85 100644 --- a/common/models/DocumentTemplate.php +++ b/common/models/DocumentTemplate.php @@ -18,6 +18,8 @@ use yii\db\Expression; */ class DocumentTemplate extends \yii\db\ActiveRecord { + private $fieldPattern = '/\${(№?\s*\w*|(\w*\s?)*)}/'; + /** * {@inheritdoc} */ @@ -66,4 +68,10 @@ class DocumentTemplate extends \yii\db\ActiveRecord 'updated_at' => 'Updated At', ]; } + + public function getFields() + { + preg_match_all($this->fieldPattern, $this->template_body,$out); + return $out[0]; + } } diff --git a/common/services/DocumentService.php b/common/services/DocumentService.php index ec0007b..3aa8672 100644 --- a/common/services/DocumentService.php +++ b/common/services/DocumentService.php @@ -83,10 +83,10 @@ class DocumentService public static function generateDocumentBody(Document $model) { $templateModel = DocumentTemplate::findOne($model->template_id); - preg_match_all('/(\${\w+})/', $templateModel->template_body,$out); + $fields = $templateModel->getFields(); $document = $templateModel->template_body;; - foreach ($out[0] as $field) { + foreach ($fields as $field) { if (str_contains($document, $field)) { switch ($field) { @@ -97,22 +97,27 @@ class DocumentService $fieldValue = $model->title; break; case '${company}': - $fieldValue = $model->company->name; + $fieldValue = $model->company->name ?? $field; break; case '${manager}': - $fieldValue = $model->manager->userCard->fio; + $fieldValue = $model->manager->userCard->fio ?? $field; break; case '${contractor_company}': - $fieldValue = $model->contractorCompany->name; + $fieldValue = $model->contractorCompany->name ?? $field; break; case '${contractor_manager}': - $fieldValue = $model->contractorManager->userCard->fio; + $fieldValue = $model->contractorManager->userCard->fio ?? $field; break; default: $fieldValue = $field; break; } - $document = str_replace($field, $fieldValue, $document); + + if ($fieldValue == $field) { + continue; + } else { + $document = str_replace($field, $fieldValue, $document); + } } } $model->body = $document; diff --git a/console/migrations/m221205_124307_create_document_field_value_table.php b/console/migrations/m221205_124307_create_document_field_value_table.php new file mode 100644 index 0000000..661dab7 --- /dev/null +++ b/console/migrations/m221205_124307_create_document_field_value_table.php @@ -0,0 +1,35 @@ +createTable('{{%document_field_value}}', [ + 'id' => $this->primaryKey(), + 'document_field_id' => $this->integer(11)->notNull(), + 'document_id' => $this->integer(11)->notNull(), + 'value' => $this->string() + ]); + + $this->addForeignKey('document_field_document_field_value', 'document_field_value', 'document_field_id', 'document_field', 'id'); + $this->addForeignKey('document_document_field_value', 'document_field_value', 'document_id', 'document', 'id'); + } + + /** + * {@inheritdoc} + */ + public function safeDown() + { + $this->dropForeignKey('document_field_document_field_value', 'document_field_value'); + $this->dropForeignKey('document_document_field_value', 'document_field_value'); + $this->dropTable('{{%document_field_value}}'); + } +}