portal.mkgtu.ru/common/services/abiturientController/bachelor/entrant_test/EntrantTestService.php

401 lines
13 KiB
PHP
Executable File
Raw 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\services\abiturientController\bachelor\entrant_test;
use common\components\ChangeHistoryManager;
use common\components\EntrantTestManager\EntrantTestManager;
use common\components\RegulationRelationManager;
use common\models\AttachmentType;
use common\models\dictionary\StoredReferenceType\StoredChildDisciplineReferenceType;
use common\models\dictionary\StoredReferenceType\StoredDisciplineReferenceType;
use common\models\errors\RecordNotValid;
use common\models\User;
use common\modules\abiturient\models\bachelor\BachelorApplication;
use common\modules\abiturient\models\bachelor\CgetChildSubject;
use common\modules\abiturient\models\bachelor\CgetEntranceTest;
use common\modules\abiturient\models\bachelor\CgetEntranceTestSet;
use common\modules\abiturient\models\bachelor\changeHistory\ChangeHistory;
use common\modules\abiturient\models\bachelor\EgeResult;
use common\services\abiturientController\bachelor\BachelorService;
use Throwable;
use Yii;
use yii\base\UserException;
use yii\helpers\ArrayHelper;
class EntrantTestService extends BachelorService
{
public function getRegulationsAndAttachmentsForEntrantTest(BachelorApplication $application): array
{
return $this->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
];
}
}