Проведение
This commit is contained in:
@@ -56,55 +56,35 @@ 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');
|
||||
if ($statementResponse->successful() &&
|
||||
$groupsResponse->successful() &&
|
||||
$disciplinesResponse->successful() &&
|
||||
$typesResponse->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,
|
||||
'estimations' => $estimations->json()
|
||||
]);
|
||||
foreach (['/employee', '/teacher'] as $prefix) {
|
||||
$statementResponse = $this->api->get("{$prefix}/statements/{$id}");
|
||||
$groupsResponse = $this->api->get("{$prefix}/groups");
|
||||
$disciplinesResponse = $this->api->get("{$prefix}/disciplines");
|
||||
$typesResponse = $this->api->get("{$prefix}/types");
|
||||
$teachersResponse = $this->api->get("{$prefix}/teachers");
|
||||
$estimationsResponse = $this->api->get("{$prefix}/estimations");
|
||||
|
||||
if (
|
||||
$statementResponse->successful() &&
|
||||
$groupsResponse->successful() &&
|
||||
$disciplinesResponse->successful() &&
|
||||
$typesResponse->successful() &&
|
||||
$teachersResponse->successful() &&
|
||||
$estimationsResponse->successful()
|
||||
) {
|
||||
return view('statements.form', [
|
||||
'statement' => $statementResponse->json(),
|
||||
'groups' => $groupsResponse->json(),
|
||||
'disciplines' => $disciplinesResponse->json(),
|
||||
'types' => $typesResponse->json(),
|
||||
'teachers' => $teachersResponse->json(),
|
||||
'isEdit' => true,
|
||||
'estimations' => $estimationsResponse->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');
|
||||
$typesResponse2 = $this->api->get('/teacher/types');
|
||||
$teachersResponse2 = $this->api->get('/teacher/teachers');
|
||||
|
||||
if ($statementResponse2->successful() &&
|
||||
$groupsResponse2->successful() &&
|
||||
$disciplinesResponse2->successful() &&
|
||||
$typesResponse2->successful() &&
|
||||
$teachersResponse2->successful() &&
|
||||
$estimations2->successful()) {
|
||||
|
||||
return view('statements.form', [
|
||||
'statement' => $statementResponse2->json(),
|
||||
'groups' => $groupsResponse2->json(),
|
||||
'disciplines' => $disciplinesResponse2->json(),
|
||||
'types' => $typesResponse2->json(),
|
||||
'teachers' => $teachersResponse2->json(),
|
||||
'isEdit' => true,
|
||||
'estimations' => $estimations2->json()
|
||||
]);
|
||||
}
|
||||
|
||||
abort($statementResponse->status() ?? $statementResponse2->status() ?? 500);
|
||||
abort(500, 'Не удалось загрузить данные для редактирования ведомости');
|
||||
}
|
||||
|
||||
public function update(Request $request, $id)
|
||||
@@ -126,7 +106,33 @@ class StatementController extends Controller
|
||||
'response' => $response->json()
|
||||
]);
|
||||
|
||||
return back()->withErrors($response->json()['errors'] ?? []);
|
||||
$teacherResponse = $this->api->patch("/teacher/statements/{$id}", $data);
|
||||
|
||||
if ($teacherResponse->successful()) {
|
||||
return redirect()->route('statements.index')
|
||||
->with('success', 'Ведомость успешно обновлена');
|
||||
}
|
||||
|
||||
Log::error('Both employee and teacher API update failed:', [
|
||||
'employee_status' => $response->status(),
|
||||
'employee_response' => $response->json(),
|
||||
'teacher_status' => $teacherResponse->status(),
|
||||
'teacher_response' => $teacherResponse->json()
|
||||
]);
|
||||
|
||||
$errorMessage = 'Ошибка при обновлении ведомости: ';
|
||||
|
||||
if ($teacherResponse->status() === 403 || $response->status() === 403) {
|
||||
$errorMessage = 'Доступ запрещен. У вас недостаточно прав для изменения этой ведомости.';
|
||||
} elseif ($teacherResponse->status() === 404 || $response->status() === 404) {
|
||||
$errorMessage = 'Ведомость не найдена.';
|
||||
} else {
|
||||
$errorMessage .= $teacherResponse->json()['message'] ??
|
||||
$response->json()['message'] ??
|
||||
'Неизвестная ошибка';
|
||||
}
|
||||
|
||||
return back()->with('error', $errorMessage);
|
||||
}
|
||||
|
||||
public function destroy($id)
|
||||
@@ -159,17 +165,18 @@ class StatementController extends Controller
|
||||
{
|
||||
try {
|
||||
$withGrades = $request->input('with_grades', true);
|
||||
$response = $this->api->get("/employee/statements/{$statementId}/pdf", [
|
||||
'with_grades' => $withGrades
|
||||
]);
|
||||
if ($response->successful()) {
|
||||
$content = $response->body();
|
||||
$contentType = $response->header('Content-Type');
|
||||
$contentDisposition = $response->header('Content-Disposition');
|
||||
$endpoints = ["/employee/statements/{$statementId}/pdf", "/teacher/statements/{$statementId}/pdf"];
|
||||
|
||||
return response($content)
|
||||
->header('Content-Type', $contentType)
|
||||
->header('Content-Disposition', $contentDisposition);
|
||||
foreach ($endpoints as $endpoint) {
|
||||
$response = $this->api->get($endpoint, [
|
||||
'with_grades' => $withGrades
|
||||
]);
|
||||
|
||||
if ($response->successful()) {
|
||||
return response($response->body())
|
||||
->header('Content-Type', $response->header('Content-Type'))
|
||||
->header('Content-Disposition', $response->header('Content-Disposition'));
|
||||
}
|
||||
}
|
||||
|
||||
return back()->withErrors($response->json()['error'] ?? 'Ошибка при генерации PDF');
|
||||
@@ -178,23 +185,6 @@ class StatementController extends Controller
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Финализация ведомости
|
||||
*/
|
||||
public function finalize(int $statementId)
|
||||
{
|
||||
try {
|
||||
$response = $this->api->post("/teacher/statements/{$statementId}/finalize");
|
||||
|
||||
if ($response->successful()) {
|
||||
return redirect()->back()->with('success', 'Ведомость успешно финализирована');
|
||||
}
|
||||
|
||||
return back()->withErrors($response->json()['error'] ?? 'Ошибка при финализации ведомости');
|
||||
} catch (\Exception $e) {
|
||||
return back()->withErrors('Ошибка при финализации ведомости: ' . $e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public function myStatements(Request $request)
|
||||
{
|
||||
|
||||
@@ -105,6 +105,8 @@ return [
|
||||
),
|
||||
],
|
||||
|
||||
'api_base_url' => env('API_BASE_URL', 'http://127.0.0.1:8000/api'),
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Maintenance Mode Driver
|
||||
|
||||
@@ -25,8 +25,15 @@
|
||||
.hidden {
|
||||
display: none;
|
||||
}
|
||||
.code-input {
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
.code-input::placeholder {
|
||||
color: rgba(0, 0, 0, 0.3);
|
||||
}
|
||||
</style>
|
||||
@endsection
|
||||
|
||||
@section('content')
|
||||
<div class="container mx-auto px-4 py-8">
|
||||
<div class="bg-white rounded-lg shadow p-6 mb-6">
|
||||
@@ -73,28 +80,65 @@
|
||||
</div>
|
||||
<div></div>
|
||||
</div>
|
||||
<form method="POST" action="{{route('statements.update', ['statement' => $statement['id']])}}">
|
||||
<form method="POST" action="{{route('statements.update', ['statement' => $statement['id']])}}" id="statementForm">
|
||||
@csrf
|
||||
@method('PATCH')
|
||||
|
||||
<!-- Кнопки действий -->
|
||||
<div class="flex space-x-4 mb-8">
|
||||
<button type="submit"
|
||||
onclick="saveAndRefresh(event)"
|
||||
class="px-4 py-2 bg-blue-500 text-white rounded hover:bg-blue-600">
|
||||
Сохранить
|
||||
</button>
|
||||
<button class="px-4 py-2 bg-green-500 text-white rounded hover:bg-green-600">
|
||||
Провести
|
||||
</button>
|
||||
<div class="flex space-x-4 mb-8" id="actionButtons">
|
||||
@if(($statement['status']['id'] ?? 0) != 3)
|
||||
<button type="submit"
|
||||
onclick="saveAndRefresh(event)"
|
||||
class="px-4 py-2 bg-blue-500 text-white rounded hover:bg-blue-600"
|
||||
id="saveButton">
|
||||
Сохранить
|
||||
</button>
|
||||
<button type="button"
|
||||
onclick="initiateFinalization()"
|
||||
class="px-4 py-2 bg-green-500 text-white rounded hover:bg-green-600"
|
||||
id="finalizeButton">
|
||||
Провести
|
||||
</button>
|
||||
@endif
|
||||
|
||||
<a href="{{ route('teacher.statements.generatePdf', ['statementId' => $statement['id'], 'with_grades' => false]) }}"
|
||||
target="_blank"
|
||||
class="px-4 py-2 bg-gray-500 text-white rounded hover:bg-gray-600">
|
||||
Скачать ведомость без оценок
|
||||
</a>
|
||||
|
||||
@if(($statement['status']['id'] ?? 0) == 3)
|
||||
<a href="{{ route('teacher.statements.generatePdf', ['statementId' => $statement['id'], 'with_grades' => true]) }}"
|
||||
target="_blank"
|
||||
class="px-4 py-2 bg-blue-500 text-white rounded hover:bg-blue-600">
|
||||
Скачать ведомость с оценками
|
||||
</a>
|
||||
@endif
|
||||
|
||||
<a href="/statements" class="px-4 py-2 bg-gray-300 text-gray-700 rounded hover:bg-gray-400">
|
||||
Назад
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<!-- Блок для ввода кода подтверждения (изначально скрыт) -->
|
||||
<div id="codeVerificationBlock" class="hidden flex space-x-4 mb-8">
|
||||
<input type="text"
|
||||
id="verificationCode"
|
||||
name="verification_code"
|
||||
placeholder="Код подтверждения"
|
||||
class="code-input px-4 py-2 border rounded focus:outline-none focus:ring-2 focus:ring-green-500">
|
||||
|
||||
<button type="button"
|
||||
onclick="confirmFinalization()"
|
||||
class="px-4 py-2 bg-green-600 text-white rounded hover:bg-green-700">
|
||||
Подтвердить код
|
||||
</button>
|
||||
|
||||
<button type="button"
|
||||
onclick="cancelFinalization()"
|
||||
class="px-4 py-2 bg-gray-500 text-white rounded hover:bg-gray-600">
|
||||
Отмена
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<!-- Таблица студентов -->
|
||||
@@ -117,14 +161,28 @@
|
||||
{{ $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>
|
||||
@if(($statement['status']['id'] ?? 0) != 3)
|
||||
<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)
|
||||
@if($statement['type_certification']['id'] == 1)
|
||||
@if(in_array($estimation['id'], [1, 2, 3]))
|
||||
<option value="{{ $estimation['id'] }}" {{ $student['estimation_name'] == $estimation['name'] ? 'selected' : '' }}>
|
||||
{{ $estimation['name'] }}
|
||||
</option>
|
||||
@endif
|
||||
@else
|
||||
@if(in_array($estimation['id'], [1, 4, 5, 6, 7]))
|
||||
<option value="{{ $estimation['id'] }}" {{ $student['estimation_name'] == $estimation['name'] ? 'selected' : '' }}>
|
||||
{{ $estimation['name'] }}
|
||||
</option>
|
||||
@endif
|
||||
@endif
|
||||
@endforeach
|
||||
</select>
|
||||
@else
|
||||
{{ $student['estimation_name'] ?? 'Не указано' }}
|
||||
@endif
|
||||
</td>
|
||||
</tr>
|
||||
@endforeach
|
||||
@@ -136,12 +194,18 @@
|
||||
</div>
|
||||
<div id="notification" class="notification hidden"></div>
|
||||
<script>
|
||||
function showNotification(message) {
|
||||
function showNotification(message, isError = false) {
|
||||
const notification = document.getElementById('notification');
|
||||
notification.textContent = message;
|
||||
notification.classList.remove('hidden');
|
||||
notification.classList.add('show');
|
||||
|
||||
if (isError) {
|
||||
notification.style.backgroundColor = '#e53e3e'; // red
|
||||
} else {
|
||||
notification.style.backgroundColor = '#48bb78'; // green
|
||||
}
|
||||
|
||||
setTimeout(() => {
|
||||
notification.classList.remove('show');
|
||||
setTimeout(() => {
|
||||
@@ -176,8 +240,93 @@
|
||||
})
|
||||
.catch(error => {
|
||||
console.error('Ошибка:', error);
|
||||
showNotification(error.message);
|
||||
showNotification(error.message, true);
|
||||
});
|
||||
}
|
||||
|
||||
function initiateFinalization() {
|
||||
const allEstimationsFilled = {{ $statement['all_estimations_filled'] ? 'true' : 'false' }};
|
||||
|
||||
if (!allEstimationsFilled) {
|
||||
showNotification('Нельзя провести ведомость: не все оценки выставлены.', true);
|
||||
return;
|
||||
}
|
||||
|
||||
window.apiToken = "{{ session('api_token') }}";
|
||||
window.apiBaseUrl = "{{ config('app.api_base_url') }}";
|
||||
window.userRole = "{{ session('user_role') }}";
|
||||
const rolePath = window.userRole == 2 ? 'teacher' : 'employee';
|
||||
fetch(`${window.apiBaseUrl}/${rolePath}/statements/{{ $statement['id'] }}/send-code`, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Authorization': `Bearer ${window.apiToken}`,
|
||||
'X-CSRF-TOKEN': '{{ csrf_token() }}',
|
||||
'Accept': 'application/json',
|
||||
'Content-Type': 'application/json'
|
||||
}
|
||||
})
|
||||
.then(response => response.json())
|
||||
.then(data => {
|
||||
if (data.error) {
|
||||
throw new Error(data.error);
|
||||
}
|
||||
|
||||
document.getElementById('actionButtons').classList.add('hidden');
|
||||
document.getElementById('codeVerificationBlock').classList.remove('hidden');
|
||||
document.getElementById('verificationCode').focus();
|
||||
|
||||
showNotification(data.message || 'Код подтверждения отправлен на вашу почту');
|
||||
})
|
||||
.catch(error => {
|
||||
console.error('Ошибка:', error);
|
||||
showNotification(error.message, true);
|
||||
});
|
||||
}
|
||||
|
||||
function confirmFinalization() {
|
||||
window.apiToken = "{{ session('api_token') }}";
|
||||
window.apiBaseUrl = "{{ config('app.api_base_url') }}";
|
||||
window.userRole = "{{ session('user_role') }}";
|
||||
const code = document.getElementById('verificationCode').value.trim();
|
||||
|
||||
if (!code) {
|
||||
showNotification('Введите код подтверждения', true);
|
||||
return;
|
||||
}
|
||||
|
||||
const rolePath = window.userRole == 2 ? 'teacher' : 'employee';
|
||||
|
||||
fetch(`${window.apiBaseUrl}/${rolePath}/statements/{{ $statement['id'] }}/verify`, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Authorization': `Bearer ${window.apiToken}`,
|
||||
'X-CSRF-TOKEN': '{{ csrf_token() }}',
|
||||
'Accept': 'application/json',
|
||||
'Content-Type': 'application/json'
|
||||
},
|
||||
body: JSON.stringify({ code: code })
|
||||
})
|
||||
.then(response => response.json())
|
||||
.then(data => {
|
||||
if (data.error) {
|
||||
throw new Error(data.error);
|
||||
}
|
||||
|
||||
showNotification(data.message || 'Ведомость успешно проведена');
|
||||
setTimeout(() => {
|
||||
window.location.reload();
|
||||
}, 1000);
|
||||
})
|
||||
.catch(error => {
|
||||
console.error('Ошибка:', error);
|
||||
showNotification(error.message, true);
|
||||
});
|
||||
}
|
||||
|
||||
function cancelFinalization() {
|
||||
document.getElementById('actionButtons').classList.remove('hidden');
|
||||
document.getElementById('codeVerificationBlock').classList.add('hidden');
|
||||
document.getElementById('verificationCode').value = '';
|
||||
}
|
||||
</script>
|
||||
@endsection
|
||||
|
||||
@@ -41,7 +41,6 @@ Route::middleware(['jwt.auth'])->group(function () {
|
||||
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/{statementId}/pdf', [StatementController::class, 'generatePdf'])->name('teacher.statements.generatePdf');
|
||||
Route::get('/statements/sendFinalizationCode', [StatementController::class, 'finalize'])->name('teacher.statements.sendFinalizationCode');
|
||||
|
||||
// Statistics
|
||||
Route::get('/statistics', [StatisticController::class, 'index'])->name('statistics.index');
|
||||
|
||||
Reference in New Issue
Block a user