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

1217 lines
43 KiB
PHP
Raw Normal View History

2024-03-28 09:51:45 +03:00
<?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;
}
}