File: /var/www/dvpis2025/dvpis.kaunokolegija.lt/src/Controller/LecturerAgreementController.php
<?php
namespace App\Controller;
use App\Entity\Department;
use App\Entity\Lecturer;
use App\Entity\LecturerAgreement;
use App\Entity\LecturerPosition;
use App\Entity\User;
use App\Form\LecturerAgreementType;
use App\Entity\LecturerAgreementType as LecturerAgreementTypeEntity;
use App\Repository\LecturerAgreementRepository;
use App\Service\FileUploader;
use App\Service\YearInformation;
use Doctrine\DBAL\Exception\UniqueConstraintViolationException;
use Doctrine\ORM\EntityManagerInterface;
use PhpOffice\PhpSpreadsheet\IOFactory;
use PhpOffice\PhpSpreadsheet\Shared\Date;
use PhpOffice\PhpSpreadsheet\Writer\Xls;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Method;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Security;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\ResponseHeaderBag;
use Symfony\Component\HttpFoundation\StreamedResponse;
use Symfony\Component\PasswordHasher\Hasher\UserPasswordHasherInterface;
use Symfony\Component\Routing\Attribute\Route;
/**
* @Security("is_granted('ROLE_PERSONAL_DEPARTMENT')")
*/
#[Route('/lecturer/agreement')]
class LecturerAgreementController extends AbstractController
{
public function __construct(
private readonly EntityManagerInterface $em,
) {
}
#[Route('/new/{id}', name: 'app_lecturer_agreement_new', methods: ['GET', 'POST'])]
public function new(Request $request, EntityManagerInterface $entityManager, Lecturer $lecturer): Response
{
$lecturerAgreement = new LecturerAgreement();
$form = $this->createForm(LecturerAgreementType::class, $lecturerAgreement);
$form->handleRequest($request);
$lecturerAgreement->setLecturer($lecturer);
if ($form->isSubmitted() && $form->isValid()) {
$entityManager->persist($lecturerAgreement);
$entityManager->flush();
return $this->redirectToRoute('lecturer_edit', ['id' => $lecturer->getId()], Response::HTTP_SEE_OTHER);
}
return $this->render('lecturer_agreement/new.html.twig', [
'lecturer_agreement' => $lecturerAgreement,
'lecturer' => $lecturer,
'form' => $form,
]);
}
#[Route('/{id}/edit', name: 'app_lecturer_agreement_edit', methods: ['GET', 'POST'])]
public function edit(Request $request, LecturerAgreement $lecturerAgreement, EntityManagerInterface $entityManager): Response
{
$form = $this->createForm(LecturerAgreementType::class, $lecturerAgreement);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$entityManager->flush();
return $this->redirectToRoute('lecturer_edit', ['id' => $lecturerAgreement->getLecturer()->getId()], Response::HTTP_SEE_OTHER);
}
return $this->render('lecturer_agreement/edit.html.twig', [
'lecturer_agreement' => $lecturerAgreement,
'form' => $form,
]);
}
#[Route('delete/{id}', name: 'app_lecturer_agreement_delete', methods: ['POST'])]
public function delete(Request $request, LecturerAgreement $lecturerAgreement, EntityManagerInterface $entityManager): Response
{
if ($this->isCsrfTokenValid('delete'.$lecturerAgreement->getId(), $request->getPayload()->get('_token'))) {
$entityManager->remove($lecturerAgreement);
$entityManager->flush();
}
return $this->redirectToRoute('lecturer_edit', ['id' => $lecturerAgreement->getLecturer()->getId()], Response::HTTP_SEE_OTHER);
}
#[Route('/import_view', name: 'lecturer_agreement_import_view', methods: ['GET', 'POST'])]
public function showImportLecturerAction(Request $request, FileUploader $fileUploader)
{
$file = $request->files->get('fileToUpload');
$uploadedFilePath = '';
$fileImportReturn = [];
if (!empty($file)) {
$uploadedFilePath = $fileUploader->getTargetDir() . DIRECTORY_SEPARATOR . $fileUploader->upload($file);
$fileImportReturn = $this->importData($uploadedFilePath);
unlink($uploadedFilePath);
}
return $this->render('lecturer_agreement/import.html.twig', [
'uploadedFilePath' => $uploadedFilePath,
'importErrors' => $fileImportReturn,
]);
}
private function importData($filePath)
{
$positions = $this->em->getRepository(LecturerPosition::class)->getAllByName();
$lecturers = $this->em->getRepository(Lecturer::class)->getAllByEmail();
$agreementTypes = $this->em->getRepository(LecturerAgreementTypeEntity::class)->findAll();
$lecturersByID = $this->em->getRepository(Lecturer::class)->getAllByID();
$agreementTypeByCode = [];
foreach ($agreementTypes as $agreementType) {
$agreementTypeByCode[$agreementType->getCode()] = $agreementType;
}
$objExcel = IOFactory::load($filePath);
$worksheet = $objExcel->setActiveSheetIndex(0);
$errors = [];
foreach ($worksheet->getRowIterator() as $row) {
$rowNumber = $row->getRowIndex();
if ($row->getRowIndex() <= 1) {
continue;
}
//insert values
$cellIterator = $row->getCellIterator();
$cellIterator->setIterateOnlyExistingCells(false); // Loop all cells, even if it is not set
$lecturerAgreement = new LecturerAgreement();
foreach ($cellIterator as $cell) {
if (!is_null($cell)) {
$column = $cell->getColumn();
switch ($cell->getColumn()) {
case 'A':/* req */
$excelIndex = trim($cell->getCalculatedValue());
$lecturer = $lecturers[$excelIndex] ?? $lecturersByID[$excelIndex] ?? null;
if (empty($lecturer)) {
$errors[] = $column . $rowNumber . ": Dėstytojas nerastas! (" . $excelIndex . ")";
}
else {
$lecturerAgreement->setLecturer($lecturer);
}
break;
case 'B':/* req */
$excelCode = ucfirst(strtolower(trim($cell->getCalculatedValue())));
if (!isset($positions[$excelCode])) {
$errors[] = $column . $rowNumber . ": Pareigybė nerasta! (" . $excelCode . ")";
} else {
$lecturerAgreement->setLecturerPosition($positions[$excelCode]);
}
break;
case 'C':
$cellValue = trim($cell->getCalculatedValue());
if (empty($cellValue)) {
$lecturerAgreement->setPostSize(null);
} else {
$lecturerAgreement->setPostSize($cellValue);
}
break;
case 'D':
$cellValue = trim($cell->getCalculatedValue());
if (empty($cellValue)) {
$lecturerAgreement->setContractFrom(null);
} else {
$excelDataDate = Date::excelToDateTimeObject($cellValue);
$lecturerAgreement->setContractFrom($excelDataDate);
}
break;
case 'E':
$cellValue = trim($cell->getCalculatedValue());
if (empty($cellValue)) {
$lecturerAgreement->setContractTo(null);
} else {
$excelDataDate = Date::excelToDateTimeObject($cellValue);
$lecturerAgreement->setContractTo($excelDataDate);
}
break;
case 'F':
$cellValue = trim($cell->getCalculatedValue());
$agreementType = $agreementTypeByCode[$cellValue] ?? null;
$lecturerAgreement->setLecturerAgreementType($agreementType);
break;
case 'G':
$cellValue = trim($cell->getCalculatedValue());
if (empty($cellValue)) {
$lecturerAgreement->setNotes(null);
} else {
$lecturerAgreement->setNotes($cellValue);
}
break;
default:
break;
}
}
if (empty($errors)) {
if (empty($valid[0])) {
$this->em->persist($lecturerAgreement);
} else {
$errors[] = $column . $rowNumber . ": " . $valid[0]->getMessage();
}
}
}
}
if (empty($errors)) {
try {
$this->em->flush();
} catch (UniqueConstraintViolationException $ex) {
$errors[] = "Faile yra vienodų naujų įrašų. Prašome patikrinti duomenis! Detaliau: " . $ex->getPrevious()->getMessage();
}
}
return $errors;
}
#[Route(path: '/excel', name: 'lecturer_aggrement_report')]
public function reportExcelAction(Request $request)
{
ini_set('max_execution_time', 60 * 5);
ini_set('max_input_time', 60 * 5);
ini_set('memory_limit', '1024M');
$excelFileName = 'dvpis_destytoju_sutartys-' . date("Y_m_d_H_i_s") . '.xls';
$excelTemplateDir = $this->getParameter('excel_templates_directory');
$excelTemplate = $excelTemplateDir . "/dvpis_destytoju_sutartys.xlsx";
$objExcel = IOFactory::load($excelTemplate);
$worksheet = $objExcel->setActiveSheetIndex(0);
$lecturerAgreements = $this->em->getRepository(LecturerAgreement::class)->findAllForReport();
$rowIndex = 2;
if (!empty($lecturerAgreements)) {
/** @var LecturerAgreement $lecturerAgreement */
foreach ($lecturerAgreements as $lecturerAgreement) {
/** @var Lecturer $lecturer */
$lecturer = $lecturerAgreement->getLecturer();
$worksheet->insertNewRowBefore($rowIndex + 1);
$worksheet->setCellValue('A' . $rowIndex, $lecturerAgreement->getLecturer());
$worksheet->setCellValue('B' . $rowIndex, $lecturerAgreement->getLecturer()->getDepartment());
$worksheet->setCellValue('C' . $rowIndex, $lecturerAgreement->getLecturer()->getEmail());
$worksheet->setCellValue('D' . $rowIndex, $lecturerAgreement->getLecturer()->getScientificDegree());
$worksheet->setCellValue('E' . $rowIndex, $lecturerAgreement->getLecturer()->getEducation());
$worksheet->setCellValue('F' . $rowIndex, $lecturer->isMainWorkplace() ? 'Taip' : 'Ne');
$worksheet->setCellValue('G' . $rowIndex, $lecturerAgreement->getLecturerPosition()->getName());
$worksheet->setCellValue('H' . $rowIndex, $lecturerAgreement->getPostSize());
$worksheet->setCellValue('I' . $rowIndex, $lecturerAgreement->getContractFrom()->format('Y-m-d'));
$worksheet->setCellValue('J' . $rowIndex, $lecturerAgreement->getContractTo()?->format('Y-m-d') ?? '');
$worksheet->setCellValue('K' . $rowIndex, $lecturerAgreement?->getLecturerAgreementType()?->getName() ?? '');
$worksheet->setCellValue('L' . $rowIndex, $lecturer?->getDepartment()?->getAcademicUnit() ?? '');
$worksheet->setCellValue('M' . $rowIndex, $lecturer?->getFieldOfStudy()?->getFieldOfStudyGroup() ?? '');
$worksheet->setCellValue('N' . $rowIndex, $lecturerAgreement->getNotes());
$rowIndex++;
}
}
$writer = new Xls($objExcel);
$response = new StreamedResponse(function () use ($writer) {
$writer->save('php://output');
});
$dispositionHeader = $response->headers->makeDisposition(
ResponseHeaderBag::DISPOSITION_ATTACHMENT,
$excelFileName
);
$response->headers->set('Content-Type', 'text/vnd.ms-excel; charset=utf-8');
$response->headers->set('Pragma', 'public');
$response->headers->set('Cache-Control', 'maxage=0');
$response->headers->set('Content-Disposition', $dispositionHeader);
$response->send();
}
}