Migrate backend to Porto architecture and fix minor bugs
- Fully transitioned the backend to the Porto architectural pattern - Improved code organization and maintainability - Fixed minor bugs and inconsistencies
This commit is contained in:
@@ -0,0 +1,45 @@
|
||||
<?php
|
||||
|
||||
namespace App\Containers\Education\Enums;
|
||||
|
||||
use Filament\Support\Contracts\HasLabel;
|
||||
use Filament\Support\Contracts\HasColor;
|
||||
|
||||
enum TypeExam: int implements HasLabel, HasColor
|
||||
{
|
||||
case EGE = 1;
|
||||
case INTERNAL_EXAM = 2;
|
||||
case AVG_SCORE = 3;
|
||||
case ACCREDITATION = 4;
|
||||
|
||||
public function getLabel(): ?string
|
||||
{
|
||||
return match ($this) {
|
||||
self::EGE => 'ЕГЭ',
|
||||
self::INTERNAL_EXAM => 'ВИ, проводимое организацией самостоятельно',
|
||||
self::AVG_SCORE => 'Ср. балл документа об образовании',
|
||||
self::ACCREDITATION => 'Аккредитация',
|
||||
};
|
||||
}
|
||||
|
||||
public function getColor(): string|array|null
|
||||
{
|
||||
return match ($this) {
|
||||
self::EGE => 'primary',
|
||||
self::INTERNAL_EXAM => 'info',
|
||||
self::AVG_SCORE => 'success',
|
||||
self::ACCREDITATION => 'warning',
|
||||
};
|
||||
}
|
||||
|
||||
public static function fromName(string $name): ?self
|
||||
{
|
||||
return match ($name) {
|
||||
'EGE' => self::EGE,
|
||||
'INTERNAL_EXAM' => self::INTERNAL_EXAM,
|
||||
'AVG_SCORE' => self::AVG_SCORE,
|
||||
'ACCREDITATION' => self::ACCREDITATION,
|
||||
default => null,
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
<?php
|
||||
|
||||
namespace App\Containers\Education\Loaders;
|
||||
|
||||
class AliasesLoader
|
||||
{
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
public array $aliases = [];
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
<?php
|
||||
|
||||
namespace App\Containers\Education\Loaders;
|
||||
|
||||
class MiddlewareLoader
|
||||
{
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
public array $middleware = [];
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
public array $middlewareGroups = [];
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
public array $routeMiddleware = [];
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
public array $middlewarePriority = [];
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
<?php
|
||||
|
||||
namespace App\Containers\Education\Loaders;
|
||||
|
||||
class ProvidersLoader
|
||||
{
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
public array $providers = [];
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
<?php
|
||||
|
||||
namespace App\Containers\Education\Models;
|
||||
|
||||
use App\Ship\Models\Model;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Relations\HasMany;
|
||||
use Illuminate\Database\Eloquent\Relations\HasManyThrough;
|
||||
|
||||
class AdmissionCampaign extends Model
|
||||
{
|
||||
use HasFactory;
|
||||
|
||||
protected $guarded = false;
|
||||
|
||||
protected $casts = [
|
||||
'info' => 'array'
|
||||
];
|
||||
|
||||
public function admission_plans(): HasMany
|
||||
{
|
||||
return $this->hasMany(AdmissionPlan::class, 'admission_campaigns_id', 'id');
|
||||
}
|
||||
|
||||
public function educationalPrograms(): HasManyThrough
|
||||
{
|
||||
return $this->hasManyThrough(
|
||||
EducationalProgram::class,
|
||||
AdmissionPlan::class,
|
||||
'admission_campaigns_id', // внешний ключ в AdmissionPlan
|
||||
'id', // внешний ключ в EducationalPrograms
|
||||
'id', // локальный ключ в AdmissionCampaign
|
||||
'educational_programs_id' // локальный ключ в AdmissionPlan
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
<?php
|
||||
|
||||
namespace App\Containers\Education\Models;
|
||||
|
||||
use App\Ship\Models\Model;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
|
||||
class AdmissionPlan extends Model
|
||||
{
|
||||
use HasFactory;
|
||||
|
||||
protected $guarded = false;
|
||||
|
||||
protected $casts = [
|
||||
'exams' => 'array',
|
||||
'contests' => 'array'
|
||||
];
|
||||
|
||||
public function educationalProgram(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(EducationalProgram::class, 'educational_programs_id', 'id');
|
||||
}
|
||||
|
||||
public function admissionCampaign(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(AdmissionCampaign::class, 'admission_campaigns_id', 'id');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
<?php
|
||||
|
||||
namespace App\Containers\Education\Models;
|
||||
|
||||
use App\Ship\Enums\Education\LevelEducational;
|
||||
use App\Ship\Models\Model;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Relations\HasMany;
|
||||
|
||||
|
||||
class DirectionStudy extends Model
|
||||
{
|
||||
use HasFactory;
|
||||
|
||||
protected $guarded = false;
|
||||
|
||||
protected $casts = [
|
||||
'lvl_edu' => LevelEducational::class,
|
||||
];
|
||||
|
||||
public function programs(): HasMany
|
||||
{
|
||||
return $this->hasMany(EducationalProgram::class);
|
||||
}
|
||||
|
||||
public function scopeWithActivePrograms(Builder $query): Builder
|
||||
{
|
||||
return $query->with(['programs' => function ($query) {
|
||||
$query->whereHas('admission_plans.admissionCampaign', function ($q) {
|
||||
$q->where('status', 1);
|
||||
});
|
||||
}]);
|
||||
}
|
||||
|
||||
public function scopeWithActiveAdmissionCampaign(Builder $query): Builder
|
||||
{
|
||||
return $query->whereHas('programs.admission_plans.admissionCampaign', function ($q) {
|
||||
$q->where('status', 1);
|
||||
});
|
||||
}
|
||||
|
||||
public function scopeWithAdmissionCampaignByYear(Builder $query, string $year): Builder
|
||||
{
|
||||
return $query->whereHas('programs.admission_plans.admissionCampaign', function ($q) use ($year) {
|
||||
$q->where('status', 1)->where('academic_year', $year);
|
||||
});
|
||||
}
|
||||
|
||||
public function scopeForBachelorLevel(Builder $query): Builder
|
||||
{
|
||||
return $query->where('lvl_edu', LevelEducational::BACHELOR);
|
||||
}
|
||||
|
||||
public function scopeForMiddleLevel(Builder $query): Builder
|
||||
{
|
||||
return $query->whereIn('lvl_edu', [LevelEducational::MIDDLE_LEVEL_SPECIALIST_TRAINING, LevelEducational::PREPARATION_OF_QUALIFIED_WORKERS]);
|
||||
}
|
||||
|
||||
public function scopeForMasterLevel(Builder $query): Builder
|
||||
{
|
||||
return $query->where('lvl_edu', LevelEducational::MASTER);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
<?php
|
||||
|
||||
namespace App\Containers\Education\Models;
|
||||
|
||||
use App\Containers\InstituteStructure\Models\Department;
|
||||
use App\Ship\Enums\Education\LevelEducational;
|
||||
use App\Ship\Models\Model;
|
||||
use App\Ship\Traits\HasSeo;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
|
||||
use Illuminate\Database\Eloquent\Relations\HasMany;
|
||||
|
||||
class EducationalProgram extends Model
|
||||
{
|
||||
use HasFactory, HasSeo;
|
||||
|
||||
protected $guarded = false;
|
||||
|
||||
|
||||
protected $casts = [
|
||||
'program_features' => 'array',
|
||||
'about_program' => 'array',
|
||||
'learning_forms' => 'array',
|
||||
'lvl_edu' => LevelEducational::class,
|
||||
];
|
||||
|
||||
public function directionStudy(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(DirectionStudy::class);
|
||||
}
|
||||
|
||||
public function departments(): BelongsToMany
|
||||
{
|
||||
return $this->belongsToMany(Department::class, 'program_department');
|
||||
}
|
||||
|
||||
|
||||
public function admission_plans(): HasMany
|
||||
{
|
||||
return $this->hasMany(AdmissionPlan::class, 'educational_programs_id', 'id');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,108 @@
|
||||
<?php
|
||||
|
||||
namespace App\Containers\Education\Policies;
|
||||
|
||||
use App\Containers\User\Models\User;
|
||||
use App\Containers\Education\Models\AdmissionCampaign;
|
||||
use Illuminate\Auth\Access\HandlesAuthorization;
|
||||
|
||||
class AdmissionCampaignPolicy
|
||||
{
|
||||
use HandlesAuthorization;
|
||||
|
||||
/**
|
||||
* Determine whether the user can view any models.
|
||||
*/
|
||||
public function viewAny(User $user): bool
|
||||
{
|
||||
return $user->can('view_any_admission::campaign');
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can view the model.
|
||||
*/
|
||||
public function view(User $user, AdmissionCampaign $admissionCampaign): bool
|
||||
{
|
||||
return $user->can('view_admission::campaign');
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can create models.
|
||||
*/
|
||||
public function create(User $user): bool
|
||||
{
|
||||
return $user->can('create_admission::campaign');
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can update the model.
|
||||
*/
|
||||
public function update(User $user, AdmissionCampaign $admissionCampaign): bool
|
||||
{
|
||||
return $user->can('update_admission::campaign');
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can delete the model.
|
||||
*/
|
||||
public function delete(User $user, AdmissionCampaign $admissionCampaign): bool
|
||||
{
|
||||
return $user->can('delete_admission::campaign');
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can bulk delete.
|
||||
*/
|
||||
public function deleteAny(User $user): bool
|
||||
{
|
||||
return $user->can('delete_any_admission::campaign');
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can permanently delete.
|
||||
*/
|
||||
public function forceDelete(User $user, AdmissionCampaign $admissionCampaign): bool
|
||||
{
|
||||
return $user->can('force_delete_admission::campaign');
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can permanently bulk delete.
|
||||
*/
|
||||
public function forceDeleteAny(User $user): bool
|
||||
{
|
||||
return $user->can('force_delete_any_admission::campaign');
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can restore.
|
||||
*/
|
||||
public function restore(User $user, AdmissionCampaign $admissionCampaign): bool
|
||||
{
|
||||
return $user->can('restore_admission::campaign');
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can bulk restore.
|
||||
*/
|
||||
public function restoreAny(User $user): bool
|
||||
{
|
||||
return $user->can('restore_any_admission::campaign');
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can replicate.
|
||||
*/
|
||||
public function replicate(User $user, AdmissionCampaign $admissionCampaign): bool
|
||||
{
|
||||
return $user->can('replicate_admission::campaign');
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can reorder.
|
||||
*/
|
||||
public function reorder(User $user): bool
|
||||
{
|
||||
return $user->can('reorder_admission::campaign');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,108 @@
|
||||
<?php
|
||||
|
||||
namespace App\Containers\Education\Policies;
|
||||
|
||||
use App\Containers\User\Models\User;
|
||||
use App\Containers\Education\Models\AdmissionPlan;
|
||||
use Illuminate\Auth\Access\HandlesAuthorization;
|
||||
|
||||
class AdmissionPlanPolicy
|
||||
{
|
||||
use HandlesAuthorization;
|
||||
|
||||
/**
|
||||
* Determine whether the user can view any models.
|
||||
*/
|
||||
public function viewAny(User $user): bool
|
||||
{
|
||||
return $user->can('view_any_admission::plan');
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can view the model.
|
||||
*/
|
||||
public function view(User $user, AdmissionPlan $admissionPlan): bool
|
||||
{
|
||||
return $user->can('view_admission::plan');
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can create models.
|
||||
*/
|
||||
public function create(User $user): bool
|
||||
{
|
||||
return $user->can('create_admission::plan');
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can update the model.
|
||||
*/
|
||||
public function update(User $user, AdmissionPlan $admissionPlan): bool
|
||||
{
|
||||
return $user->can('update_admission::plan');
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can delete the model.
|
||||
*/
|
||||
public function delete(User $user, AdmissionPlan $admissionPlan): bool
|
||||
{
|
||||
return $user->can('delete_admission::plan');
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can bulk delete.
|
||||
*/
|
||||
public function deleteAny(User $user): bool
|
||||
{
|
||||
return $user->can('delete_any_admission::plan');
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can permanently delete.
|
||||
*/
|
||||
public function forceDelete(User $user, AdmissionPlan $admissionPlan): bool
|
||||
{
|
||||
return $user->can('force_delete_admission::plan');
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can permanently bulk delete.
|
||||
*/
|
||||
public function forceDeleteAny(User $user): bool
|
||||
{
|
||||
return $user->can('force_delete_any_admission::plan');
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can restore.
|
||||
*/
|
||||
public function restore(User $user, AdmissionPlan $admissionPlan): bool
|
||||
{
|
||||
return $user->can('restore_admission::plan');
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can bulk restore.
|
||||
*/
|
||||
public function restoreAny(User $user): bool
|
||||
{
|
||||
return $user->can('restore_any_admission::plan');
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can replicate.
|
||||
*/
|
||||
public function replicate(User $user, AdmissionPlan $admissionPlan): bool
|
||||
{
|
||||
return $user->can('replicate_admission::plan');
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can reorder.
|
||||
*/
|
||||
public function reorder(User $user): bool
|
||||
{
|
||||
return $user->can('reorder_admission::plan');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,108 @@
|
||||
<?php
|
||||
|
||||
namespace App\Containers\Education\Policies;
|
||||
|
||||
use App\Containers\User\Models\User;
|
||||
use App\Containers\Education\Models\DirectionStudy;
|
||||
use Illuminate\Auth\Access\HandlesAuthorization;
|
||||
|
||||
class DirectionStudyPolicy
|
||||
{
|
||||
use HandlesAuthorization;
|
||||
|
||||
/**
|
||||
* Determine whether the user can view any models.
|
||||
*/
|
||||
public function viewAny(User $user): bool
|
||||
{
|
||||
return $user->can('view_any_direction::study');
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can view the model.
|
||||
*/
|
||||
public function view(User $user, DirectionStudy $directionStudy): bool
|
||||
{
|
||||
return $user->can('view_direction::study');
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can create models.
|
||||
*/
|
||||
public function create(User $user): bool
|
||||
{
|
||||
return $user->can('create_direction::study');
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can update the model.
|
||||
*/
|
||||
public function update(User $user, DirectionStudy $directionStudy): bool
|
||||
{
|
||||
return $user->can('update_direction::study');
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can delete the model.
|
||||
*/
|
||||
public function delete(User $user, DirectionStudy $directionStudy): bool
|
||||
{
|
||||
return $user->can('delete_direction::study');
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can bulk delete.
|
||||
*/
|
||||
public function deleteAny(User $user): bool
|
||||
{
|
||||
return $user->can('delete_any_direction::study');
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can permanently delete.
|
||||
*/
|
||||
public function forceDelete(User $user, DirectionStudy $directionStudy): bool
|
||||
{
|
||||
return $user->can('force_delete_direction::study');
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can permanently bulk delete.
|
||||
*/
|
||||
public function forceDeleteAny(User $user): bool
|
||||
{
|
||||
return $user->can('force_delete_any_direction::study');
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can restore.
|
||||
*/
|
||||
public function restore(User $user, DirectionStudy $directionStudy): bool
|
||||
{
|
||||
return $user->can('restore_direction::study');
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can bulk restore.
|
||||
*/
|
||||
public function restoreAny(User $user): bool
|
||||
{
|
||||
return $user->can('restore_any_direction::study');
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can replicate.
|
||||
*/
|
||||
public function replicate(User $user, DirectionStudy $directionStudy): bool
|
||||
{
|
||||
return $user->can('replicate_direction::study');
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can reorder.
|
||||
*/
|
||||
public function reorder(User $user): bool
|
||||
{
|
||||
return $user->can('reorder_direction::study');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,108 @@
|
||||
<?php
|
||||
|
||||
namespace App\Containers\Education\Policies;
|
||||
|
||||
use App\Containers\User\Models\User;
|
||||
use App\Containers\Education\Models\EducationalProgram;
|
||||
use Illuminate\Auth\Access\HandlesAuthorization;
|
||||
|
||||
class EducationalProgramPolicy
|
||||
{
|
||||
use HandlesAuthorization;
|
||||
|
||||
/**
|
||||
* Determine whether the user can view any models.
|
||||
*/
|
||||
public function viewAny(User $user): bool
|
||||
{
|
||||
return $user->can('view_any_educational::program');
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can view the model.
|
||||
*/
|
||||
public function view(User $user, EducationalProgram $educationalProgram): bool
|
||||
{
|
||||
return $user->can('view_educational::program');
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can create models.
|
||||
*/
|
||||
public function create(User $user): bool
|
||||
{
|
||||
return $user->can('create_educational::program');
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can update the model.
|
||||
*/
|
||||
public function update(User $user, EducationalProgram $educationalProgram): bool
|
||||
{
|
||||
return $user->can('update_educational::program');
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can delete the model.
|
||||
*/
|
||||
public function delete(User $user, EducationalProgram $educationalProgram): bool
|
||||
{
|
||||
return $user->can('delete_educational::program');
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can bulk delete.
|
||||
*/
|
||||
public function deleteAny(User $user): bool
|
||||
{
|
||||
return $user->can('delete_any_educational::program');
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can permanently delete.
|
||||
*/
|
||||
public function forceDelete(User $user, EducationalProgram $educationalProgram): bool
|
||||
{
|
||||
return $user->can('force_delete_educational::program');
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can permanently bulk delete.
|
||||
*/
|
||||
public function forceDeleteAny(User $user): bool
|
||||
{
|
||||
return $user->can('force_delete_any_educational::program');
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can restore.
|
||||
*/
|
||||
public function restore(User $user, EducationalProgram $educationalProgram): bool
|
||||
{
|
||||
return $user->can('restore_educational::program');
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can bulk restore.
|
||||
*/
|
||||
public function restoreAny(User $user): bool
|
||||
{
|
||||
return $user->can('restore_any_educational::program');
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can replicate.
|
||||
*/
|
||||
public function replicate(User $user, EducationalProgram $educationalProgram): bool
|
||||
{
|
||||
return $user->can('replicate_educational::program');
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can reorder.
|
||||
*/
|
||||
public function reorder(User $user): bool
|
||||
{
|
||||
return $user->can('reorder_educational::program');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
<?php
|
||||
|
||||
namespace App\Containers\Education\UI\API\Controllers;
|
||||
|
||||
use App\Containers\Education\Models\AdmissionCampaign;
|
||||
use App\Ship\Controllers\Controller;
|
||||
|
||||
class AcademicYearController extends Controller
|
||||
{
|
||||
public function __invoke()
|
||||
{
|
||||
$activeCampaign = AdmissionCampaign::query()->where('status', 1)->firstOrFail();
|
||||
return $activeCampaign->academic_year;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
<?php
|
||||
|
||||
namespace App\Containers\Education\UI\API\Controllers;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Jobs\CreateAdmissionPlan;
|
||||
use App\Jobs\CreateDirectionStudy;
|
||||
use App\Jobs\CreateEducationalProgram;
|
||||
use App\Services\Vicon\EducationalProgram\EducationalProgramService;
|
||||
|
||||
class UpdateAdmissionPlansDataApiController extends Controller
|
||||
{
|
||||
|
||||
public function index()
|
||||
{
|
||||
$this->clearAndCreateAdmissionPlans();
|
||||
return redirect()->route('index');
|
||||
}
|
||||
|
||||
private function clearAndCreateAdmissionPlans() : void
|
||||
{
|
||||
dispatch(new CreateAdmissionPlan());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
<?php
|
||||
|
||||
namespace App\Containers\Education\UI\API\Controllers;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Jobs\CreateDirectionStudy;
|
||||
use App\Jobs\CreateEducationalProgram;
|
||||
use App\Services\Vicon\EducationalProgram\EducationalProgramService;
|
||||
|
||||
class UpdateEduDataApiController extends Controller
|
||||
{
|
||||
|
||||
public function index()
|
||||
{
|
||||
$this->updateOrCreateDirectionStudy();
|
||||
$this->updateOrCreateEducationProgram();
|
||||
return redirect()->route('index');
|
||||
}
|
||||
|
||||
private function updateOrCreateDirectionStudy() : void
|
||||
{
|
||||
dispatch(new CreateDirectionStudy());
|
||||
}
|
||||
private function updateOrCreateEducationProgram() : void
|
||||
{
|
||||
dispatch(new CreateEducationalProgram());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
<?php
|
||||
|
||||
use App\Containers\Education\UI\API\Controllers\AcademicYearController;
|
||||
use App\Containers\Education\UI\API\Controllers\UpdateAdmissionPlansDataApiController;
|
||||
use App\Containers\Education\UI\API\Controllers\UpdateEduDataApiController;
|
||||
use Illuminate\Support\Facades\Route;
|
||||
|
||||
Route::get('/getAcademicYear', AcademicYearController::class)->name('academic.year');
|
||||
|
||||
Route::middleware(['auth', 'superadmin'])->group(function () {
|
||||
Route::get('/get-edu-program-data', [UpdateEduDataApiController::class, 'index']);
|
||||
Route::get('/get-admission-plans-data', [UpdateAdmissionPlansDataApiController::class, 'index']);
|
||||
});
|
||||
@@ -0,0 +1,176 @@
|
||||
<?php
|
||||
|
||||
namespace App\Containers\Education\UI\WEB\Controllers;
|
||||
|
||||
use App\Containers\Education\Models\AdmissionCampaign;
|
||||
use App\Containers\Education\Models\AdmissionPlan;
|
||||
use App\Containers\Education\Models\DirectionStudy;
|
||||
use App\Containers\Education\Models\EducationalProgram;
|
||||
use App\Containers\Education\UI\WEB\Transformers\DirectionStudyResource;
|
||||
use App\Containers\Education\UI\WEB\Transformers\EducationalProgramResource;
|
||||
use App\Ship\Contracts\SeoServiceInterface;
|
||||
use App\Ship\Controllers\Controller;
|
||||
use App\Ship\Enums\CacheKeys;
|
||||
use App\Ship\Enums\Education\BudgetEducation;
|
||||
use App\Ship\Enums\Education\FormEducation;
|
||||
use App\Ship\Enums\Education\LevelEducational;
|
||||
use App\Ship\Requests\Request;
|
||||
use Illuminate\Support\Facades\Cache;
|
||||
use Illuminate\Support\Str;
|
||||
use Inertia\Inertia;
|
||||
|
||||
class ClientProgramController extends Controller
|
||||
{
|
||||
public function __construct(readonly SeoServiceInterface $seoPageProvider){}
|
||||
|
||||
public function index(Request $request): \Inertia\Response
|
||||
{
|
||||
$cacheKey = CacheKeys::EDUCATION_PROGRAMS_PREFIX->value . md5(serialize($request->all()));
|
||||
$cacheKeyLevels = 'education_levels_list';
|
||||
$cacheKeyForms = 'education_forms_list';
|
||||
$cacheKeyBudgets = 'education_budgets_list';
|
||||
$cacheKeySeo = 'education_programs_seo';
|
||||
|
||||
$activeCampaign = Cache::remember(CacheKeys::ADMISSION_CAMPAIGNS_PREFIX->value, now()->addDay(), function () {
|
||||
return AdmissionCampaign::where('status', 1)->first();
|
||||
});
|
||||
|
||||
$levelsEducational = Cache::remember($cacheKeyLevels, now()->addDay(), function () {
|
||||
return EducationalProgram::distinct()->pluck('lvl_edu')
|
||||
->mapWithKeys(fn($level) => [$level->name => $level->getLabel()]);
|
||||
});
|
||||
|
||||
$formsEdu = Cache::remember($cacheKeyForms, now()->addDay(), function () {
|
||||
return AdmissionPlan::distinct()
|
||||
->pluck('contests')
|
||||
->flatten(1)
|
||||
->filter(fn ($item) => isset($item['form_education']))
|
||||
->pluck('form_education')
|
||||
->unique()
|
||||
->map(fn ($item) => FormEducation::tryFrom((int)$item))
|
||||
->filter()
|
||||
->mapWithKeys(fn ($form) => [$form->name => $form->getLabel()]);
|
||||
});
|
||||
|
||||
|
||||
$budgetEdu = Cache::remember($cacheKeyBudgets, now()->addDay(), function () {
|
||||
return AdmissionPlan::distinct()
|
||||
->pluck('contests')
|
||||
->flatten(1)
|
||||
->filter(fn ($item) => isset($item['places']['form_budget']))
|
||||
->pluck('places.form_budget')
|
||||
->unique()
|
||||
->map(fn ($item) => BudgetEducation::tryFrom($item))
|
||||
->filter()
|
||||
->mapWithKeys(fn ($form) => [$form->name => $form->getLabel()]);
|
||||
});
|
||||
|
||||
$seo = Cache::remember($cacheKeySeo, now()->addDay(), function () {
|
||||
return $this->seoPageProvider->getSeoForCurrentPage();
|
||||
});
|
||||
|
||||
$naprs = Cache::remember($cacheKey, now()->addHours(), function () use ($request, $activeCampaign) {
|
||||
return DirectionStudyResource::collection(
|
||||
DirectionStudy::query()
|
||||
->withAdmissionCampaignByYear($activeCampaign->academic_year)
|
||||
->withActivePrograms()
|
||||
// ->with('programs.admission_plans')
|
||||
->when($request->input('level'), fn($q, $level) =>
|
||||
$q->where('lvl_edu', LevelEducational::fromName($level)->value))
|
||||
->when($request->input('form'), fn($q, $form) =>
|
||||
$this->applyFormFilter($q, $form))
|
||||
->when($request->input('budget'), fn($q, $budget) =>
|
||||
$this->applyBudgetFilter($q, $budget))
|
||||
->when($request->input('direction'), fn($q, $slugs) =>
|
||||
is_array($slugs) ? $q->whereIn('slug', $slugs) : $q)
|
||||
->get()
|
||||
);
|
||||
});
|
||||
|
||||
|
||||
$data = [
|
||||
'naprs' => $naprs,
|
||||
'campaignName' => $this->getAdmissionCampaignName(),
|
||||
'levelsEducational' => $levelsEducational,
|
||||
'filters' => [
|
||||
'level_filter' => ['type' => 'level', 'value' => $request->input('level'), 'param' => 'level'],
|
||||
'budget_filter' => ['type' => 'budget', 'value' => $request->input('budget'), 'param' => 'budget'],
|
||||
'formEdu_filter' => ['type' => 'form', 'value' => $request->input('form'), 'param' => 'form'],
|
||||
'direction_filter' => ['type' => 'direction', 'value' => $request->input('direction'), 'param' => 'direction'],
|
||||
],
|
||||
'formsEdu' => $formsEdu,
|
||||
'budgetEdu' => $budgetEdu,
|
||||
'direction_studies' => DirectionStudy::query()
|
||||
->withAdmissionCampaignByYear($activeCampaign->academic_year)
|
||||
->withActivePrograms()
|
||||
->get(),
|
||||
'seo' => $seo
|
||||
];
|
||||
|
||||
return Inertia::render('Client/Programs/Index', $data);
|
||||
}
|
||||
public function show(string $slug): \Inertia\Response
|
||||
{
|
||||
$cacheKeyProgram = CacheKeys::EDUCATION_PROGRAM_PREFIX->value . md5($slug);
|
||||
$cacheKeySeo = CacheKeys::EDUCATION_PROGRAM_PREFIX->value . 'seo_' . md5($slug);
|
||||
$cacheKeyForms = 'education_forms_list';
|
||||
|
||||
$programModel = Cache::remember($cacheKeyProgram, now()->addHours(1), function () use ($slug) {
|
||||
return EducationalProgram::query()
|
||||
->where('slug', $slug)
|
||||
->with(['admission_plans', 'directionStudy', 'seo'])
|
||||
->firstOrFail();
|
||||
});
|
||||
|
||||
$formsEdu = Cache::remember($cacheKeyForms, now()->addDay(), function () {
|
||||
return collect(BudgetEducation::cases())
|
||||
->mapWithKeys(fn($form) => [$form->value => $form->getLabel()]);
|
||||
});
|
||||
|
||||
$seo = Cache::remember($cacheKeySeo, now()->addHours(1), function () use ($programModel) {
|
||||
return $this->seoPageProvider->getSeoForModel($programModel);
|
||||
});
|
||||
|
||||
$program = new EducationalProgramResource($programModel);
|
||||
|
||||
return Inertia::render('Client/Programs/Show', compact('program', 'formsEdu', 'seo'));
|
||||
}
|
||||
|
||||
private function getAdmissionCampaignName(): string
|
||||
{
|
||||
$cacheKey = CacheKeys::EDUCATION_PROGRAM_PREFIX->value . 'active_campaign_name';
|
||||
|
||||
return Cache::remember($cacheKey, now()->addHours(1), function () {
|
||||
$campaign = AdmissionCampaign::query()->where('status', 1)->first();
|
||||
return $campaign->name;
|
||||
});
|
||||
}
|
||||
|
||||
private function applyFormFilter($query, $form)
|
||||
{
|
||||
$formValue = Str::of(FormEducation::fromName($form)->value)->toString();
|
||||
|
||||
$query->whereHas('programs.admission_plans', function ($query) use ($formValue) {
|
||||
$query->whereJsonContains('contests', ['form_education' => $formValue]);
|
||||
})
|
||||
->with(['programs' => function ($query) use ($formValue) {
|
||||
$query->whereHas('admission_plans', function ($q) use ($formValue) {
|
||||
$q->whereJsonContains('contests', ['form_education' => $formValue]);
|
||||
});
|
||||
}]);
|
||||
}
|
||||
|
||||
private function applyBudgetFilter($query, $budget): void
|
||||
{
|
||||
$budgetValue = Str::of(BudgetEducation::fromName($budget)->value)->toString();
|
||||
|
||||
$query->whereHas('programs.admission_plans', function ($query) use ($budgetValue) {
|
||||
$query->where('contests', 'like', '%"form_budget":"'.$budgetValue.'"%');
|
||||
})
|
||||
->with(['programs' => function ($query) use ($budgetValue) {
|
||||
$query->whereHas('admission_plans', function ($query) use ($budgetValue) {
|
||||
$query->where('contests', 'like', '%"form_budget":"'.$budgetValue.'"%');
|
||||
});
|
||||
}]);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
<?php
|
||||
|
||||
use App\Containers\Education\UI\WEB\Controllers\ClientProgramController;
|
||||
use Illuminate\Support\Facades\Route;
|
||||
|
||||
|
||||
Route::middleware('access-check')->group(function () {
|
||||
Route::get('/programs/', [ClientProgramController::class, 'index'])->name('client.program.index');
|
||||
Route::get('/program/{slug}', [ClientProgramController::class, 'show'])->name('client.program.show');
|
||||
});
|
||||
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
<?php
|
||||
|
||||
namespace App\Containers\Education\UI\WEB\Transformers;
|
||||
|
||||
use App\Ship\Resources\JsonResource;
|
||||
|
||||
class DirectionStudyResource extends JsonResource
|
||||
{
|
||||
public function toArray($request): array
|
||||
{
|
||||
return [
|
||||
'id' => $this->id,
|
||||
'name' => $this->name,
|
||||
'code' => $this->code,
|
||||
'programs' => EducationalProgramBasicResource::collection($this->programs),
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
<?php
|
||||
|
||||
namespace App\Containers\Education\UI\WEB\Transformers;
|
||||
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Http\Resources\Json\JsonResource;
|
||||
|
||||
class EducationalProgramBasicResource extends JsonResource
|
||||
{
|
||||
/**
|
||||
* Transform the resource into an array.
|
||||
*
|
||||
* @return array<string, mixed>
|
||||
*/
|
||||
public function toArray(Request $request): array
|
||||
{
|
||||
return [
|
||||
'id' => $this->id,
|
||||
'name' => $this->name,
|
||||
'slug' => $this->slug
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
<?php
|
||||
|
||||
namespace App\Containers\Education\UI\WEB\Transformers;
|
||||
|
||||
use App\Ship\Enums\Education\FormEducation;
|
||||
use App\Ship\Resources\JsonResource;
|
||||
|
||||
class EducationalProgramResource extends JsonResource
|
||||
{
|
||||
|
||||
public function toArray($request): array
|
||||
{
|
||||
return [
|
||||
'id' => $this->id,
|
||||
'name' => $this->name,
|
||||
'about_program' => $this->about_program,
|
||||
'program_features' => $this->program_features,
|
||||
'inner_code' => $this->inner_code,
|
||||
'lvl_edu' => $this->lvl_edu->getLabel(),
|
||||
'status' => $this->status,
|
||||
// 'lang_stud' => $this->lang_stud,
|
||||
'learning_forms' => $this->transformLearningForms($this->learning_forms),
|
||||
'directionStudy' => $this->directionStudy,
|
||||
'admissionPlans' => $this->admission_plans,
|
||||
];
|
||||
}
|
||||
|
||||
private function transformLearningForms(array $learningForms): array
|
||||
{
|
||||
return array_map(function ($form) {
|
||||
$formId = $form['form_id'];
|
||||
$formEnum = FormEducation::from($formId); // Получаем enum по form_id
|
||||
|
||||
return [
|
||||
'form_edu' => $formEnum->getLabel(), // Значение из enum
|
||||
'period_data' => $form['period_data'],
|
||||
];
|
||||
}, $learningForms);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user