portal.mkgtu.ru/common/services/abiturientController/bachelor/AdmissionAgreementService.php

390 lines
14 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\services\abiturientController\bachelor;
use common\commands\command\AddToTimelineCommand;
use common\components\ChangeHistoryManager;
use common\components\configurationManager;
use common\components\exceptions\AdmissionAgreementException;
use common\models\errors\RecordNotValid;
use common\models\User;
use common\modules\abiturient\models\bachelor\AdmissionAgreement;
use common\modules\abiturient\models\bachelor\AgreementDecline;
use common\modules\abiturient\models\bachelor\ApplicationHistory;
use common\modules\abiturient\models\bachelor\BachelorApplication;
use common\modules\abiturient\models\bachelor\BachelorSpeciality;
use common\modules\abiturient\models\bachelor\changeHistory\ChangeHistory;
use common\modules\abiturient\models\bachelor\changeHistory\ChangeHistoryEntityClass;
use common\modules\abiturient\models\File;
use common\modules\abiturient\models\repositories\BachelorSpecialityRepository;
use common\services\abiturientController\bachelor\BachelorService;
use Yii;
use yii\helpers\ArrayHelper;
use yii\web\Request;
use yii\web\UploadedFile;
class AdmissionAgreementService extends BachelorService
{
protected $commandBus;
public function __construct(
Request $request,
configurationManager $configurationManager
) {
$this->request = $request;
$this->configurationManager = $configurationManager;
$this->commandBus = Yii::$app->commandBus;
}
public function checkAgreementAccessibility(BachelorApplication $application, BachelorSpeciality $speciality): array
{
if (
$application->haveAttachedAgreementExcludeNonBudget() &&
!$speciality->isCommercialBasis()
) {
return [
'canEdited' => false,
'consentAddErrors' => Yii::t(
'abiturient/bachelor/admission-agreement/all',
'Текст ошибки дублировании согласия на зачисление, на странице НП: `Невозможно прикрепить согласие, так как в системе уже есть информация о прикрепленном согласии на зачисление.`'
),
];
}
if (!$speciality->canAddAgreements()) {
return [
'canEdited' => false,
'consentAddErrors' => Yii::t(
'abiturient/bachelor/admission-agreement/all',
'Текст ошибки о блокировке согласия на зачисление, на странице НП: `Невозможно прикрепить согласие, так как запрещено редактировать согласие на зачисление.`'
),
];
}
if (!$speciality->checkAgreementConditions()) {
return [
'canEdited' => false,
'consentAddErrors' => Yii::t(
'abiturient/bachelor/admission-agreement/all',
'Текст ошибки о блокировке согласия на зачисление, на странице НП: `Невозможно прикрепить согласие на зачисление для данного основания поступления, обратитесь в приёмную кампанию.`'
),
];
}
return [
'canEdited' => true,
'consentAddErrors' => '',
];
}
protected function uploadAgreement(int $specialityId): ?AdmissionAgreement
{
$admissionAgreement = new AdmissionAgreement();
$admissionAgreement->load($this->request->post());
$admissionAgreement->speciality_id = $specialityId;
$admissionAgreement->setScenario(AdmissionAgreement::SCENARIO_NEW_AGREEMENT);
$admissionAgreement->file = UploadedFile::getInstance($admissionAgreement, 'file');
if (!$admissionAgreement->upload()) {
return null;
}
return $admissionAgreement;
}
protected function copyAgreement(AdmissionAgreement $agreement, BachelorSpeciality $toSpeciality): ?AdmissionAgreement
{
$admissionAgreement = new AdmissionAgreement();
$admissionAgreement->speciality_id = $toSpeciality->id;
$admissionAgreement->setScenario(AdmissionAgreement::SCENARIO_NEW_AGREEMENT);
if (!$admissionAgreement->save()) {
throw new RecordNotValid($admissionAgreement);
}
$admissionAgreement->link('linkedFile', $agreement->linkedFile);
return $admissionAgreement;
}
public function createAgreements(User $user, BachelorApplication $application, BachelorSpeciality $speciality): void
{
$addedAgreements = [];
$transaction = Yii::$app->db->beginTransaction();
try {
if (!$admissionAgreement = $this->uploadAgreement($speciality->id)) {
throw new AdmissionAgreementException("Не удалось создать согласие");
}
$addedAgreements[] = $admissionAgreement;
if (ArrayHelper::getValue($application, 'type.campaign.use_common_agreements', false) && $speciality->isInAgreementConditions()) {
foreach ($this->getSpecialitiesByAgreementConditions($application, $speciality) as $other_spec) {
if (!$other_spec->agreement) {
$addedAgreements[] = $this->copyAgreement($admissionAgreement, $other_spec);
}
}
}
foreach ($addedAgreements as $addedAgreement) {
$addToTimelineCommandConfig = $this->changeAgreementHistoryProcess(
$user,
$application,
$speciality,
$addedAgreement
);
$this->commandBus->handle(new AddToTimelineCommand($addToTimelineCommandConfig));
}
$transaction->commit();
} catch (\Throwable $e) {
$transaction->rollBack();
throw $e;
}
}
public function copyAgreementToAddedSpecialities(BachelorApplication $application, array $added_specialities): void
{
if (!ArrayHelper::getValue($application, 'type.campaign.use_common_agreements', false)) {
return;
}
$conditions = $application->type->campaign->agreementConditions ?? [];
$edu_source_ref_uids = ArrayHelper::getColumn($conditions, 'educationSourceRef.reference_uid');
$existing_spec = $application->getSpecialities()
->innerJoinWith('agreement', true)
->joinWith('speciality.educationSourceRef edu_source_ref', false)
->andWhere(['edu_source_ref.reference_uid' => $edu_source_ref_uids])
->one();
if (!$existing_spec) {
return;
}
foreach ($added_specialities as $added_speciality) {
if ($added_speciality->isInAgreementConditions()) {
$this->copyAgreement($existing_spec->agreement, $added_speciality);
}
}
}
protected function getSpecialitiesByAgreementConditions(BachelorApplication $application, BachelorSpeciality $speciality): array
{
$conditions = $application->type->campaign->agreementConditions ?? [];
$edu_source_ref_uids = ArrayHelper::getColumn($conditions, 'educationSourceRef.reference_uid');
return BachelorSpecialityRepository::GetSpecialitiesByAgreementConditons($speciality, $edu_source_ref_uids)->all();
}
protected function createAgreementDecline(AdmissionAgreement $agreement, File $file): AgreementDecline
{
$agreementDecline = new AgreementDecline();
$agreementDecline->agreement_id = $agreement->id;
$agreementDecline->archive = false;
$agreementDecline->file = $file;
if (!$agreementDecline->upload()) {
Yii::error(
'Ошибки валидации при отзыве согласия согласия' .
($agreement->hasErrors() ? "\nAgreement\n" .
print_r($agreement->errors, true) : '') .
($agreementDecline->hasErrors() ? "\nAgreementDecline\n" .
print_r($agreementDecline->errors, true) : ''),
'AdmissionAgreementService.uploadAgreementDecline'
);
throw new RecordNotValid($agreementDecline);
}
return $agreementDecline;
}
public function declineAgreements(User $user, BachelorApplication $application, AdmissionAgreement $agreement)
{
$agreementsToDecline = [$agreement];
if (ArrayHelper::getValue($application, 'type.campaign.use_common_agreements', false)) {
$agreements = AdmissionAgreement::find()
->innerJoinWith('speciality bachelor_spec', true)
->andWhere([AdmissionAgreement::tableName() . '.archive' => false])
->andWhere(['!=', AdmissionAgreement::tableName() . '.status', AdmissionAgreement::STATUS_MARKED_TO_DELETE])
->andWhere(['!=', AdmissionAgreement::tableName() . '.id', $agreement->id])
->andWhere(['bachelor_spec.application_id' => $application->id])
->all();
foreach ($agreements as $activeAgreement) {
if ($activeAgreement->speciality->isInAgreementConditions()) {
$agreementsToDecline[] = $activeAgreement;
}
}
}
$file = null;
$transaction = Yii::$app->db->beginTransaction();
try {
foreach ($agreementsToDecline as $agreementToDecline) {
if ($agreementToDecline->status === AdmissionAgreement::STATUS_NOTVERIFIED) {
$addToTimelineCommandConfig = $this->changeAgreementDeclineHistoryProcess(
$user,
$application,
$agreementToDecline->speciality,
$agreementToDecline
);
$this->commandBus->handle(new AddToTimelineCommand($addToTimelineCommandConfig));
} elseif ($agreementToDecline->status = AdmissionAgreement::STATUS_VERIFIED) {
if (!$file) {
$tmpDecline = new AgreementDecline();
$tmpDecline->agreement_id = $agreement->id;
$uploaded_file = UploadedFile::getInstance($tmpDecline, 'file');
$file = File::GetOrCreateByTempFile(
$tmpDecline->getPathToStoreFiles(),
$uploaded_file
);
}
$this->createAgreementDecline($agreementToDecline, $file);
if (!$agreementToDecline->makeDeclined()) {
throw new AdmissionAgreementException("Не удалось отозвать согласие");
}
$addToTimelineCommandConfig = $this->changeAgreementDeclineHistoryProcess(
$user,
$application,
$agreementToDecline->speciality,
$agreementToDecline,
);
$this->commandBus->handle(new AddToTimelineCommand($addToTimelineCommandConfig));
}
}
$transaction->commit();
} catch (\Throwable $e) {
$transaction->rollBack();
\Yii::error($e->getMessage(), 'declineAgreements');
throw $e;
}
}
public function changeAgreementHistoryProcess(
User $user,
BachelorApplication $application,
BachelorSpeciality $speciality,
AdmissionAgreement $admissionAgreement
): array {
$application->addApplicationHistory(ApplicationHistory::TYPE_AGREEMENT_CHANGED);
return $this->changeHistoryProcess(
$user,
$application,
$speciality,
$admissionAgreement,
'application_add_consent',
ChangeHistory::CHANGE_HISTORY_NEW_AGREEMENT
);
}
public function changeAgreementDeclineHistoryProcess(
User $user,
BachelorApplication $application,
BachelorSpeciality $speciality,
AdmissionAgreement $admissionAgreement
): array {
$admissionAgreement->archive();
return $this->changeHistoryProcess(
$user,
$application,
$speciality,
$admissionAgreement,
'application_return_consent',
ChangeHistory::CHANGE_HISTORY_AGREEMENT_DECLINE
);
}
private function changeHistoryProcess(
User $user,
BachelorApplication $application,
BachelorSpeciality $speciality,
AdmissionAgreement $admissionAgreement,
string $event,
int $changeHistoryType
): array {
$application->resetStatus();
$change = ChangeHistoryManager::persistChangeForEntity($user, $changeHistoryType);
$change->application_id = $application->id;
if (!$change->save()) {
throw new RecordNotValid($change);
}
$class = ChangeHistoryManager::persistChangeHistoryEntity($admissionAgreement, ChangeHistoryEntityClass::CHANGE_TYPE_INSERT);
$class->setChangeHistory($change);
if (!$class->save()) {
throw new RecordNotValid($class);
}
return [
'category' => 'abiturient',
'event' => $event,
'data' => [
'public_identity' => $user->getPublicIdentity(),
'user_id' => $user->getId(),
'campaign' => $application->type->campaignName,
'speciality' => $speciality->speciality->directionRef->reference_name ?? '',
]
];
}
}