getRegulationsAndAttachments( $application, AttachmentType::RELATED_ENTITY_EGE, RegulationRelationManager::RELATED_ENTITY_EGE ); } public function postProcessingRegulationsAndAttachments( BachelorApplication $application, array $attachments, array $regulations ): array { $hasChanges = false; if ($application->canEdit()) { [ 'hasError' => $hasError, 'hasChanges' => $hasChanges, ] = EntrantTestManager::proceedEntrantTestFromPost($this->request, $application); if (!$hasError) { [ 'hasChanges' => $hasChangesTmp, 'attachments' => $attachments, 'regulations' => $regulations, ] = parent::postProcessingRegulationsAndAttachments($application, $attachments, $regulations); $hasChanges |= $hasChangesTmp; } } return [ 'hasChanges' => $hasChanges, 'attachments' => $attachments, 'regulations' => $regulations, ]; } public function getNextStep(BachelorApplication $application, string $currentStep = 'ege-result'): string { return parent::getNextStep($application, $currentStep); } public function checkAttachmentFiles( BachelorApplication $application, bool $canEdit, ?string $attachmentTypeRelatedEntity = null ): array { return parent::checkAttachmentFiles( $application, $canEdit, AttachmentType::RELATED_ENTITY_EGE ); } public function defineDisciplineSet(BachelorApplication $application, User $currentUser): array { $hasError = false; $hasChanges = false; $classForAlert = ''; $messageForAlert = ''; if ($application->canEdit()) { $db = EgeResult::getDb(); $transaction = $db->beginTransaction(); try { [ 'hasError' => $hasError, 'messageForAlert' => $messageForAlert ] = $this->writeHistoryChanges($application, $currentUser); if (!$hasError) { $classForAlert = 'alert alert-warning'; $messageForAlert = Yii::$app->configurationManager->getText('no_data_saved_text'); $hasChanges = EgeResult::loadFromPost($application, $this->request->post()); if ($hasChanges) { $application->resetStatus(); $classForAlert = 'alert alert-success'; $messageForAlert = Yii::t( 'abiturient/bachelor/ege/all', 'Сообщение об успешном сохранении набора ВИ; на стр. ВИ: `Набор вступительных испытаний подтвержден.`' ); $transaction->commit(); } else { $transaction->rollBack(); } } else { $classForAlert = 'alert alert-danger'; $messageForAlert = Yii::t( 'abiturient/bachelor/ege/all', 'Сообщение о не удачном заполнении набора ВИ; на стр. ВИ: `Ошибка заполнения актуальных вступительных испытаний. Обратитесь к администратору.`' ); throw new UserException($messageForAlert); } } catch (Throwable $e) { $hasError = true; $transaction->rollBack(); Yii::error( 'Критическая ошибка обработки наборов ВИ.' . PHP_EOL . print_r(['throwable' => $e->getMessage()], true), 'EntrantTestService.defineDisciplineSet' ); throw $e; } } return [ 'hasError' => $hasError, 'classForAlert' => $classForAlert, 'messageForAlert' => $messageForAlert ]; } public function solvedConflict(BachelorApplication $application): void { $deletedIds = []; $egeResults = $application->egeResults; [ 'entranceTestsCollection' => $entranceTestsCollection, 'childrenEntranceTestsCollection' => $childrenEntranceTestsCollection ] = $this->getEntranceTestsCollections($application); foreach ($egeResults as $result) { if (in_array($result->id, $deletedIds)) { continue; } if (!$this->mainDisciplineSolvedConflict($result, $entranceTestsCollection)) { continue; } $this->childrenDisciplineSolvedConflict($result, $childrenEntranceTestsCollection); } } private function mainDisciplineSolvedConflict(EgeResult $result, array $entranceTestsCollection): bool { $isArchived = ArrayHelper::getValue($result, 'cgetDiscipline.archive', true); if (!$isArchived) { return false; } $referenceUid = ArrayHelper::getValue($result, 'cgetDiscipline.reference_uid', ''); $newDisciplineId = ArrayHelper::getValue($entranceTestsCollection, $referenceUid); if (!$newDisciplineId) { $result->delete(); return false; } $result->cget_discipline_id = $newDisciplineId; if (!$result->save()) { throw new RecordNotValid($result); } return true; } private function childrenDisciplineSolvedConflict(EgeResult $result, array $childrenEntranceTestsCollection): bool { $isArchived = ArrayHelper::getValue($result, 'cgetChildDiscipline.archive', true); $referenceUid = ArrayHelper::getValue($result, 'cgetChildDiscipline.reference_uid', ''); if ( !$isArchived || empty($referenceUid) || empty($childrenEntranceTestsCollection) ) { return false; } $newChildDisciplineId = ArrayHelper::getValue($childrenEntranceTestsCollection, $referenceUid); if (!$newChildDisciplineId) { $result->delete(); return false; } $result->cget_child_discipline_id = $newChildDisciplineId; if (!$result->save()) { throw new RecordNotValid($result); } return true; } private function getEntranceTestsCollections(BachelorApplication $application): array { return [ 'entranceTestsCollection' => ArrayHelper::map( $this->getEntranceTestsCollection($application), 'reference_uid', 'id' ), 'childrenEntranceTestsCollection' => ArrayHelper::map( $this->getChildrenEntranceTestsCollection($application), 'reference_uid', 'id' ), ]; } private function getEntranceTestsCollection(BachelorApplication $application): array { $availableSets = $application->getAvailableCgetEntranceTestSetIds(); $cgetEntranceTestTableName = CgetEntranceTest::tableName(); $cgetEntranceTestSetTableName = CgetEntranceTestSet::tableName(); $storedDisciplineReferenceTypeTableName = StoredDisciplineReferenceType::tableName(); $disciplines = StoredDisciplineReferenceType::find() ->select([ "{$storedDisciplineReferenceTypeTableName}.id", "{$storedDisciplineReferenceTypeTableName}.reference_uid" ]) ->leftJoin($cgetEntranceTestTableName, "{$storedDisciplineReferenceTypeTableName}.id = {$cgetEntranceTestTableName}.subject_ref_id") ->leftJoin($cgetEntranceTestSetTableName, "{$cgetEntranceTestTableName}.cget_entrance_test_set_id = {$cgetEntranceTestSetTableName}.id") ->andWhere([ "{$cgetEntranceTestTableName}.archive" => false, "{$cgetEntranceTestSetTableName}.archive" => false, "{$storedDisciplineReferenceTypeTableName}.archive" => false, ]) ->andWhere(['IN', "{$cgetEntranceTestSetTableName}.id", $availableSets]) ->groupBy([ "{$storedDisciplineReferenceTypeTableName}.id", "{$storedDisciplineReferenceTypeTableName}.reference_uid" ]) ->all(); return $disciplines; } private function getChildrenEntranceTestsCollection(BachelorApplication $application): array { $availableSets = $application->getAvailableCgetEntranceTestSetIds(); $cgetChildSubjectTableName = CgetChildSubject::tableName(); $cgetEntranceTestTableName = CgetEntranceTest::tableName(); $cgetEntranceTestSetTableName = CgetEntranceTestSet::tableName(); $storedChildDisciplineReferenceTypeTableName = StoredChildDisciplineReferenceType::tableName(); $disciplines = StoredChildDisciplineReferenceType::find() ->select([ "{$storedChildDisciplineReferenceTypeTableName}.id", "{$storedChildDisciplineReferenceTypeTableName}.reference_uid" ]) ->leftJoin($cgetChildSubjectTableName, "{$storedChildDisciplineReferenceTypeTableName}.id = {$cgetChildSubjectTableName}.child_subject_ref_id") ->leftJoin($cgetEntranceTestTableName, "{$cgetChildSubjectTableName}.cget_entrance_test_id = {$cgetEntranceTestTableName}.id") ->leftJoin($cgetEntranceTestSetTableName, "{$cgetEntranceTestTableName}.cget_entrance_test_set_id = {$cgetEntranceTestSetTableName}.id") ->andWhere([ "{$cgetChildSubjectTableName}.archive" => false, "{$cgetEntranceTestTableName}.archive" => false, "{$cgetEntranceTestSetTableName}.archive" => false, "{$storedChildDisciplineReferenceTypeTableName}.archive" => false, ]) ->andWhere(['IN', "{$cgetEntranceTestSetTableName}.id", $availableSets]) ->groupBy([ "{$storedChildDisciplineReferenceTypeTableName}.id", "{$storedChildDisciplineReferenceTypeTableName}.reference_uid" ]) ->all(); return $disciplines; } protected function writeHistoryChanges(BachelorApplication $application, User $currentUser): array { $hasError = false; $messageForAlert = ''; $change = ChangeHistoryManager::persistChangeForEntity($currentUser, ChangeHistory::CHANGE_HISTORY_EXAM_SET); $change->application_id = $application->id; if (!$change->save()) { $hasError = true; $messageForAlert = Yii::t( 'abiturient/bachelor/ege/all', 'Сообщение о не удачном сохранении изменений; на стр. ВИ: `Ошибка записи истории изменений. Обратитесь к администратору.`' ); Yii::error( 'Ошибка записи истории изменений.' . PHP_EOL . print_r(['errors' => $change->errors], true), 'EntrantTestService.writeHistoryChanges' ); } return [ 'hasError' => $hasError, 'messageForAlert' => $messageForAlert ]; } }