portal.mkgtu.ru/common/modules/abiturient/models/AbiturientQuestionary.php

1217 lines
43 KiB
PHP
Executable File
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php
namespace common\modules\abiturient\models;
use common\components\AddressHelper\AddressHelper;
use common\components\AfterValidateHandler\LoggingAfterValidateHandler;
use common\components\ApplicationSendHandler\FullPacketSendHandler\SerializersForOneS\BaseApplicationPackageBuilder;
use common\components\ApplicationSendHandler\FullPacketSendHandler\SerializersForOneS\FullApplicationPackageBuilder;
use common\components\AttachmentManager;
use common\components\changeHistoryHandler\interfaces\ChangeHistoryHandlerInterface;
use common\components\IndependentQueryManager\IndependentQueryManager;
use common\components\PageRelationManager;
use common\components\ReferenceTypeManager\ReferenceTypeManager;
use common\components\UserReferenceTypeManager\UserReferenceTypeManager;
use common\models\AbiturientAvatar;
use common\models\Attachment;
use common\models\AttachmentType;
use common\models\dictionary\Country;
use common\models\dictionary\DocumentType;
use common\models\EntityForDuplicatesFind;
use common\models\interfaces\ArchiveModelInterface;
use common\models\relation_presenters\AttachmentsRelationPresenter;
use common\models\relation_presenters\OneToManyRelationPresenter;
use common\models\relation_presenters\OneToOneRelationPresenter;
use common\models\repositories\UserRegulationRepository;
use common\models\ToAssocCaster;
use common\models\traits\ArchiveTrait;
use common\models\traits\CheckAbiturientAccessibilityTrait;
use common\models\traits\HtmlPropsEncoder;
use common\models\User;
use common\models\UserRegulation;
use common\modules\abiturient\models\bachelor\ApplicationType;
use common\modules\abiturient\models\bachelor\BachelorApplication;
use common\modules\abiturient\models\bachelor\changeHistory\ChangeHistory;
use common\modules\abiturient\models\bachelor\changeHistory\ChangeHistoryClasses;
use common\modules\abiturient\models\bachelor\changeHistory\ChangeHistoryEntityClass;
use common\modules\abiturient\models\bachelor\changeHistory\ChangeHistoryEntityClassInput;
use common\modules\abiturient\models\bachelor\changeHistory\interfaces\ChangeLoggedModelInterface;
use common\modules\abiturient\models\bachelor\extensions\AbiturientQuestionaryFileAttacher;
use common\modules\abiturient\models\bachelor\ModerateHistory;
use common\modules\abiturient\models\drafts\DraftsManager;
use common\modules\abiturient\models\drafts\IHasRelations;
use common\modules\abiturient\models\interfaces\ICanAttachFile;
use common\modules\abiturient\models\interfaces\IDraftable;
use common\modules\abiturient\models\interfaces\IQuestionnaireValidateModelInterface;
use common\modules\abiturient\models\interfaces\IReceivedFile;
use common\modules\abiturient\models\parentData\ParentData;
use common\modules\abiturient\models\questionary\QuestionarySettings;
use common\modules\abiturient\models\repositories\FileRepository;
use DateTime;
use stdClass;
use Yii;
use yii\base\UserException;
use yii\behaviors\TimestampBehavior;
use yii\db\ActiveQuery;
use yii\db\ActiveRecord;
use yii\db\Query;
use yii\helpers\ArrayHelper;
class AbiturientQuestionary extends ActiveRecord
implements
IQuestionnaireValidateModelInterface,
ChangeLoggedModelInterface,
IDraftable,
ArchiveModelInterface,
IHasRelations,
ICanAttachFile
{
use ArchiveTrait;
use CheckAbiturientAccessibilityTrait;
use HtmlPropsEncoder;
const STATUS_CREATED = 0;
const STATUS_SENT = 1;
const STATUS_APPROVED = 2;
const STATUS_NOT_APPROVED = 3;
const STATUS_REJECTED_BY1C = 4;
const STATUS_CREATE_FROM_1C = 5;
public static function tableName()
{
return '{{%abiturient_questionary}}';
}
public $questionaryFileAttacher;
public function __construct($config = [])
{
parent::__construct($config);
$this->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;
}
}