Почти работает генерация ведомости

This commit is contained in:
2025-05-31 22:20:31 +04:00
parent 18b4d060a2
commit 5bfff5eb38
5 changed files with 434 additions and 314 deletions

View File

@@ -3,7 +3,6 @@
namespace App\Http\Controllers;
use App\Services\ApiService;
use Exception;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Log;
@@ -35,7 +34,7 @@ class StatementController extends Controller
$types = $this->api->get('/employee/types')->json();
$teachers = $this->api->get('/employee/teachers')->json();
return view('statements.form', [
return view('statements.create', [
'groups' => $groups,
'disciplines' => $disciplines,
'types' => $types,
@@ -57,29 +56,30 @@ class StatementController extends Controller
public function edit($id)
{
$estimations = $this->api->get("/employee/estimations");
$statementResponse = $this->api->get("/employee/statements/{$id}");
$groupsResponse = $this->api->get('/employee/groups');
$disciplinesResponse = $this->api->get('/employee/disciplines');
$typesResponse = $this->api->get('/employee/types');
$teachersResponse = $this->api->get('/employee/teachers');
// Если employee API успешно ответил
if ($statementResponse->successful() &&
$groupsResponse->successful() &&
$disciplinesResponse->successful() &&
$typesResponse->successful() &&
$teachersResponse->successful()) {
$teachersResponse->successful() &&
$estimations->successful()) {
return view('statements.form', [
'statement' => $statementResponse->json(),
'groups' => $groupsResponse->json(),
'disciplines' => $disciplinesResponse->json(),
'types' => $typesResponse->json(),
'teachers' => $teachersResponse->json(),
'isEdit' => true
'isEdit' => true,
'estimations' => $estimations->json()
]);
}
$estimations2 = $this->api->get("/teacher/estimations");
$statementResponse2 = $this->api->get("/teacher/statements/{$id}");
$groupsResponse2 = $this->api->get('/teacher/groups');
$disciplinesResponse2 = $this->api->get('/teacher/disciplines');
@@ -90,7 +90,8 @@ class StatementController extends Controller
$groupsResponse2->successful() &&
$disciplinesResponse2->successful() &&
$typesResponse2->successful() &&
$teachersResponse2->successful()) {
$teachersResponse2->successful() &&
$estimations2->successful()) {
return view('statements.form', [
'statement' => $statementResponse2->json(),
@@ -98,7 +99,8 @@ class StatementController extends Controller
'disciplines' => $disciplinesResponse2->json(),
'types' => $typesResponse2->json(),
'teachers' => $teachersResponse2->json(),
'isEdit' => true
'isEdit' => true,
'estimations' => $estimations2->json()
]);
}
@@ -110,6 +112,8 @@ class StatementController extends Controller
$data = $request->all();
$data['is_finalized'] = $data['is_finalized'] ?? false;
Log::info('Updating statement data:', $data);
$response = $this->api->patch("/employee/statements/{$id}", $data);
if ($response->successful()) {
@@ -117,6 +121,11 @@ class StatementController extends Controller
->with('success', 'Ведомость успешно обновлена');
}
Log::error('Failed to update statement:', [
'status' => $response->status(),
'response' => $response->json()
]);
return back()->withErrors($response->json()['errors'] ?? []);
}
@@ -196,27 +205,27 @@ class StatementController extends Controller
$apiParams = [
'academic_year' => $request->input('academic_year'),
'discipline_id' => $request->input('discipline_id')
'discipline_id' => $request->input('discipline_id'),
'group_id' => $request->input('group_id')
];
$statementsResponse = $this->api->get('/teacher/statements', $apiParams);
if (!$statementsResponse->successful()) {
throw new \Exception('Failed to load statements');
throw new \Exception('Не удалось загрузить ведомости');
}
$groups = $this->api->get('/employee/groups')->json();
$groupsResponse = $this->api->get('/teacher/groups');
$groups = $groupsResponse->json()['data'] ?? $groupsResponse->json();
return view('teacher.statements.index', [
'statements' => $statementsResponse->json(),
'statements' => $statementsResponse->json()['data'] ?? $statementsResponse->json(),
'disciplines' => $disciplines,
'filters' => $request->only(['academic_year', 'discipline_id']),
'filters' => $request->only(['academic_year', 'discipline_id', 'group_id']),
'groups' => $groups
]);
} catch (\Exception $e) {
Log::error('Ошибка в myStatements: ' . $e->getMessage());
return back()->with('error', $e->getMessage())->withInput();
}
}

View File

@@ -0,0 +1,276 @@
@extends('layouts.app')
@section('content')
<div class="container">
<div class="row justify-content-center">
<div class="col-md-8">
<div class="card">
<div class="card-header">
{{ isset($statement) ? 'Редактирование ведомости' : 'Создание новой ведомости' }}
</div>
<div class="card-body">
<form method="POST" action="{{ isset($statement) ? route('statements.update', $statement['id']) : route('statements.store') }}">
@csrf
@if(isset($statement))
@method('PATCH')
@endif
<div class="row mb-3">
<label for="discipline_id" class="col-md-4 col-form-label text-md-end">Дисциплина*</label>
<div class="col-md-6">
<select id="discipline_id" class="form-control @error('discipline_id') is-invalid @enderror" name="discipline_id" required>
<option value="" disabled {{ old('discipline_id', $statement['discipline']['id'] ?? '') == '' ? 'selected' : '' }}>Выберите дисциплину</option>
@isset($disciplines)
@foreach($disciplines as $discipline)
<option value="{{ $discipline['id'] }}" {{ (old('discipline_id', $statement['discipline']['id'] ?? '') == $discipline['id'] ? 'selected' : '') }}>
{{ $discipline['name'] }}
</option>
@endforeach
@else
<option value="" disabled>Нет доступных дисциплин</option>
@endisset
</select>
@error('discipline_id')
<span class="invalid-feedback" role="alert">
<strong>{{ $message }}</strong>
</span>
@enderror
</div>
</div>
<div class="row mb-3">
<label for="group_id" class="col-md-4 col-form-label text-md-end">Группа*</label>
<div class="col-md-6">
<select id="group_id" class="form-control @error('group_id') is-invalid @enderror" name="group_id" required>
<option value="" disabled {{ old('group_id', $statement['group']['id'] ?? '') == '' ? 'selected' : '' }}>Выберите группу</option>
@isset($groups)
@foreach($groups as $group)
<option value="{{ $group['id'] }}" {{ (old('group_id', $statement['group']['id'] ?? '') == $group['id'] ? 'selected' : '') }}>
{{ $group['name'] }}
</option>
@endforeach
@else
<option value="" disabled>Нет доступных групп</option>
@endisset
</select>
@error('group_id')
<span class="invalid-feedback" role="alert">
<strong>{{ $message }}</strong>
</span>
@enderror
</div>
</div>
<div class="row mb-3">
<label for="teacher_id" class="col-md-4 col-form-label text-md-end">Преподаватель*</label>
<div class="col-md-6">
<select id="teacher_id" name="teacher_id" required class="form-control @error('teacher_id') is-invalid @enderror">
<option value="" disabled {{ empty($statement['teacher']['teacher_id'] ?? null) ? 'selected' : '' }}>
Выберите преподавателя
</option>
@isset($teachers['data'])
@foreach($teachers['data'] as $teacher)
<option value="{{ $teacher['teacher_id'] }}"
{{ ($statement['teacher']['teacher_id'] ?? null) == $teacher['teacher_id'] ? 'selected' : '' }}>
{{ $teacher['surname'] }} {{ $teacher['name'] }} {{ $teacher['patronymic'] }}
</option>
@endforeach
@else
<option value="" disabled>Нет доступных преподавателей</option>
@endisset
</select>
@error('teacher_id')
<span class="invalid-feedback" role="alert">
<strong>{{ $message }}</strong>
</span>
@enderror
</div>
</div>
<div class="row mb-3">
<label for="type_certification_id" class="col-md-4 col-form-label text-md-end">Тип аттестации*</label>
<div class="col-md-6">
<select id="type_certification_id" class="form-control @error('type_certification_id') is-invalid @enderror" name="type_certification_id" required>
<option value="" disabled {{ old('type_certification_id', $statement['type_certification']['id'] ?? '') == '' ? 'selected' : '' }}>Выберите тип</option>
@isset($types)
@foreach($types as $type)
<option value="{{ $type['id'] }}" {{ (old('type_certification_id', $statement['type_certification']['id'] ?? '') == $type['id'] ? 'selected' : '') }}>
{{ $type['name'] }}
</option>
@endforeach
@else
<option value="" disabled>Нет доступных типов</option>
@endisset
</select>
@error('type_certification_id')
<span class="invalid-feedback" role="alert">
<strong>{{ $message }}</strong>
</span>
@enderror
</div>
</div>
<div class="row mb-3">
<label for="semester" class="col-md-4 col-form-label text-md-end">Семестр*</label>
<div class="col-md-6">
<select id="semester" class="form-control @error('semester') is-invalid @enderror" name="semester" required>
<option value="" disabled {{ empty(old('semester', $statement['semester'] ?? '')) ? 'selected' : '' }}>Выберите семестр</option>
@php
$semesters = [
1 => 'Первый семестр',
2 => 'Второй семестр',
3 => 'Третий семестр',
4 => 'Четвертый семестр',
5 => 'Пятый семестр',
6 => 'Шестой семестр',
7 => 'Седьмой семестр',
8 => 'Восьмой семестр',
9 => 'Девятый семестр',
10 => 'Десятый семестр',
11 => 'Одиннадцатый семестр',
12 => 'Двенадцатый семестр'
];
$selected = old('semester', $statement['semester'] ?? '');
@endphp
@foreach($semesters as $number => $name)
<option value="{{ $name }}" {{ $selected == $name ? 'selected' : '' }}>
{{ $name }}
</option>
@endforeach
</select>
@error('semester')
<span class="invalid-feedback" role="alert">
<strong>{{ $message }}</strong>
</span>
@enderror
</div>
</div>
<div class="row mb-3">
<label for="academic_year" class="col-md-4 col-form-label text-md-end">Учебный год*</label>
<div class="col-md-6">
<select id="academic_year" class="form-control @error('academic_year') is-invalid @enderror" name="academic_year" required>
<option value="" disabled {{ empty(old('academic_year', $statement['academic_year'] ?? '')) ? 'selected' : '' }}>Выберите учебный год</option>
@php
$currentYear = date('Y');
$nextYear = $currentYear + 1;
$selectedYear = old('academic_year', $statement['academic_year'] ?? '');
@endphp
@for($i = 0; $i < 10; $i++)
@php
$year = $currentYear - $i;
$next = $year + 1;
$yearRange = "{$year}-{$next}";
@endphp
<option value="{{ $yearRange }}" {{ $selectedYear == $yearRange ? 'selected' : '' }}>
{{ $yearRange }}
@if($i == 0) @endif
</option>
@endfor
</select>
@error('academic_year')
<span class="invalid-feedback" role="alert">
<strong>{{ $message }}</strong>
</span>
@enderror
</div>
</div>
<div class="row mb-3">
<label for="hours" class="col-md-4 col-form-label text-md-end">Часы*</label>
<div class="col-md-6">
<input id="hours" type="text" class="form-control @error('hours') is-invalid @enderror" name="hours" value="{{ old('hours', $statement['hours'] ?? '') }}" required>
@error('hours')
<span class="invalid-feedback" role="alert">
<strong>{{ $message }}</strong>
</span>
@enderror
</div>
</div>
<div class="row mb-3">
<label for="exam_date" class="col-md-4 col-form-label text-md-end">Дата занятия*</label>
<div class="col-md-6">
<input id="exam_date" type="date" class="form-control @error('exam_date') is-invalid @enderror" name="exam_date"
value="{{ old('exam_date', $statement['exam_date'] ?? '') }}"
min="" max="" required>
@error('exam_date')
<span class="invalid-feedback" role="alert">
<strong>{{ $message }}</strong>
</span>
@enderror
<small class="text-muted" id="date-range-info"></small>
</div>
</div>
<div class="row mb-0">
<div class="col-md-6 offset-md-4">
<button type="submit" class="btn btn-primary">
{{ isset($statement) ? 'Обновить' : 'Создать' }}
</button>
<a href="{{ route('statements.index') }}" class="btn btn-secondary">Отмена</a>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
<script>
document.addEventListener('DOMContentLoaded', function() {
const academicYearSelect = document.getElementById('academic_year');
const examDateInput = document.getElementById('exam_date');
const dateRangeInfo = document.getElementById('date-range-info');
const form = document.getElementById('statementForm');
academicYearSelect.addEventListener('change', updateDateRange);
if (academicYearSelect.value) {
updateDateRange();
}
form.addEventListener('submit', function(event) {
if (!validateExamDate()) {
event.preventDefault();
alert('Дата занятия должна быть в пределах выбранного учебного года (с 1 сентября по 30 июня)');
}
});
function updateDateRange() {
const yearRange = academicYearSelect.value;
if (!yearRange) return;
const [startYear, endYear] = yearRange.split('-').map(Number);
const minDate = `${startYear}-09-01`;
const maxDate = `${endYear}-06-30`;
examDateInput.min = minDate;
examDateInput.max = maxDate;
dateRangeInfo.textContent = `Допустимый диапазон: 01.09.${startYear} - 30.06.${endYear}`;
if (examDateInput.value) {
validateExamDate();
}
}
function validateExamDate() {
const examDate = new Date(examDateInput.value);
const minDate = new Date(examDateInput.min);
const maxDate = new Date(examDateInput.max);
if (examDate < minDate || examDate > maxDate) {
examDateInput.classList.add('is-invalid');
return false;
} else {
examDateInput.classList.remove('is-invalid');
return true;
}
}
});
</script>
@endsection

View File

@@ -1,277 +1,110 @@
@extends('layouts.app')
@section('links')
<link href="https://cdn.jsdelivr.net/npm/tailwindcss@2.2.19/dist/tailwind.min.css" rel="stylesheet">
<link href="/resources/css/app.css" rel="stylesheet">
@endsection
@section('content')
<div class="container">
<div class="row justify-content-center">
<div class="col-md-8">
<div class="card">
<div class="card-header">
{{ isset($statement) ? 'Редактирование ведомости' : 'Создание новой ведомости' }}
<div class="container mx-auto px-4 py-8">
<div class="bg-white rounded-lg shadow p-6 mb-6">
<!-- Шапка ведомости -->
<div class="grid grid-cols-3 gap-4 mb-6">
<div>
<span class="font-semibold">Номер ведомости:</span> {{ $statement['id'] ?? 'Не указано' }}
</div>
<div>
<span class="font-semibold">Дата:</span> {{ \Carbon\Carbon::parse($statement['exam_date'])->format('d.m.Y') ?? 'Не указано' }}
</div>
<div>
<span class="font-semibold">Учебный год:</span> {{ $statement['academic_year'] ?? 'Не указано' }}
</div>
</div>
<div class="card-body">
<form method="POST" action="{{ isset($statement) ? route('statements.update', $statement['id']) : route('statements.store') }}">
@csrf
@if(isset($statement))
@method('PATCH')
<div class="grid grid-cols-3 gap-4 mb-6">
<div>
<span class="font-semibold">Дисциплина:</span> {{ $statement['discipline']['name'] ?? 'Не указано' }}
</div>
<div>
<span class="font-semibold">Преподаватель:</span>
{{ $statement['teacher']['surname'] ?? '' }}
{{ $statement['teacher']['name'] ?? '' }}
{{ $statement['teacher']['patronymic'] ?? '' }}
</div>
<div>
<span class="font-semibold">Вид контроля:</span> {{ $statement['type_certification']['name'] ?? 'Не указано' }}
</div>
</div>
<div class="grid grid-cols-3 gap-4 mb-8">
<div>
<span class="font-semibold">Статус:</span>
@if(($statement['status']['id'] ?? 0) == 3)
<span class="px-2 py-1 bg-green-100 text-green-800 rounded-full text-xs">
Проведена
</span>
@else
<span class="px-2 py-1 bg-yellow-100 text-yellow-800 rounded-full text-xs">
Не проведена
</span>
@endif
<div class="row mb-3">
<label for="discipline_id" class="col-md-4 col-form-label text-md-end">Дисциплина*</label>
<div class="col-md-6">
<select id="discipline_id" class="form-control @error('discipline_id') is-invalid @enderror" name="discipline_id" required>
<option value="" disabled {{ old('discipline_id', $statement['discipline']['id'] ?? '') == '' ? 'selected' : '' }}>Выберите дисциплину</option>
@isset($disciplines)
@foreach($disciplines as $discipline)
<option value="{{ $discipline['id'] }}" {{ (old('discipline_id', $statement['discipline']['id'] ?? '') == $discipline['id'] ? 'selected' : '') }}>
{{ $discipline['name'] }}
</option>
@endforeach
@else
<option value="" disabled>Нет доступных дисциплин</option>
@endisset
</select>
@error('discipline_id')
<span class="invalid-feedback" role="alert">
<strong>{{ $message }}</strong>
</span>
@enderror
</div>
<div></div>
</div>
<div class="row mb-3">
<label for="group_id" class="col-md-4 col-form-label text-md-end">Группа*</label>
<div class="col-md-6">
<select id="group_id" class="form-control @error('group_id') is-invalid @enderror" name="group_id" required>
<option value="" disabled {{ old('group_id', $statement['group']['id'] ?? '') == '' ? 'selected' : '' }}>Выберите группу</option>
@isset($groups)
@foreach($groups as $group)
<option value="{{ $group['id'] }}" {{ (old('group_id', $statement['group']['id'] ?? '') == $group['id'] ? 'selected' : '') }}>
{{ $group['name'] }}
</option>
@endforeach
@else
<option value="" disabled>Нет доступных групп</option>
@endisset
</select>
@error('group_id')
<span class="invalid-feedback" role="alert">
<strong>{{ $message }}</strong>
</span>
@enderror
</div>
</div>
<div class="row mb-3">
<label for="teacher_id" class="col-md-4 col-form-label text-md-end">Преподаватель*</label>
<div class="col-md-6">
<select id="teacher_id" name="teacher_id" required class="form-control @error('teacher_id') is-invalid @enderror">
<option value="" disabled {{ empty($statement['teacher']['teacher_id'] ?? null) ? 'selected' : '' }}>
Выберите преподавателя
</option>
@isset($teachers['data'])
@foreach($teachers['data'] as $teacher)
<option value="{{ $teacher['teacher_id'] }}"
{{ ($statement['teacher']['teacher_id'] ?? null) == $teacher['teacher_id'] ? 'selected' : '' }}>
{{ $teacher['surname'] }} {{ $teacher['name'] }} {{ $teacher['patronymic'] }}
</option>
@endforeach
@else
<option value="" disabled>Нет доступных преподавателей</option>
@endisset
</select>
@error('teacher_id')
<span class="invalid-feedback" role="alert">
<strong>{{ $message }}</strong>
</span>
@enderror
</div>
</div>
<div class="row mb-3">
<label for="type_certification_id" class="col-md-4 col-form-label text-md-end">Тип аттестации*</label>
<div class="col-md-6">
<select id="type_certification_id" class="form-control @error('type_certification_id') is-invalid @enderror" name="type_certification_id" required>
<option value="" disabled {{ old('type_certification_id', $statement['type_certification']['id'] ?? '') == '' ? 'selected' : '' }}>Выберите тип</option>
@isset($types)
@foreach($types as $type)
<option value="{{ $type['id'] }}" {{ (old('type_certification_id', $statement['type_certification']['id'] ?? '') == $type['id'] ? 'selected' : '') }}>
{{ $type['name'] }}
</option>
@endforeach
@else
<option value="" disabled>Нет доступных типов</option>
@endisset
</select>
@error('type_certification_id')
<span class="invalid-feedback" role="alert">
<strong>{{ $message }}</strong>
</span>
@enderror
</div>
</div>
<div class="row mb-3">
<label for="semester" class="col-md-4 col-form-label text-md-end">Семестр*</label>
<div class="col-md-6">
<select id="semester" class="form-control @error('semester') is-invalid @enderror" name="semester" required>
<option value="" disabled {{ empty(old('semester', $statement['semester'] ?? '')) ? 'selected' : '' }}>Выберите семестр</option>
@php
$semesters = [
1 => 'Первый семестр',
2 => 'Второй семестр',
3 => 'Третий семестр',
4 => 'Четвертый семестр',
5 => 'Пятый семестр',
6 => 'Шестой семестр',
7 => 'Седьмой семестр',
8 => 'Восьмой семестр',
9 => 'Девятый семестр',
10 => 'Десятый семестр',
11 => 'Одиннадцатый семестр',
12 => 'Двенадцатый семестр'
];
$selected = old('semester', $statement['semester'] ?? '');
@endphp
@foreach($semesters as $number => $name)
<option value="{{ $name }}" {{ $selected == $name ? 'selected' : '' }}>
{{ $name }}
</option>
@endforeach
</select>
@error('semester')
<span class="invalid-feedback" role="alert">
<strong>{{ $message }}</strong>
</span>
@enderror
</div>
</div>
<div class="row mb-3">
<label for="academic_year" class="col-md-4 col-form-label text-md-end">Учебный год*</label>
<div class="col-md-6">
<select id="academic_year" class="form-control @error('academic_year') is-invalid @enderror" name="academic_year" required>
<option value="" disabled {{ empty(old('academic_year', $statement['academic_year'] ?? '')) ? 'selected' : '' }}>Выберите учебный год</option>
@php
$currentYear = date('Y');
$nextYear = $currentYear + 1;
$selectedYear = old('academic_year', $statement['academic_year'] ?? '');
@endphp
@for($i = 0; $i < 10; $i++)
@php
$year = $currentYear - $i;
$next = $year + 1;
$yearRange = "{$year}-{$next}";
@endphp
<option value="{{ $yearRange }}" {{ $selectedYear == $yearRange ? 'selected' : '' }}>
{{ $yearRange }}
@if($i == 0) @endif
</option>
@endfor
</select>
@error('academic_year')
<span class="invalid-feedback" role="alert">
<strong>{{ $message }}</strong>
</span>
@enderror
</div>
</div>
<div class="row mb-3">
<label for="hours" class="col-md-4 col-form-label text-md-end">Часы*</label>
<div class="col-md-6">
<input id="hours" type="text" class="form-control @error('hours') is-invalid @enderror" name="hours" value="{{ old('hours', $statement['hours'] ?? '') }}" required>
@error('hours')
<span class="invalid-feedback" role="alert">
<strong>{{ $message }}</strong>
</span>
@enderror
</div>
</div>
<div class="row mb-3">
<label for="exam_date" class="col-md-4 col-form-label text-md-end">Дата занятия*</label>
<div class="col-md-6">
<input id="exam_date" type="date" class="form-control @error('exam_date') is-invalid @enderror" name="exam_date"
value="{{ old('exam_date', $statement['exam_date'] ?? '') }}"
min="" max="" required>
@error('exam_date')
<span class="invalid-feedback" role="alert">
<strong>{{ $message }}</strong>
</span>
@enderror
<small class="text-muted" id="date-range-info"></small>
</div>
</div>
<div class="row mb-0">
<div class="col-md-6 offset-md-4">
<button type="submit" class="btn btn-primary">
{{ isset($statement) ? 'Обновить' : 'Создать' }}
<form method="POST" action="{{route('statements.update', ['statement' => $statement['id']])}}">
@csrf
@method('PATCH')
<!-- Кнопки действий -->
<div class="flex space-x-4 mb-8">
<button type="submit" class="px-4 py-2 bg-blue-500 text-white rounded hover:bg-blue-600">
Сохранить
</button>
<a href="{{ route('statements.index') }}" class="btn btn-secondary">Отмена</a>
<button class="px-4 py-2 bg-green-500 text-white rounded hover:bg-green-600">
Провести
</button>
<a href="{{ route('teacher.statements.generatePdf', ['statementId' => $statement['id'], 'with_grades' => false]) }}"
class="px-4 py-2 bg-gray-500 text-white rounded hover:bg-gray-600">
Скачать ведомость без оценок
</a>
<a href="{{ url()->previous() }}" class="px-4 py-2 bg-gray-300 text-gray-700 rounded hover:bg-gray-400">
Назад
</a>
</div>
<!-- Таблица студентов -->
<div class="overflow-x-auto">
<table class="min-w-full divide-y divide-gray-200">
<thead class="bg-gray-50">
<tr>
<th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Номер зачетной книжки</th>
<th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Группа</th>
<th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Ф.И.О.</th>
<th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Отметка</th>
</tr>
</thead>
<tbody class="bg-white divide-y divide-gray-200">
@foreach($statement['students'] ?? [] as $student)
<tr>
<td class="px-6 py-4 whitespace-nowrap">{{ $student['matriculation_number'] ?? 'Не указано' }}</td>
<td class="px-6 py-4 whitespace-nowrap">{{ $statement['group']['name'] ?? 'Не указано' }}</td>
<td class="px-6 py-4 whitespace-nowrap">
{{ $student['full_name'] ?? '' }}
</td>
<td class="px-6 py-4 whitespace-nowrap">
<select name="grades[{{ $student['student_profile_id'] }}]" class="border-gray-300 rounded">
<option value="" disabled {{ empty($student['estimation_name']) ? 'selected' : '' }}>Укажите оценку</option>
@foreach($estimations as $estimation)
<option value="{{ $estimation['id'] }}" {{ $student['estimation_name'] == $estimation['name'] ? 'selected' : '' }}>
{{ $estimation['name'] }}
</option>
@endforeach
</select>
</td>
</tr>
@endforeach
</tbody>
</table>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
<script>
document.addEventListener('DOMContentLoaded', function() {
const academicYearSelect = document.getElementById('academic_year');
const examDateInput = document.getElementById('exam_date');
const dateRangeInfo = document.getElementById('date-range-info');
const form = document.getElementById('statementForm');
academicYearSelect.addEventListener('change', updateDateRange);
if (academicYearSelect.value) {
updateDateRange();
}
// Валидация перед отправкой формы
form.addEventListener('submit', function(event) {
if (!validateExamDate()) {
event.preventDefault();
alert('Дата занятия должна быть в пределах выбранного учебного года (с 1 сентября по 30 июня)');
}
});
function updateDateRange() {
const yearRange = academicYearSelect.value;
if (!yearRange) return;
const [startYear, endYear] = yearRange.split('-').map(Number);
const minDate = `${startYear}-09-01`;
const maxDate = `${endYear}-06-30`;
examDateInput.min = minDate;
examDateInput.max = maxDate;
dateRangeInfo.textContent = `Допустимый диапазон: 01.09.${startYear} - 30.06.${endYear}`;
if (examDateInput.value) {
validateExamDate();
}
}
function validateExamDate() {
const examDate = new Date(examDateInput.value);
const minDate = new Date(examDateInput.min);
const maxDate = new Date(examDateInput.max);
if (examDate < minDate || examDate > maxDate) {
examDateInput.classList.add('is-invalid');
return false;
} else {
examDateInput.classList.remove('is-invalid');
return true;
}
}
});
</script>
@endsection

View File

@@ -52,8 +52,12 @@
<select id="group_id" name="group_id" class="mt-1 block w-full rounded-md border-gray-300 shadow-sm">
<option value="">Все группы</option>
@foreach($groups as $group)
<option value="{{ $group }}" {{ request('group_id') == $group ? 'selected' : '' }}>
{{ $group }}
@php
$groupId = is_array($group) ? ($group['id'] ?? $group) : $group;
$groupName = is_array($group) ? ($group['name'] ?? $group) : $group;
@endphp
<option value="{{ $groupId }}" {{ request('group_id') == $groupId ? 'selected' : '' }}>
{{ $groupName }}
</option>
@endforeach
</select>
@@ -64,6 +68,11 @@
Применить фильтры
</button>
</div>
<div class="flex items-end">
<button type="button" class="px-4 py-2 bg-red-500 text-white rounded-md hover:bg-red-600 w-full" id="clearParams">
Стереть фильтры
</button>
</div>
</div>
</form>
</div>
@@ -72,21 +81,24 @@
<div class="bg-white rounded-lg shadow overflow-hidden">
@if(count($statements) > 0)
<div class="table-responsive">
<table class="min-w-full divide-y divide-gray-200">
<table class="min-w-full divide-y divide-gray-200 text-center">
<thead class="bg-gray-50">
<tr>
<th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Дисциплина</th>
<th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Группа</th>
<th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Учебный год</th>
<th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Семестр</th>
<th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Тип аттестации</th>
<th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Статус</th>
<th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider"></th>
<th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider text-center">Номер ведомости</th>
<th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider text-center">Дисциплина</th>
<th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider text-center">Группа</th>
<th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider text-center">Учебный год</th>
<th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider text-center">Семестр</th>
<th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider text-center">Тип аттестации</th>
<th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider text-center">Статус</th>
</tr>
</thead>
<tbody class="bg-white divide-y divide-gray-200">
@foreach($statements as $statement)
<tr class="hover:bg-gray-50">
<td class="px-6 py-4 whitespace-nowrap cursor-pointer" onclick="window.location='{{ route('statements.edit', $statement['id']) }}'">
<div class="text-sm text-gray-500">{{ $statement['id'] }}</div>
</td>
<td class="px-6 py-4 whitespace-nowrap cursor-pointer" onclick="window.location='{{ route('statements.edit', $statement['id']) }}'">
<div class="text-sm font-medium text-gray-900">
{{ $statement['discipline']['name'] }}
@@ -108,7 +120,7 @@
</td>
<td class="px-6 py-4 whitespace-nowrap cursor-pointer" onclick="window.location='{{ route('statements.edit', $statement['id']) }}'">
<div class="text-sm text-gray-500">
@if($statement['is_finalized'])
@if($statement['status']['id'] == 3)
<span class="px-2 py-1 bg-green-100 text-green-800 rounded-full text-xs">
Проведена
</span>
@@ -119,24 +131,6 @@
@endif
</div>
</td>
<td class="px-6 py-4 whitespace-nowrap text-sm font-medium flex justify-end items-center space-x-2">
<a href="{{ route('teacher.statements.generatePdf', ['statementId' => $statement['id'], 'with_grades' => true]) }}"
class="text-blue-500 hover:text-blue-700" title="Скачать с оценками">
<svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 10v6m0 0l-3-3m3 3l3-3m2 8H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z" />
</svg>
</a>
@if(!$statement['is_finalized'])
<form action="{{ route('teacher.statements.sendFinalizationCode', $statement['id']) }}" method="POST" class="inline">
@csrf
<button type="submit" class="text-green-500 hover:text-green-700" title="Завершить ведомость">
<svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 13l4 4L19 7" />
</svg>
</button>
</form>
@endif
</td>
</tr>
@endforeach
</tbody>
@@ -149,4 +143,15 @@
@endif
</div>
</div>
<script>
document.getElementById('clearParams').onclick = function(event) {
event.preventDefault();
const url = new URL(window.location.href);
url.searchParams.delete('academic_year');
url.searchParams.delete('discipline_id');
url.searchParams.delete('group_id');
window.location.href = url.toString();
};
</script>
@endsection

View File

@@ -10,9 +10,7 @@ use App\Http\Controllers\StatisticController;
use App\Http\Controllers\StudentController;
use Illuminate\Support\Facades\Route;
Route::get('/', function () {
return view('welcome');
});
Route::redirect('/', '/login');
Route::controller(AuthController::class)->group(function () {
Route::get('/login', 'showLoginForm')->name('login');
@@ -42,9 +40,8 @@ Route::middleware(['jwt.auth'])->group(function () {
Route::resource('statements', StatementController::class)->except(['show']);
Route::get('/statements/search', [StatementController::class, 'search'])->name('teacher.statements.search');
Route::get('/my/statements', [StatementController::class, 'myStatements'])->name('teacher.statements.index');
Route::get('/statements/pdf', [StatementController::class, 'generatePdf'])->name('teacher.statements.generatePdf');
Route::get('/statements/{statementId}/pdf', [StatementController::class, 'generatePdf'])->name('teacher.statements.generatePdf');
Route::get('/statements/sendFinalizationCode', [StatementController::class, 'finalize'])->name('teacher.statements.sendFinalizationCode');
/* Route::get('/statements/{id}/sendFinalizationCode', [StatementController::class, 'myStatements'])->name('teacher.statements.sendFinalizationCode');*/
// Statistics
Route::get('/statistics', [StatisticController::class, 'index'])->name('statistics.index');