self::SCENARIO_NEW_AGREEMENT ], [ 'status', 'default', 'value' => self::STATUS_NOTVERIFIED ], [['archive'], 'boolean'], [ 'status', 'in', 'range' => [ AdmissionAgreement::STATUS_NOTVERIFIED, AdmissionAgreement::STATUS_VERIFIED, AdmissionAgreement::STATUS_MARKED_TO_DELETE, ] ], [ ['file'], 'file', 'extensions' => AdmissionAgreement::getExtensionsListForRules(), 'skipOnEmpty' => true, 'maxSize' => iniGet::getUploadMaxFilesize(false), 'except' => [static::SCENARIO_RECOVER] ], ]; } public static function getExtensionsListForRules(): string { return implode(', ', static::getExtensionsList()); } public static function getExtensionsList(): array { return FilesWorker::getAllowedExtensionsToUploadList(); } public function validateUniqueSpec() { if ($this->status === self::STATUS_MARKED_TO_DELETE) { return true; } if (AdmissionAgreement::find() ->active() ->andWhere([AdmissionAgreement::tableName() . '.speciality_id' => $this->speciality_id]) ->andWhere(['not', [AdmissionAgreement::tableName() . '.status' => self::STATUS_MARKED_TO_DELETE]]) ->exists() ) { $this->addError( 'speciality_id', Yii::t( 'abiturient/bachelor/application/admission-agreement', 'Подсказка с ошибкой для поля "speciality_id"; формы согласия: `Невозможно прикрепить несколько согласий на зачисление на одно направление подготовки.`' ) ); return false; } return true; } public function scenarios() { $scenarios = parent::scenarios(); $scenarios[self::SCENARIO_NEW_AGREEMENT] = $scenarios[self::SCENARIO_DEFAULT]; return $scenarios; } public function getStatusString() { switch ($this->status) { case self::STATUS_NOTVERIFIED: return Yii::t('abiturient/bachelor/application/admission-agreement', 'Статус согласия: `Не подтверждено`'); case self::STATUS_VERIFIED: return Yii::t('abiturient/bachelor/application/admission-agreement', 'Статус согласия: `Подтверждено`'); case self::STATUS_MARKED_TO_DELETE: return Yii::t('abiturient/bachelor/application/admission-agreement', 'Статус согласия: `Отклонено`'); default: return Yii::t('abiturient/bachelor/application/admission-agreement', 'Статус согласия: `Неизвестно`'); } } public function attributeLabels() { return [ 'file' => Yii::t('abiturient/bachelor/application/admission-agreement', 'Подпись для поля "file"; формы согласия: `файл`'), 'status' => Yii::t('abiturient/bachelor/application/admission-agreement', 'Подпись для поля "status"; формы согласия: `Статус`'), 'statusString' => Yii::t('abiturient/bachelor/application/admission-agreement', 'Подпись для поля "status"; формы согласия: `Статус`'), 'filename' => Yii::t('abiturient/bachelor/application/admission-agreement', 'Подпись для поля "filename"; формы согласия: `Имя файла`'), 'speciality_id' => Yii::t('abiturient/bachelor/application/admission-agreement', 'Подпись для поля "speciality_id"; формы согласия: `Направление подготовки`'), ]; } public function getSpeciality() { return $this->hasOne(BachelorSpeciality::class, ['id' => 'speciality_id']); } public function getUser() { return ArrayHelper::getValue($this, 'speciality.application.user'); } public function getRawAgreementDecline() { return $this->hasOne(AgreementDecline::class, ['agreement_id' => 'id']) ->orderBy([AgreementDecline::tableName() . '.archive' => SORT_ASC]); } public function getAgreementDecline() { return $this->hasOne(AgreementDecline::class, ['agreement_id' => 'id']) ->active() ->orderBy([AgreementDecline::tableName() . '.archive' => SORT_ASC]); } protected function getOwnerId() { return $this->user->id; } public function checkAccess($user) { if ($user->isModer()) { return true; } elseif ($user->id == $this->getOwnerId()) { return true; } else { return false; } } public function makeDeclined() { if ($this->status === AdmissionAgreement::STATUS_NOTVERIFIED) { return $this->archive(); } $user_id = ArrayHelper::getValue($this, 'speciality.application.user.id'); $app_code = ArrayHelper::getValue($this, 'speciality.application_code'); $campaign_code = ArrayHelper::getValue($this, 'speciality.application.type.campaign.referenceType.reference_id'); $transaction = Yii::$app->db->beginTransaction(); try { if (isset($user_id, $app_code, $campaign_code)) { $toDeleteEntity = new AdmissionAgreementToDelete([ 'user_id' => $user_id, 'agreement_id' => $this->id, 'application_code' => $app_code, 'campaign_code' => $campaign_code, 'archive' => false ]); $result = $this->markToDelete() && $toDeleteEntity->validate(); if ($result) { $toDeleteEntity->save(false); $transaction->commit(); return true; } } $transaction->rollBack(); return false; } catch (\Throwable $e) { $transaction->rollBack(); throw $e; } } public function markToDelete() { $this->status = self::STATUS_MARKED_TO_DELETE; if ($this->validate()) { $this->save(false); return true; } return false; } public function archiveAllDeclines() { if (isset($this->speciality->application_code)) { AdmissionAgreementToDelete::updateAll(['archive' => true], [ 'user_id' => $this->user->id, 'id' => $this->getRawAgreementToDelete()->select('id')->column() ]); AgreementDecline::updateAll(['archive' => true], [ 'id' => $this->getAgreementDecline()->select('id')->column() ]); } } public function getRawAgreementToDelete() { return $this->hasOne(AdmissionAgreementToDelete::class, ['agreement_id' => 'id']); } public function getAgreementToDelete() { return $this->getRawAgreementToDelete()->andOnCondition([AdmissionAgreementToDelete::tableName() . '.archive' => false]); } public function getClassTypeForChangeHistory(): int { return ChangeHistoryClasses::CLASS_AGREEMENT; } public function getChangeLoggedAttributes() { return []; } public function getOldClass(): ChangeLoggedModelInterface { return $this; } public function getEntityIdentifier(): ?string { if ($this->speciality !== null) { return $this->speciality->getEntityIdentifier(); } return ''; } public function getChangeHistoryHandler(): ?ChangeHistoryHandlerInterface { return null; } public function getEntityChangeType(): int { return ChangeHistory::CHANGE_HISTORY_NEW_AGREEMENT; } public function setChangeHistoryHandler(ChangeHistoryHandlerInterface $handler) { return null; } public function beforeArchive() { if ($this->agreementDecline) { $this->agreementDecline->archive(); } } public function beforeDelete() { if (parent::beforeDelete()) { $transaction = Yii::$app->db->beginTransaction(); $deleteSuccess = true; try { $errorFrom = ''; $agreementDecline = $this->getRawAgreementDecline()->all(); if (!empty($agreementDecline)) { foreach ($agreementDecline as $dataToDelete) { $deleteSuccess = $dataToDelete->delete(); if (!$deleteSuccess) { $errorFrom .= "{$this->tableName()} -> {$dataToDelete->tableName()} -> {$dataToDelete->id}\n"; break; } } } if ($deleteSuccess) { $agreementToDelete = $this->getRawAgreementToDelete()->all(); if (!empty($agreementToDelete)) { foreach ($agreementToDelete as $dataToDelete) { $deleteSuccess = $dataToDelete->delete(); if (!$deleteSuccess) { $errorFrom .= "{$this->tableName()} -> {$dataToDelete->tableName()} -> {$dataToDelete->id}\n"; break; } } } } if ($deleteSuccess) { $this->deleteAttachedFile(); $transaction->commit(); } else { Yii::error("Ошибка при удалении данных с портала. В таблице: {$errorFrom}"); $transaction->rollBack(); return false; } return true; } catch (\Throwable $e) { $transaction->rollBack(); Yii::error("Ошибка при удалении данных с портала. " . $e->getMessage()); return false; } } else { return false; } } public function afterValidate() { (new LoggingAfterValidateHandler()) ->setModel($this) ->invoke(); } public function getRelationsInfo(): array { return [ new OneToManyRelationPresenter('agreementDeclines', [ 'parent_instance' => $this, 'child_class' => AgreementDecline::class, 'child_column_name' => 'agreement_id', ]), new OneToManyRelationPresenter('agreementsToDelete', [ 'parent_instance' => $this, 'child_class' => AdmissionAgreementToDelete::class, 'child_column_name' => 'agreement_id', 'ignore_in_comparison' => true, ]), ]; } public function getIdentityString(): string { $declined = (int)(bool)$this->agreementDecline; return "{$this->status}_{$declined}_{$this->filename}"; } public function getPropsToCompare(): array { return [ 'statusString', 'filename', ]; } }