<?php
namespace App\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
use App\Entity\Fichaje;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\JsonResponse;
use Doctrine\ORM\EntityManagerInterface;
use DateTime;
use DateTimeImmutable;
use DateInterval;
use Symfony\Component\Security\Core\Security;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\IsGranted;
class FichajeController extends AbstractController
{
private $entityManager;
private $security;
public function __construct(EntityManagerInterface $entityManager, Security $security)
{
$this->entityManager = $entityManager;
$this->security = $security;
}
/**
* @Route("/", name="fichaje")
* @IsGranted("ROLE_USER")
*/
public function index(): Response{
$user = $this->getUser();
if (!$user) {
throw $this->createAccessDeniedException('Debes estar autenticado para acceder a esta página');
}
$username = $user->getUserIdentifier();
$hoy = new DateTime();
$repoFichaje = $this->entityManager->getRepository(Fichaje::class);
$fichajes = $repoFichaje->findAll();
//$fichajesUser = $repoFichaje->findBy(['user' => $username]);
$dataFichajes = array();
//$dataFichajesUser = array();
foreach ($fichajes as $fichaje) {
//calculo de horas totales trabajadas
$arrayHoras = array(
'inicio_am' => $fichaje->getInicioAm() ? $fichaje->getInicioAm()->format('H:i') : null,
'fin_am' => $fichaje->getFinAm() ? $fichaje->getFinAm()->format('H:i') : null,
'inicio_pm' => $fichaje->getInicioPm() ? $fichaje->getInicioPm()->format('H:i') : null,
'fin_pm' => $fichaje->getFinPm() ? $fichaje->getFinPm()->format('H:i') : null,
'inicio_descanso_am' => $fichaje->getInicioDescansoAm() ? $fichaje->getInicioDescansoAm()->format('H:i') : null,
'fin_descanso_am' => $fichaje->getFinDescansoAm() ? $fichaje->getFinDescansoAm()->format('H:i') : null,
'inicio_descanso_pm' => $fichaje->getInicioDescansoPm() ? $fichaje->getInicioDescansoPm()->format('H:i') : null,
'fin_descanso_pm' => $fichaje->getFinDescansoPm() ? $fichaje->getFinDescansoPm()->format('H:i') : null,
);
$totalHorasFichadas = $this->calcularHorasTrabajadas($arrayHoras);
//array temporal
$temp = array(
'id' => $fichaje->getId(),
'user' => $fichaje->getUser(),
'fecha' => $fichaje->getFecha(),
'inicio_am' => $fichaje->getInicioAm() ? $fichaje->getInicioAm()->format('H:i') : null,
'fin_am' => $fichaje->getFinAm() ? $fichaje->getFinAm()->format('H:i') : null,
'inicio_pm' => $fichaje->getInicioPm() ? $fichaje->getInicioPm()->format('H:i') : null,
'fin_pm' => $fichaje->getFinPm() ? $fichaje->getFinPm()->format('H:i') : null,
'inicio_descanso_am' => $fichaje->getInicioDescansoAm() ? $fichaje->getInicioDescansoAm()->format('H:i') : null,
'fin_descanso_am' => $fichaje->getFinDescansoAm() ? $fichaje->getFinDescansoAm()->format('H:i') : null,
'inicio_descanso_pm' => $fichaje->getInicioDescansoPm() ? $fichaje->getInicioDescansoPm()->format('H:i') : null,
'fin_descanso_pm' => $fichaje->getFinDescansoPm() ? $fichaje->getFinDescansoPm()->format('H:i') : null,
'total_horas' => $totalHorasFichadas,
);
//se almacena l'array temporal y si el usuario dentro del fichaje coincide con el usuario se añade en un segundo array
// array_push($dataFichajes, $temp);
// if ($fichaje->getUser() === $username) {
// array_push($dataFichajesUser, $temp);
// }
if ($this->isGranted('ROLE_ADMIN')) {
array_push($dataFichajes, $temp);
} elseif ($this->isGranted('ROLE_USER') && $fichaje->getUser() === $username) {
array_push($dataFichajes, $temp);
}
}
// busca en los fichajes el usuario y fecha actual
$dateFichaje = $repoFichaje->findOneBy(['fecha' => $hoy, 'user' => $username]);
//verifica si hay fichaje por la mañana y por la tarde
$fichajeMannana = ($dateFichaje && $dateFichaje->getInicioAm() !== null) ? true : false;
$fichajeTarde = ($dateFichaje && $dateFichaje->getInicioPm() !== null) ? true : false;
$horaInicioAm = ($dateFichaje && $dateFichaje->getInicioAm() !== null) ? $dateFichaje->getInicioAm() : false;
$horaFinAm = ($dateFichaje && $dateFichaje->getFinAm() !== null) ? $dateFichaje->getFinAm() : false;
$horaInicioPm = ($dateFichaje && $dateFichaje->getInicioPm() !== null) ? $dateFichaje->getInicioPm() : false;
$horaFinPm = ($dateFichaje && $dateFichaje->getFinPm() !== null) ? $dateFichaje->getFinPm() : false;
$horaInicioAmString = $horaInicioAm !== false ? $horaInicioAm->format('H:i') : '';
$horaFinAmString = $horaFinAm !== false ? $horaFinAm->format('H:i') : '';
$horaInicioPmString = $horaInicioPm !== false ? $horaInicioPm->format('H:i') : '';
$horaFinPmString = $horaFinPm !== false ? $horaFinPm->format('H:i') : '';
$horaInicioDescansoAm = ($dateFichaje && $dateFichaje->getInicioDescansoAm() !== null) ? $dateFichaje->getInicioDescansoAm()->format('H:i') : false;
$horaFinDescansoAm = ($dateFichaje && $dateFichaje->getFinDescansoAm() !== null) ? $dateFichaje->getFinDescansoAm()->format('H:i') : false;
$horaInicioDescansoPm = ($dateFichaje && $dateFichaje->getInicioDescansoPm() !== null) ? $dateFichaje->getInicioDescansoPm()->format('H:i') : false;
$horaFinDescansoPm = ($dateFichaje && $dateFichaje->getFinDescansoPm() !== null) ? $dateFichaje->getFinDescansoPm()->format('H:i') : false;
//Si hay fichajes tanto en la mañana como en la tarde, muestra el mensaje
if ($fichajeMannana === true && $fichajeTarde === true) {
$this->addFlash('info', '¡No puedes modificar tu fichaje una vez insertadas las horas!');
}
return $this->render('fichaje/index.html.twig', [
'controller_name' => 'FichajeController',
'fichajeMannana' => $fichajeMannana,
'fichajeTarde' => $fichajeTarde,
'horaInicioAm' => $horaInicioAmString,
'horaFinAm' => $horaFinAmString,
'horaInicioPm' => $horaInicioPmString,
'horaFinPm' => $horaFinPmString,
'fichajes' => $dataFichajes,
//'fichajesUser' => $dataFichajesUser,
'horaInicioDescansoAm' => $horaInicioDescansoAm,
'horaFinDescansoAm' => $horaFinDescansoAm,
'horaInicioDescansoPm' => $horaInicioDescansoPm,
'horaFinDescansoPm' => $horaFinDescansoPm,
]);
}
/**
* @Route("/insertfichaje", name="insert_fichaje")
*/
public function insertFichaje(Request $request)
{
$inicioMannana = $request->request->get('inicioMannana');
$finMannana = $request->request->get('finMannana');
$inicioTarde = $request->request->get('inicioTarde');
$finTarde = $request->request->get('finTarde');
$inicioDescansoAm = $request->request->get('inicioDescansoAm');
$finDescansoAm = $request->request->get('finDescansoAm');
$inicioDescansoPm = $request->request->get('inicioDescansoPm');
$finDescansoPm = $request->request->get('finDescansoPm');
$fecha = new DateTime();
$user = $this->getUser();
if (!$user) {
throw $this->createAccessDeniedException('Debes estar autenticado para realizar esta acción');
}
$username = $user->getUserIdentifier();
$repoFichaje = $this->entityManager->getRepository(Fichaje::class);
$dateFichaje = $repoFichaje->findOneBy(['fecha' => $fecha, 'user' => $username]);
// Verificar si todas las horas están completas
if ($dateFichaje && $dateFichaje->getInicioAm() !== null && $dateFichaje->getFinAm() !== null && $dateFichaje->getInicioPm() !== null && $dateFichaje->getFinPm() !== null) {
$this->addFlash('info', '¡No puedes insertar más fichajes, todas las horas están completas!');
return $this->redirectToRoute('fichaje');
}
if ($dateFichaje) {
if ($dateFichaje->getInicioAm() !== null || $dateFichaje->getFinAm() !== null) {
$dateFichaje->setInicioPm(!empty($inicioTarde) ? new DateTimeImmutable('today ' . $inicioTarde) : null);
$dateFichaje->setFinPm(!empty($finTarde) ? new DateTimeImmutable('today ' . $finTarde) : null);
if (!empty($inicioDescansoAm) && !empty($finDescansoAm)) {
$dateFichaje->setInicioDescansoAm(new DateTimeImmutable('today ' . $inicioDescansoAm));
$dateFichaje->setFinDescansoAm(new DateTimeImmutable('today ' . $finDescansoAm));
}
if (!empty($inicioDescansoPm) && !empty($finDescansoPm)) {
$dateFichaje->setInicioDescansoPm(new DateTimeImmutable('today ' . $inicioDescansoPm));
$dateFichaje->setFinDescansoPm(new DateTimeImmutable('today ' . $finDescansoPm));
}
} else {
$dateFichaje->setInicioAm(new DateTimeImmutable('today ' . $inicioMannana));
$dateFichaje->setFinAm(new DateTimeImmutable('today ' . $finMannana));
}
$this->entityManager->persist($dateFichaje);
} else {
$fichaje = new Fichaje();
if (!empty($inicioMannana) && !empty($finMannana)) {
$fichaje->setInicioAm(new DateTimeImmutable('today ' . $inicioMannana));
$fichaje->setFinAm(new DateTimeImmutable('today ' . $finMannana));
}
if (!empty($inicioTarde) && !empty($finTarde)) {
$fichaje->setInicioPm(new DateTimeImmutable('today ' . $inicioTarde));
$fichaje->setFinPm(new DateTimeImmutable('today ' . $finTarde));
}
if (!empty($inicioDescansoAm) && !empty($finDescansoAm)) {
$fichaje->setInicioDescansoAm(new DateTimeImmutable('today ' . $inicioDescansoAm));
$fichaje->setFinDescansoAm(new DateTimeImmutable('today ' . $finDescansoAm));
}
if (!empty($inicioDescansoPm) && !empty($finDescansoPm)) {
$fichaje->setInicioDescansoPm(new DateTimeImmutable('today ' . $inicioDescansoPm));
$fichaje->setFinDescansoPm(new DateTimeImmutable('today ' . $finDescansoPm));
}
$fichaje->setUser($username);
$fichaje->setFecha($fecha);
$this->entityManager->persist($fichaje);
}
$this->entityManager->flush();
return $this->redirectToRoute('fichaje');
}
// Función auxiliar para calcular la diferencia entre dos horas
private function calcularDiferencia($inicio, $fin) {
if ($inicio && $fin) {
$inicioDT = DateTime::createFromFormat('H:i', $inicio);
$finDT = DateTime::createFromFormat('H:i', $fin);
if ($inicioDT && $finDT) {
return $inicioDT->diff($finDT);
}
}
return new DateInterval('PT0H'); // Retorna 0 horas si los valores son inválidos
}
private function calcularHorasTrabajadas($arrayHoras) {
// Calcular horas trabajadas en la mañana
$horasAm = $this->calcularDiferencia($arrayHoras['inicio_am'], $arrayHoras['fin_am']);
$descansoAm = $this->calcularDiferencia($arrayHoras['inicio_descanso_am'], $arrayHoras['fin_descanso_am']);
// Calcular horas trabajadas en la tarde
$horasPm = $this->calcularDiferencia($arrayHoras['inicio_pm'], $arrayHoras['fin_pm']);
$descansoPm = $this->calcularDiferencia($arrayHoras['inicio_descanso_pm'], $arrayHoras['fin_descanso_pm']);
// Restar los descansos
$totalMinutos = ($horasAm->h * 60 + $horasAm->i) + ($horasPm->h * 60 + $horasPm->i)
- ($descansoAm->h * 60 + $descansoAm->i) - ($descansoPm->h * 60 + $descansoPm->i);
// Convertir minutos totales a horas y minutos
$horasTrabajadas = floor($totalMinutos / 60);
$minutosTrabajados = $totalMinutos % 60;
return str_pad($horasTrabajadas, 2, "0", STR_PAD_LEFT).":".str_pad($minutosTrabajados, 2, "0", STR_PAD_LEFT);
//return sprintf('%02d:%02d', $horasTrabajadas, $minutosTrabajados);
}
}