questionaryFileAttacher = new AbiturientQuestionaryFileAttacher($this); } public function behaviors() { return [TimestampBehavior::class]; } public function rules() { return [ [ [ 'user_id', 'approver_id', 'status', 'draft_status' ], 'integer' ], [ ['have_no_previous_passport'], 'boolean' ], [ ['draft_status'], 'in', 'range' => [ self::DRAFT_STATUS_CREATED, self::DRAFT_STATUS_SENT, self::DRAFT_STATUS_MODERATING, self::DRAFT_STATUS_APPROVED, ] ], [ 'draft_status', 'default', 'value' => self::DRAFT_STATUS_CREATED ], [ 'status', 'default', 'value' => self::STATUS_CREATED ], [ 'have_no_previous_passport', 'default', 'value' => false ], [ 'status', 'in', 'range' => [ self::STATUS_CREATED, self::STATUS_SENT, self::STATUS_APPROVED, self::STATUS_NOT_APPROVED, self::STATUS_REJECTED_BY1C, self::STATUS_CREATE_FROM_1C ] ], ]; } public function attributeLabels() { return [ 'fio' => Yii::t('abiturient/bachelor/questionary/abiturient-questionary', 'Подпись для поля "fio" формы "Анкеты": `ФИО`'), 'status' => Yii::t('abiturient/bachelor/questionary/abiturient-questionary', 'Подпись для поля "status" формы "Анкеты": `Статус`'), 'user_id' => Yii::t('abiturient/bachelor/questionary/abiturient-questionary', 'Подпись для поля "user_id" формы "Анкеты": `Поступающий`'), 'userRef' => Yii::t('abiturient/bachelor/questionary/abiturient-questionary', 'Подпись для поля "userRef" формы "Анкеты": `Код физ. лица`'), 'usermail' => Yii::t('abiturient/bachelor/questionary/abiturient-questionary', 'Подпись для поля "usermail" формы "Анкеты": `Email`'), 'approver_id' => Yii::t('abiturient/bachelor/questionary/abiturient-questionary', 'Подпись для поля "approver_id" формы "Анкеты": `Проверивший модератор`'), 'approved_at' => Yii::t('abiturient/bachelor/questionary/abiturient-questionary', 'Подпись для поля "approved_at" формы "Анкеты": `Проверено в`'), 'created_at' => Yii::t('abiturient/bachelor/questionary/abiturient-questionary', 'Подпись для поля "created_at" формы "Анкеты": `Создано в`'), ]; } public function getPersonalData() { return $this->hasOne(PersonalData::class, ['questionary_id' => 'id']); } public function getPassportData() { return $this->getRawPassportData()->andOnCondition([PassportData::tableName() . '.archive' => false]); } public function getRawPassportData() { return $this->hasMany(PassportData::class, ['questionary_id' => 'id']); } public function getAddressData() { return $this->hasOne(AddressData::class, ['questionary_id' => 'id']); } public function getActualAddressData() { return $this->hasOne(ActualAddressData::class, ['questionary_id' => 'id']); } public function getParentData() { return $this->hasMany(ParentData::class, ['questionary_id' => 'id']) ->andWhere([ParentData::tableName() . '.archive' => false]); } public function getAllParentData() { return $this->hasMany(ParentData::class, ['questionary_id' => 'id']); } public function getUser() { return $this->getRawUser()->andOnCondition(['user.is_archive' => false]); } public function getRawUser() { return $this->hasOne(User::class, ['id' => 'user_id']); } public function getAttachments() { return $this->hasMany(Attachment::class, ['questionary_id' => 'id']) ->joinWith('attachmentType attachment_type') ->andWhere([ Attachment::tableName() . '.deleted' => false, 'attachment_type.hidden' => false, 'attachment_type.system_type' => AttachmentType::SYSTEM_TYPE_COMMON, 'attachment_type.id' => AttachmentType::find()->alias('at')->select('at.id')->notInRegulation() ]) ->union( Attachment::find() ->innerJoinWith('attachmentType attachment_type', false) ->andWhere([ Attachment::tableName() . '.deleted' => false, 'attachment_type.related_entity' => AttachmentType::RELATED_ENTITY_REGISTRATION, 'attachment_type.id' => AttachmentType::find()->alias('at')->select('at.id')->notInRegulation() ]) ->andWhere([ Attachment::tableName() . '.owner_id' => $this->user_id, Attachment::tableName() . '.questionary_id' => null, ]) ); } public function getPassportsAttachments() { $passport_attachments = $this->getPassportData()->innerJoinWith(['attachments attachment'])->select(['attachment.id']); return Attachment::find()->where(['id' => $passport_attachments])->with(['attachmentType']); } protected function buildAdditionalElements(): array { $result = []; $personal_data = $this->personalData; if ($personal_data) { $result[] = BaseApplicationPackageBuilder::buildAdditionalAttribute('EntrantUniqueCode', $personal_data->entrant_unique_code); $result[] = BaseApplicationPackageBuilder::buildAdditionalAttribute('EntrantUniqueCodeSpecialQuota', $personal_data->entrant_unique_code_special_quota); } return $result; } public function getEntrantRefFrom1C() { if (Yii::$app->configurationManager->fullPackageEntrantProfileAvailable()) { $result = $this->getRawGetEntrantProfilePackageFrom1C(); if ($result && isset($result->Entrant) && isset($result->Entrant->EntrantRef)) { return $result->Entrant->EntrantRef; } } return null; } public function getRawGetEntrantProfilePackageFrom1C(): ?stdClass { if (!$this->user || !$this->user->userRef) { return null; } $result = Yii::$app->soapClientWebApplication->load_with_caching( 'GetEntrantProfilePackage', [ 'EntrantRef' => UserReferenceTypeManager::GetProcessedUserReferenceType($this->user) ] ); if ($result === false) { return null; } if (!isset($result->return) || !isset($result->return->Entrant)) { Yii::$app->session->setFlash( 'errorGetAnketa', 'Ошибка получения анкеты из ПК' ); return null; } return $result->return; } public function getFrom1C($fetch_email = true, &$errors = null): bool { if (Yii::$app->configurationManager->fullPackageEntrantProfileAvailable()) { return $this->getFrom1CByGetEntrantProfilePackage($fetch_email, $errors); } return false; } public function getFrom1CWithParents($fetch_email = true, &$errors = null): bool { $this->getFrom1C($fetch_email, $errors); return true; } public function getFrom1CByGetEntrantProfilePackage($fetch_email = true, &$errors = null): bool { $raw_data = $this->getRawGetEntrantProfilePackageFrom1C(); if (!$raw_data) { if ($errors !== null) { $label = Yii::t( 'abiturient/bachelor/questionary/abiturient-questionary', 'Подпись для блока ошибок в данных пользователя; формы "Анкеты": `Данные пользователя`' ); $errors[$label] = 'Ошибка получения анкеты из ПК'; } return false; } $this->save(false); return (new FullApplicationPackageBuilder(null)) ->setQuestionary($this) ->updateUserRefByFullPackage($raw_data) ->updateQuestionary($raw_data, true, $fetch_email); } public function getEntireQuestionaryAttachmentCollections(): array { $collections = FileRepository::GetQuestionaryCollectionsFromTypes($this, [ PageRelationManager::RELATED_ENTITY_QUESTIONARY, PageRelationManager::RELATED_ENTITY_REGISTRATION ]); $regulations = UserRegulationRepository::GetUserRegulationsWithFilesByQuestionaryAndRelatedEntity($this, [ PageRelationManager::RELATED_ENTITY_QUESTIONARY, PageRelationManager::RELATED_ENTITY_REGISTRATION ]); $collections = array_merge($collections, ArrayHelper::getColumn($this->passportData, 'attachmentCollection')); return array_merge($collections, ArrayHelper::getColumn($regulations, 'attachmentCollection')); } public function isNotCreatedDraft() { if (in_array($this->draft_status, [IDraftable::DRAFT_STATUS_SENT, IDraftable::DRAFT_STATUS_MODERATING, IDraftable::DRAFT_STATUS_APPROVED])) { return true; } if ($this->getLinkedBachelorApplication() ->andWhere([BachelorApplication::tableName() . '.draft_status' => [IDraftable::DRAFT_STATUS_SENT, IDraftable::DRAFT_STATUS_MODERATING]]) ->exists() ) { return true; } return false; } public function canEditQuestionary() { if (Yii::$app->user->identity->isModer()) { $linked_app = $this->getLinkedBachelorApplication()->one(); if ($linked_app) { return $this->draft_status == $linked_app->getDraftStatusToModerate(); } return $this->draft_status != IDraftable::DRAFT_STATUS_APPROVED; } else { return !$this->isNotCreatedDraft(); } } public static function isBlockedAfterApprove(?AbiturientQuestionary $questionary): bool { if (is_null($questionary)) { return false; } $block_after_approve = !QuestionarySettings::getSettingByName('allow_edit_questionary_after_approve'); return $block_after_approve && isset($questionary->user) && $questionary->hasApprovedApps(); } public function getStatusMessage() { $first_app_type = ArrayHelper::getValue($this, 'user.applications.0.type'); switch ($this->status) { case (self::STATUS_SENT): return Yii::$app->configurationManager->getText('questionary_sended', $first_app_type); case (self::STATUS_APPROVED): if (Yii::$app->configurationManager->sandboxEnabled) { return Yii::$app->configurationManager->getText('questionary_approved_sandbox_on', $first_app_type); } else { return Yii::$app->configurationManager->getText('questionary_approved_sandbox_off', $first_app_type); } case (self::STATUS_NOT_APPROVED): return Yii::$app->configurationManager->getText('questionary_notapproved', $first_app_type); case (self::STATUS_REJECTED_BY1C): return Yii::$app->configurationManager->getText('questionary_rejected_by1c', $first_app_type); case (self::STATUS_CREATE_FROM_1C): return Yii::$app->configurationManager->getText('questionary__create_from_1C', $first_app_type); default: return false; } } public function getFio() { return ArrayHelper::getValue($this, 'personalData.fio'); } public function getUsermail() { return ArrayHelper::getValue($this, 'user.email'); } public static function UpdateDataFromOneS(AbiturientQuestionary $questionary): AbiturientQuestionary { $transaction = Yii::$app->db->beginTransaction(); try { $actual = DraftsManager::getActualQuestionary($questionary->user, true); if ($actual) { $raw_ref = $questionary->getEntrantRefFrom1C(); if ($raw_ref) { $questionary->user->assignUserRef($raw_ref); } if ($actual->id != $questionary->id) { $draft_status = $questionary->draft_status; $status = $questionary->status; if ($status == AbiturientQuestionary::STATUS_CREATED) { $status = AbiturientQuestionary::STATUS_APPROVED; } $questionary = DraftsManager::makeCopy($actual, $questionary); $questionary->draft_status = $draft_status; $questionary->status = $status; $questionary->save(false); } } $transaction->commit(); } catch (\Throwable $e) { $transaction->rollBack(); throw $e; } return $questionary; } public function canCreateQuestionary() { $startDates = $this->getCampaignsStartDates(); if (empty($startDates)) { return false; } foreach ($startDates as $start) { if ((new DateTime($start['minDate'])) < (new DateTime())) { return true; } } return false; } public function getCampaignsStartDates() { $applicationTypes = ApplicationType::findAll(['archive' => false]); if (empty($applicationTypes)) { return []; } else { $startDates = []; foreach ($applicationTypes as $applicationType) { $campaignInfo = (new Query()) ->select(["MIN(" . IndependentQueryManager::strToDateTime("date_start") . ") AS min_date_start"]) ->from('campaign_info') ->where([ 'archive' => false, 'campaign_id' => $applicationType->campaign_id ]) ->one(); $minDate = ArrayHelper::getValue($campaignInfo, 'min_date_start'); if (isset($minDate)) { $startDates[] = [ 'minDate' => $minDate, 'nameCampaign' => $applicationType->name ]; } } return $startDates; } } public function getChangeHistory() { return $this->hasMany( ChangeHistory::class, ['questionary_id' => 'id'] ); } public function getChangeHistoryOrderedById() { return $this->getChangeHistory()->orderBy([ChangeHistory::tableName() . '.id' => SORT_ASC]); } private function processAddressDataFrom1C($response, $fieldName, $addressData) { return self::updateAddressFromOneS($addressData, $response->return->$fieldName); } public function updateAddressFromOneS(AddressData $addressData, $raw_data): ?AddressData { $raw_data = ToAssocCaster::getAssoc($raw_data); if (empty($raw_data)) { return null; } $addressData->postal_index = ArrayHelper::getValue($raw_data, 'PostalIndex'); $russia_guid = Yii::$app->configurationManager->getCode('russia_guid'); $country = null; $countryRef = ArrayHelper::getValue($raw_data, 'CountryRef'); if (isset($countryRef) && !empty($countryRef)) { $country = ReferenceTypeManager::GetOrCreateReference(Country::class, $countryRef); } $countryCode = ArrayHelper::getValue($raw_data, 'Country'); if (is_null($country) && isset($countryCode)) { $country = Country::findOne(['code' => (string)$countryCode, 'archive' => false]); } $addressData->country_id = $country->id ?? null; $addressData->not_found = false; $addressData->homeless = (bool)ArrayHelper::getValue($raw_data, 'Homeless', false); if (!empty($country) && $country->ref_key == $russia_guid) { $region = AddressHelper::getRegion(ArrayHelper::getValue($raw_data, 'Region'))->getOne(); $area = AddressHelper::getArea($region, ArrayHelper::getValue($raw_data, 'Area'))->getOne(); $city = AddressHelper::getCity($region, $area, ArrayHelper::getValue($raw_data, 'City'))->getOne(); $town = AddressHelper::getTown($region, $area, $city, ArrayHelper::getValue($raw_data, 'Town'))->getOne(); $street = AddressHelper::getStreet($region, $area, $city, $town, ArrayHelper::getValue($raw_data, 'Street'))->getOne(); AddressData::setAddressProperty( $addressData, $region, ArrayHelper::getValue($raw_data, 'Region'), 'region_id', 'region_name', true, true ); AddressData::setAddressProperty( $addressData, $area, ArrayHelper::getValue($raw_data, 'Area'), 'area_id', 'area_name' ); AddressData::setAddressProperty( $addressData, $city, ArrayHelper::getValue($raw_data, 'City'), 'city_id', 'city_name' ); AddressData::setAddressProperty( $addressData, $town, ArrayHelper::getValue($raw_data, 'Town'), 'village_id', 'town_name' ); AddressData::setAddressProperty( $addressData, $street, ArrayHelper::getValue($raw_data, 'Street'), 'street_id', 'street_name' ); $addressData->processKLADRCode(); } else { $addressData->not_found = true; $addressData->region_name = ArrayHelper::getValue($raw_data, 'Region'); $addressData->area_name = ArrayHelper::getValue($raw_data, 'Area'); $addressData->city_name = ArrayHelper::getValue($raw_data, 'City'); $addressData->town_name = ArrayHelper::getValue($raw_data, 'Town'); $addressData->street_name = ArrayHelper::getValue($raw_data, 'Street'); } $addressData->house_number = ArrayHelper::getValue($raw_data, 'House'); $addressData->housing_number = ArrayHelper::getValue($raw_data, 'Korpus'); $addressData->flat_number = ArrayHelper::getValue($raw_data, 'Kvartira'); $addressData->isFrom1C = true; $addressData->cleanUnusedAttributes(); DraftsManager::SuspendHistory($addressData); if (!$addressData->save()) { throw new UserException("Не удалось обновить адрес: " . print_r($addressData->errors, true)); } return $addressData; } public function getOrCreateActualAddressData(bool $run_model_preparation = true) { $addressData = $this->actualAddressData; if ($addressData === null) { $addressData = new ActualAddressData(); $addressData->questionary_id = $this->id; $addressData->homeless = false; $country = Country::findOne([ 'ref_key' => Yii::$app->configurationManager->getCode('russia_guid'), 'archive' => false ]); if ($country === null) { throw new UserException('Невозможно найти страну по коду по умолчанию.'); } $addressData->country_id = $country->id; } if ($run_model_preparation) { $addressData->validation_extender ? $addressData->validation_extender->modelPreparationCallback() : null; } return $addressData; } public function getAbiturientAvatar() { return $this->hasOne(AbiturientAvatar::class, [ 'questionary_id' => 'id' ])->andWhere([ 'attachment_type_id' => AttachmentManager::GetSystemAttachmentType(AttachmentType::SYSTEM_TYPE_ABITURIENT_AVATAR)->id, 'deleted' => false ]); } public function getComputedAbiturientAvatar(): AbiturientAvatar { $avatar = $this->abiturientAvatar; if ($avatar === null) { $avatar = new AbiturientAvatar(); $avatar->owner_id = $this->user->id; $avatar->questionary_id = $this->id; $avatar->deleted = false; $avatar->attachment_type_id = AttachmentManager::GetSystemAttachmentType(AttachmentType::SYSTEM_TYPE_ABITURIENT_AVATAR)->id; } return $avatar; } public function attachPhoto(IReceivedFile $receivingFile): ?File { $attachment = $this->getComputedAbiturientAvatar(); if ($attachment->getIsNewRecord()) { $attachment->save(false); } $file = $receivingFile->getFile($attachment); $attachment->LinkFile($file); return $file; } public function beforeDelete() { $transaction = Yii::$app->db->beginTransaction(); $deleteSuccess = true; try { $errorFrom = ''; $personalData = $this->personalData; if (isset($personalData)) { $deleteSuccess = $personalData->delete(); } if (!$deleteSuccess) { $errorFrom .= "{$this->tableName()} -> {$personalData->tableName()} -> {$personalData->id}\n"; } if ($deleteSuccess) { $passportData = $this->rawPassportData; if (!empty($passportData)) { foreach ($passportData as $dataToDelete) { $deleteSuccess = $dataToDelete->delete(); if (!$deleteSuccess) { $errorFrom .= "{$this->tableName()} -> {$dataToDelete->tableName()} -> {$dataToDelete->id}\n"; break; } } } } if ($deleteSuccess) { $addressData = $this->addressData; if (isset($addressData)) { $deleteSuccess = $addressData->delete(); } if (!$deleteSuccess) { $errorFrom .= "{$this->tableName()} -> {$addressData->tableName()} -> {$addressData->id}\n"; } } if ($deleteSuccess) { $parentData = $this->allParentData; if (!empty($parentData)) { foreach ($parentData as $dataToDelete) { $deleteSuccess = $dataToDelete->delete(); if (!$deleteSuccess) { $errorFrom .= "{$this->tableName()} -> {$dataToDelete->tableName()} -> {$dataToDelete->id}\n"; break; } } } } if ($deleteSuccess) { $actualAddressData = $this->actualAddressData; if (isset($actualAddressData)) { $deleteSuccess = $actualAddressData->delete(); } if (!$deleteSuccess) { $errorFrom .= "{$this->tableName()} -> {$actualAddressData->tableName()} -> {$actualAddressData->id}\n"; } } if ($deleteSuccess) { $attachments = $this->attachments; if (!empty($attachments)) { foreach ($attachments as $dataToDelete) { $deleteSuccess = $dataToDelete->delete(); if (!$deleteSuccess) { $errorFrom .= "{$this->tableName()} -> {$dataToDelete->tableName()} -> {$dataToDelete->id}\n"; break; } } } } if ($deleteSuccess) { $userRegulations = $this->userRegulations; if (!empty($userRegulations)) { foreach ($userRegulations as $dataToDelete) { $deleteSuccess = $dataToDelete->delete(); if (!$deleteSuccess) { $errorFrom .= "{$this->tableName()} -> {$dataToDelete->tableName()} -> {$dataToDelete->id}\n"; break; } } } } if ($deleteSuccess) { $change_history_ids = $this->getChangeHistory()->select('id')->column(); $change_history_class_ids = ChangeHistoryEntityClass::find()->where(['change_id' => $change_history_ids])->select('id')->column(); $change_history_class_input_ids = ChangeHistoryEntityClassInput::find()->where(['entity_class_id' => $change_history_class_ids])->select('id')->column(); ChangeHistoryEntityClassInput::deleteAll(['id' => $change_history_class_input_ids]); ChangeHistoryEntityClass::deleteAll(['id' => $change_history_class_ids]); ChangeHistory::deleteAll(['id' => $change_history_ids]); } if ($deleteSuccess) { $transaction->commit(); } else { Yii::error("Ошибка при удалении данных с портала. В таблице: {$errorFrom}"); $transaction->rollBack(); } } catch (\Throwable $e) { $transaction->rollBack(); Yii::error("Ошибка при удалении данных с портала. " . $e->getMessage()); return false; } return $deleteSuccess; } public function getValidatedName(): string { return Yii::t( 'abiturient/bachelor/questionary/abiturient-questionary', 'Валидационное имя; формы "Анкеты": `Анкета`' ); } public function afterValidate() { (new LoggingAfterValidateHandler()) ->setModel($this) ->invoke(); } public function getClassTypeForChangeHistory(): int { return ChangeHistoryClasses::CLASS_ABITURIENT_QUESTIONARY; } public function getChangeLoggedAttributes() { return ['userRef' => function (AbiturientQuestionary $model) { return ArrayHelper::getValue($model, 'user.userRef.reference_id'); }]; } public function getEntityChangeType(): int { return ChangeHistory::CHANGE_HISTORY_TYPE_DEFAULT; } public function getOldClass(): ChangeLoggedModelInterface { return $this; } public function getEntityIdentifier(): ?string { return $this->user->getFullName(); } public function getChangeHistoryHandler(): ?ChangeHistoryHandlerInterface { return null; } public function setChangeHistoryHandler(ChangeHistoryHandlerInterface $handler) { return null; } public function getLinkedBachelorApplication(): ActiveQuery { return $this->hasOne(BachelorApplication::class, ['id' => 'application_id']) ->viaTable( '{{%application_and_questionary_junction}}', ['questionary_id' => 'id'] ); } public function getUserRegulations(): ActiveQuery { return $this->hasMany(UserRegulation::class, ['abiturient_questionary_id' => 'id']); } public function isNotFilled() { return $this->draft_status == IDraftable::DRAFT_STATUS_CREATED && $this->status == AbiturientQuestionary::STATUS_CREATED; } public function getNotFilledRequiredCommonAttachmentTypeIds(): array { return Attachment::getNotFilledRequiredAttachmentTypeIds( $this->getAttachments()->with(['attachmentType'])->all(), AttachmentType::GetRequiredCommonAttachmentTypeIds([AttachmentType::RELATED_ENTITY_REGISTRATION, AttachmentType::RELATED_ENTITY_QUESTIONARY]) ); } public function getSpecificEntitiesFilesInfo(): array { return [ ...$this->getPassportFilesInfo(), ]; } public function getPassportFilesInfo(): array { $files = []; $passports = $this->passportData; foreach ($passports as $passport) { $files = [...$files, ...$passport->getAttachedFilesInfo()]; } return $files; } public function isRequiredCommonFilesAttached(): bool { return !$this->getNotFilledRequiredCommonAttachmentTypeIds(); } public function getOnePassportWithoutFile(): ?PassportData { $passports_with_empty_files = AttachmentManager::GetEntityWithEmptyFilesQuery(PassportData::instance()) ->andWhere([PassportData::tableName() . '.questionary_id' => $this->id]) ->all(); foreach ($passports_with_empty_files as $passport) { if ($passport->getAttachmentCollection()->isRequired()) { return $passport; } } return null; } public function isPassportsRequiredFilesAttached(): bool { return is_null($this->onePassportWithoutFile); } public function isPreviousPassportsFilled(): bool { if ($this->have_no_previous_passport) { return true; } $passports = $this->passportData; if (count($passports) == 1) { $age_with_penalty_in_days = $this->personalData->age * 365 - 100; if ($age_with_penalty_in_days > 365 * 20) { return false; } $passport = $passports[0]; if ($passport->isNotRegularIssueDate()) { return false; } } return true; } public function translateDraftStatus(): string { switch ($this->draft_status) { case IDraftable::DRAFT_STATUS_CREATED: return Yii::$app->configurationManager->getText('draft_status_questionary_preparing'); case IDraftable::DRAFT_STATUS_SENT: return Yii::$app->configurationManager->getText('draft_status_questionary_sent'); case IDraftable::DRAFT_STATUS_MODERATING: return Yii::$app->configurationManager->getText('draft_status_questionary_moderating'); case IDraftable::DRAFT_STATUS_APPROVED: return Yii::$app->configurationManager->getText('draft_status_questionary_clean_copy'); } throw new UserException("Не известный статус черновика"); } public function getRelationsInfo(): array { return [ new OneToOneRelationPresenter('personalData', [ 'parent_instance' => $this, 'child_class' => PersonalData::class, 'child_column_name' => 'questionary_id', ]), new OneToManyRelationPresenter('passportData', [ 'parent_instance' => $this, 'child_class' => PassportData::class, 'child_column_name' => 'questionary_id', ]), new OneToOneRelationPresenter('addressData', [ 'parent_instance' => $this, 'child_class' => AddressData::class, 'child_column_name' => 'questionary_id', ]), new OneToOneRelationPresenter('actualAddressData', [ 'parent_instance' => $this, 'child_class' => ActualAddressData::class, 'child_column_name' => 'questionary_id', ]), new OneToManyRelationPresenter('parentData', [ 'parent_instance' => $this, 'child_class' => ParentData::class, 'child_column_name' => 'questionary_id', ]), new AttachmentsRelationPresenter('attachments', [ 'parent_instance' => $this, ]), new OneToManyRelationPresenter('changeHistory', [ 'parent_instance' => $this, 'child_class' => ChangeHistory::class, 'child_column_name' => 'questionary_id', 'actual_relation_name' => 'changeHistoryOrderedById', 'ignore_in_comparison' => true, 'find_exists_child' => false, 'make_new_child' => true, ]), new OneToManyRelationPresenter('user_regulations', [ 'parent_instance' => $this, 'child_class' => UserRegulation::class, 'child_column_name' => 'abiturient_questionary_id', 'actual_relation_name' => 'userRegulations', ]) ]; } public function hasApprovedAppsQuery(): ActiveQuery { $tnModerateHistory = ModerateHistory::tableName(); $tnBachelorApplication = BachelorApplication::tableName(); $tnAbiturientQuestionary = AbiturientQuestionary::tableName(); $approvedAppsUserIdQuery = BachelorApplication::find() ->active() ->select("{$tnBachelorApplication}.user_id") ->joinWith('moderateHistory') ->andWhere(['IN', "{$tnBachelorApplication}.user_id", $this->user_id]) ->andWhere([ 'or', ["{$tnModerateHistory}.status" => BachelorApplication::STATUS_APPROVED], ["{$tnBachelorApplication}.status" => BachelorApplication::STATUS_APPROVED], ]); return AbiturientQuestionary::find() ->active() ->andWhere(['NOT IN', "{$tnAbiturientQuestionary}.id", [null, 0]]) ->andWhere(['IN', "{$tnAbiturientQuestionary}.user_id", $approvedAppsUserIdQuery]) ->andWhere(['=', "{$tnAbiturientQuestionary}.draft_status", IDraftable::DRAFT_STATUS_APPROVED]); } public function hasApprovedApps(): bool { return $this->hasApprovedAppsQuery()->exists(); } public function hasPassedApplicationWithEditableAttachments(): bool { $tnAttachmentType = AttachmentType::tableName(); $attachmentQurtyArray = [ 'and', ["{$tnAttachmentType}.hidden" => false], [ 'IN', "{$tnAttachmentType}.related_entity", [ AttachmentType::RELATED_ENTITY_QUESTIONARY, AttachmentType::RELATED_ENTITY_REGISTRATION, ] ], [ 'or', ["{$tnAttachmentType}.allow_delete_file_after_app_approve" => true], ["{$tnAttachmentType}.allow_add_new_file_after_app_approve" => true], ], ]; return AttachmentType::find() ->andWhere($attachmentQurtyArray) ->andWhere([ 'IS NOT', $this ->hasApprovedAppsQuery() ->select('id') ->limit(1), null ]) ->andWhere(["{$tnAttachmentType}.admission_campaign_ref_id" => null]) ->exists(); } public function getEntityForDuplicatesFind(): EntityForDuplicatesFind { $passports = ArrayHelper::getValue($this, 'passportData', []); $passport_data = []; foreach ($passports as $passport) { $passport_data[] = [ 'type' => $passport->documentType, 'number' => (string)$passport->number, 'series' => (string)$passport->series, ]; } return new EntityForDuplicatesFind( (string)ArrayHelper::getValue($this, 'personalData.firstname'), (string)ArrayHelper::getValue($this, 'personalData.lastname'), (string)ArrayHelper::getValue($this, 'personalData.middlename'), (string)ArrayHelper::getValue($this, 'personalData.formated_birthdate'), (string)ArrayHelper::getValue($this, 'personalData.snils'), $passport_data ); } public function attachFile(IReceivedFile $receivingFile, DocumentType $documentType): ?File { $attachmentTypeIds = AttachmentType::find() ->joinWith(['documentType document_type']) ->andWhere([ 'document_type.ref_key' => $documentType->ref_key, 'attachment_type.hidden' => false, ]) ->select(['attachment_type.id']) ->column(); if (!$attachmentTypeIds) { return null; } $file = null; $file = $this->questionaryFileAttacher->attachFileToQuestionaryAttachments($receivingFile, $attachmentTypeIds, $file); $file = $this->questionaryFileAttacher->attachFileToQuestionaryRegulations($receivingFile, $attachmentTypeIds, $file); return $this->questionaryFileAttacher->attachFileToUserRegulations($receivingFile, $attachmentTypeIds, $file); } public function removeNotPassedFiles(array $file_ids_to_ignore) { $questionary = $this; $ignored_questionary_attachment_ids = Attachment::find() ->select(['MAX(attachment.id) id']) ->joinWith('attachmentType') ->joinWith(['linkedFile linked_file']) ->andWhere(['attachment.id' => (new Query())->from(['a' => $questionary->getAttachments()])->select('a.id')]) ->andWhere(['linked_file.id' => $file_ids_to_ignore]) ->groupBy(['linked_file.id', 'attachment_type.id']); $attachments_to_delete = $questionary->getAttachments() ->joinWith(['linkedFile linked_file']) ->andWhere(['NOT', ['attachment.id' => $ignored_questionary_attachment_ids]]) ->all(); foreach ($attachments_to_delete as $attachment_to_delete) { $attachment_to_delete->silenceSafeDelete(); } } public function getAttachedFilesInfo(): array { return $this->getAdditionalAttachmentsInfo(); } public function getAdditionalAttachmentsInfo(): array { $files = []; $attachments = $this->attachments; foreach ($attachments as $attachment) { $files[] = [ $attachment, ArrayHelper::getValue($attachment, 'attachmentType.documentType'), ArrayHelper::getValue($attachment, 'attachmentType.name') ]; } return $files; } }