<?php
namespace App\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Security\Http\Authentication\UserAuthenticatorInterface;
use Symfony\Component\Routing\Annotation\Route;
use App\Repository\PcConvocatoriasRepository;
use App\Repository\PcPuntoCulturaRepository;
use App\Entity\PcConvocatorias;
use App\Entity\PcCriterios;
use App\Repository\PcCriteriosRepository;
use App\Entity\PcCriteriosConvocatorias;
use App\Repository\PcCriteriosConvocatoriasRepository;
use App\Repository\RegionRepository;
use App\Service\RegionComunaService;
use App\Service\RacService;
use App\Service\ValidacionService;
use App\Entity\PcPostulacion;
use App\Repository\PcPostulacionRepository;
use App\Repository\PostulacionRepository;
use App\Entity\Postulacion;
use App\Entity\Region;
use App\Entity\Comuna;
use App\Repository\ComunaRepository;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\File\Exception\FileNotFoundException;
use Symfony\Component\HttpFoundation\BinaryFileResponse;
use Symfony\Component\HttpFoundation\ResponseHeaderBag;
use Symfony\Component\Security\Core\Security;
use Symfony\Component\Validator\Validator\ValidatorInterface;
use DateTime;
use DateTimeInterface;
/**
* @Route("/api/pu", name="api_pu_")
*/
class ApiPuntoCulturaController extends AbstractController
{
#[Route('/insecure/puntocultura', name: 'obtenerTodosPuntoCultura', methods: ['GET'])]
public function obtenerTodosPuntoCultura(
PcPuntoCulturaRepository $pcPuntoCulturaRepository
): JsonResponse
{
try {
$puntos = $pcPuntoCulturaRepository->findAllActivos();
$data = [];
$puntoxregion = [];
foreach ($puntos as $punto) {
$region = $punto->getRegion();
$comuna = $punto->getComuna();
if(empty($puntoxregion[$region])) $puntoxregion[$region] = 0;
$puntoxregion[$region] += 1;
if(empty($data[$region])) $data[$region] = [];
if(empty($data[$region][$comuna])) $data[$region][$comuna] = [];
$data[$region][$comuna][] = [
'id' => $punto->getId(),
'nombre' => $punto->getNombre(),
];
}
return $this->json(['data' => $data, 'total' => $puntoxregion]);
} catch (\Exception $e) {
return new JsonResponse(['error' => 'Error de servidor', 'detalle' => $e->getMessage()], 500);
}
}
#[Route('/insecure/puntocultura/{id}', name: 'obtenerPuntoCulturaPublico', methods: ['GET'])]
public function obtenerPuntoCulturaPublico(
$id, PcPuntoCulturaRepository $pcPuntoCulturaRepository
): JsonResponse
{
try {
$punto = $pcPuntoCulturaRepository->findActivo($id);
if (!$punto) {
return new JsonResponse(['error' => 'Punto no encontrado'], JsonResponse::HTTP_NOT_FOUND);
}
return $this->json([
'id' => $punto->getId(),
'nombre' => $punto->getNombre() ?? '',
'resenia' => $punto->getResenia() ?? '',
'region' => $punto->getRegion() ?? '',
'comuna' => $punto->getComuna() ?? '',
'direccion' => $punto->getDireccion() ?? '',
'georeferencia' => $punto->getGeoreferencia(),
'nombre_contacto' => $punto->getNombreContacto() ?? '',
'email_contacto' => $punto->getEmailContacto() ?? '',
'redes_sociales' => $punto->getRedesSociales(),
'certificado_punto' => $punto->getCertificadoPunto() ?? '',
// 'nombre_persona_juridica' => $punto->getNombrePersonaJuridica(),
// 'nombre_representante_legal' => $punto->getNombreRepresentanteLegal(),
// 'rut_persona_juridica' => $punto->getRutPersonaJuridica(),
// 'rut_representante_legal' => $punto->getRutRepresentanteLegal(),
// 'direccion_postal' => $punto->getDireccionPostal(),
// 'correo_electronico_1' => $punto->getCorreoElectronico1(),
// 'correo_electronico_2' => $punto->getCorreoElectronico2(),
// 'telefono_1' => $punto->getTelefono1(),
// 'telefono_2' => $punto->getTelefono2(),
// 'organizacion_comunitaria_id' => $punto->getOrganizacionComunitariaId(),
// 'doc_estatuto_organizacion' => $punto->getDocEstatutoOrganizacion(),
// 'doc_certificado_vigencia_persona_juridica' => $punto->getDocCertificadoVigenciaPersonaJuridica(),
// 'doc_acredita_personeria_vigente' => $punto->getDocAcreditaPersoneriaVigente(),
// 'doc_listado_personas'=> $punto->getDocListadoPersonas(),
// 'documentos' => $punto->getDocumentos(),
'rut' => $punto->getRut(),
'dv' => $punto->getDv(),
]);
} catch (\Exception $e) {
return new JsonResponse(['error' => 'Error de servidor', 'detalle' => $e->getMessage()], 500);
}
}
#[Route('/secure/puntocultura/{id}', name: 'obtenerPuntoCulturaPrivado', methods: ['GET'])]
public function obtenerPuntoCulturaPrivado(
$id,
PcPuntoCulturaRepository $pcPuntoCulturaRepository,
RacService $racService,
Security $security
): JsonResponse
{
try {
$user = $security->getUser();
if (!$user) {
return new JsonResponse(['error' => 'Usuario no encontrado'], JsonResponse::HTTP_NOT_FOUND);
}
$rut = $user->getRut();
$dv = $user->getDv();
$userRut = strval(number_format((int) $rut, 0, '', '.')) . '-' . $dv;
$punto = $pcPuntoCulturaRepository->findByIdAndRut($id, $rut, $dv);
if (!$punto) {
return new JsonResponse(['error' => 'Punto no encontrado'], JsonResponse::HTTP_NOT_FOUND);
}
$organizaciones = $racService->getRegisterRac($userRut);
$organizacionId = (string) $punto->getOrganizacionComunitariaId();
$rac = null;
foreach($organizaciones as $org){
if(empty($org['org_id'])) continue;
$org_id = $org['org_id'];
if($organizacionId == $org_id){
$rac = $org;
}
}
return $this->json([
'id' => $punto->getId(),
'nombre' => $punto->getNombre() ?? '',
'resenia' => $punto->getResenia() ?? '',
'region' => $punto->getRegion() ?? '',
'comuna' => $punto->getComuna() ?? '',
'direccion' => $punto->getDireccion() ?? '',
'georeferencia' => $punto->getGeoreferencia() ?? '',
'nombre_contacto' => $punto->getNombreContacto() ?? '',
'email_contacto' => $punto->getEmailContacto() ?? '',
'redes_sociales' => $punto->getRedesSociales(),
'certificado_punto' => $punto->getCertificadoPunto() ?? '',
'nombre_persona_juridica' => $punto->getNombrePersonaJuridica() ?? '',
'nombre_representante_legal' => $punto->getNombreRepresentanteLegal() ?? '',
'rut_persona_juridica' => $punto->getRutPersonaJuridica() ?? '',
'rut_representante_legal' => $punto->getRutRepresentanteLegal() ?? '',
'direccion_postal' => $punto->getDireccionPostal() ?? '',
'correo_electronico_1' => $punto->getCorreoElectronico1() ?? '',
'correo_electronico_2' => $punto->getCorreoElectronico2() ?? '',
'telefono_1' => $punto->getTelefono1() ?? '',
'telefono_2' => $punto->getTelefono2() ?? '',
'organizacion_comunitaria_id' => $punto->getOrganizacionComunitariaId(),
'doc_estatuto_organizacion' => $punto->getDocEstatutoOrganizacion(),
'doc_certificado_vigencia_persona_juridica' => $punto->getDocCertificadoVigenciaPersonaJuridica(),
'doc_acredita_personeria_vigente' => $punto->getDocAcreditaPersoneriaVigente(),
'doc_listado_personas'=> $punto->getDocListadoPersonas(),
'documentos' => $punto->getDocumentos(),
'rut' => $punto->getRut(),
'dv' => $punto->getDv(),
'rac' => $rac,
]);
} catch (\Exception $e) {
return new JsonResponse(['error' => 'Error de servidor', 'detalle' => $e->getMessage()], 500);
}
}
#[Route('/secure/puntocultura/{id}', name: 'actualizarPuntoCultura', methods: ['PUT'])]
public function actualizarPuntoCultura(
$id,
Request $request,
PcPuntoCulturaRepository $pcPuntoCulturaRepository,
Security $security,
ValidatorInterface $validator,
ValidacionService $validacionService
): JsonResponse
{
try {
$user = $security->getUser();
if (!$user) {
return new JsonResponse(['error' => 'Usuario no encontrado'], JsonResponse::HTTP_NOT_FOUND);
}
$rut = $user->getRut();
$dv = $user->getDv();
$punto = $pcPuntoCulturaRepository->findByIdAndRut($id, $rut, $dv);;
if (!$punto) {
return new JsonResponse(['error' => 'Punto cultura no encontrado'], JsonResponse::HTTP_NOT_FOUND);
}
$data = json_decode($request->getContent(), true);
// Validacion
if (!$validacionService->validacionesOrNulo([
$data['nombre'],
$data['resenia'],
$data['region'],
$data['comuna'],
$data['direccion'],
$data['georeferencia'],
$data['nombre_contacto'],
$data['email_contacto'],
$data['certificado_punto'],
$data['nombre_persona_juridica'],
$data['nombre_representante_legal'],
$data['rut_persona_juridica'],
$data['rut_representante_legal'],
$data['direccion_postal'],
$data['correo_electronico_1'],
$data['correo_electronico_2'],
$data['telefono_1'],
$data['telefono_2']
], 'string')) {
return new JsonResponse(['error' => 'Los campos de nombre, reseña, region, comuna, georeferencia, nombre_contacto, email_contacto, certificado_punto, nombre_persona_juridica, nombre_representante_legal, rut_persona_juridica, rut_representante_legal, direccion_postal, correo_electronico_1, correo_electronico_2, telefono_1, telefono_2 y dirección deben ser texto'], JsonResponse::HTTP_BAD_REQUEST);
}
if (!$validacionService->validacionesOrNulo([
$data['organizacion_comunitaria_id']
], 'integer')) {
return new JsonResponse(['error' => 'Los campos organizacion_comunitaria_id debe ser numerico'], JsonResponse::HTTP_BAD_REQUEST);
}
if (!$validacionService->validacionesOrNulo([
$data['redes_sociales'],
$data['doc_estatuto_organizacion'],
$data['doc_certificado_vigencia_persona_juridica'],
$data['doc_acredita_personeria_vigente'],
$data['doc_listado_personas'],
$data['documentos']
], 'array')) {
return new JsonResponse(['error' => 'Los campos de redes_sociales, doc_estatuto_organizacion, doc_certificado_vigencia_persona_juridica, doc_acredita_personeria_vigente, doc_listado_personas y documentos deben ser objetos'], JsonResponse::HTTP_BAD_REQUEST);
}
$punto->setNombre($data['nombre']);
$punto->setResenia($data['resenia']);
$punto->setRegion($data['region']);
$punto->setComuna($data['comuna']);
$punto->setDireccion($data['direccion']);
$punto->setGeoreferencia($data['georeferencia']);
$punto->setNombreContacto($data['nombre_contacto']);
$punto->setEmailContacto($data['email_contacto']);
$punto->setRedesSociales($data['redes_sociales']);
$punto->setCertificadoPunto($data['certificado_punto']);
$punto->setNombrePersonaJuridica($data['nombre_persona_juridica']);
$punto->setNombreRepresentanteLegal($data['nombre_representante_legal']);
$punto->setRutPersonaJuridica($data['rut_persona_juridica']);
$punto->setRutRepresentanteLegal($data['rut_representante_legal']);
$punto->setDireccionPostal($data['direccion_postal']);
$punto->setCorreoElectronico1($data['correo_electronico_1']);
$punto->setCorreoElectronico2($data['correo_electronico_2']);
$punto->setTelefono1($data['telefono_1']);
$punto->setTelefono2($data['telefono_2']);
$punto->setOrganizacionComunitariaId($data['organizacion_comunitaria_id']);
$punto->setDocEstatutoOrganizacion($data['doc_estatuto_organizacion']);
$punto->setDocCertificadoVigenciaPersonaJuridica($data['doc_certificado_vigencia_persona_juridica']);
$punto->setDocAcreditaPersoneriaVigente($data['doc_acredita_personeria_vigente']);
$punto->setDocListadoPersonas($data['doc_listado_personas']);
$punto->setDocumentos($data['documentos']);
// Validar con Symfony Validator
$errors = $validator->validate($punto);
if (count($errors) > 0) {
$errorMessages = [];
foreach ($errors as $error) {
$errorMessages[] = $error->getMessage();
}
return new JsonResponse(['error' => $errorMessages], JsonResponse::HTTP_BAD_REQUEST);
}
$pcPuntoCulturaRepository->save($punto, true);
$puntoCulturaArr = [
'id' => $punto->getId(),
'nombre' => $punto->getNombre(),
'resenia' => $punto->getResenia(),
'region' => $punto->getRegion(),
'comuna' => $punto->getComuna(),
'direccion' => $punto->getDireccion(),
'georeferencia' => $punto->getGeoreferencia(),
'nombre_contacto' => $punto->getNombreContacto(),
'email_contacto' => $punto->getEmailContacto(),
'redes_sociales' => $punto->getRedesSociales(),
'certificado_punto' => $punto->getCertificadoPunto(),
'nombre_persona_juridica' => $punto->getNombrePersonaJuridica(),
'nombre_representante_legal' => $punto->getNombreRepresentanteLegal(),
'rut_persona_juridica' => $punto->getRutPersonaJuridica(),
'rut_representante_legal' => $punto->getRutRepresentanteLegal(),
'direccion_postal' => $punto->getDireccionPostal(),
'correo_electronico_1' => $punto->getCorreoElectronico1(),
'correo_electronico_2' => $punto->getCorreoElectronico2(),
'telefono_1' => $punto->getTelefono1(),
'telefono_2' => $punto->getTelefono2(),
'organizacion_comunitaria_id' => $punto->getOrganizacionComunitariaId(),
'doc_estatuto_organizacion' => $punto->getDocEstatutoOrganizacion(),
'doc_certificado_vigencia_persona_juridica' => $punto->getDocCertificadoVigenciaPersonaJuridica(),
'doc_acredita_personeria_vigente' => $punto->getDocAcreditaPersoneriaVigente(),
'doc_listado_personas'=> $punto->getDocListadoPersonas(),
'documentos' => $punto->getDocumentos(),
'rut' => $punto->getRut(),
'dv' => $punto->getDv(),
];
return new JsonResponse(['message' => 'Punto Cultura actualizado con éxito', 'pc' => $puntoCulturaArr]);
} catch (\Exception $e) {
return new JsonResponse(['error' => 'Error de servidor', 'detalle' => $e->getMessage()], 500);
}
}
#[Route('/secure/region', name: 'obtenerRegiones', methods: ['GET'])]
public function obtenerRegiones(
RegionRepository $regionRepository
): JsonResponse
{
try {
$regiones = $regionRepository->findAll();
$regionesJson = [];
foreach($regiones as $region){
$regionesJson[] = [
'nombre' => $region->getNombre(),
'codigo' => $region->getId()
];
}
return $this->json($regionesJson);
} catch (\Exception $e) {
return new JsonResponse(['error' => 'Error de servidor', 'detalle' => $e->getMessage()], 500);
}
}
#[Route('/secure/region/{codigo}/comuna', name: 'obtenerComunas', methods: ['GET'])]
public function obtenerComunas(
$codigo,
ComunaRepository $comunaRepository
): JsonResponse
{
try {
$comunas = $comunaRepository->findByRegion((int) $codigo);
$comunasJson = [];
foreach($comunas as $comuna){
$comunasJson[] = [
'nombre' => $comuna->getNombre(),
'codigo' => $comuna->getId()
];
}
return $this->json($comunasJson);
} catch (\Exception $e) {
return new JsonResponse(['error' => 'Error de servidor', 'detalle' => $e->getMessage()], 500);
}
}
/**
* @Route("/secure/upload-file", name="uploadFile", methods={"POST"})
*/
public function uploadFile(Request $request): JsonResponse
{
try {
$file = $request->files->get('file');
if (!$file) {
return new JsonResponse(['error' => 'No hay documento'], 400);
}
try {
$originalName = $file->getClientOriginalName();
$newFilename = str_replace(' ', '_', $originalName) . '-' . uniqid() . '.' . $file->guessExtension();
$projectRoot = $this->getParameter('kernel.project_dir');
$dirToMove = $projectRoot . '/private/documentos/subidas';
if (!is_dir($dirToMove)) {
mkdir($dirToMove, 0777, true);
}
$file->move($dirToMove, $newFilename);
return new JsonResponse([
'message' => 'Documento subido con exito',
'original_name' => $originalName,
'new_filename' => $newFilename,
'path' => '/documentos/subidas/' . $newFilename,
], 200);
} catch (FileException $e) {
return new JsonResponse(['error' => 'Falla al subir archivo: ' . $e->getMessage()], 500);
}
} catch (\Exception $e) {
return new JsonResponse(['error' => 'Error de servidor', 'detalle' => $e->getMessage()], 500);
}
}
/**
* @Route("/secure/download-file/{filename}", name="downloadFile", methods={"GET"})
*/
public function downloadFile(string $filename): Response
{
try {
$projectRoot = $this->getParameter('kernel.project_dir');
$filePath = $projectRoot . '/private/documentos/subidas/' . $filename;
if (!file_exists($filePath)) {
throw $this->createNotFoundException("Archivo no encontrado: $filename");
}
// Devolver el archivo como una respuesta
$response = new BinaryFileResponse($filePath);
$response->setContentDisposition(ResponseHeaderBag::DISPOSITION_ATTACHMENT, $filename);
return $response;
} catch (\Exception $e) {
return new JsonResponse(['error' => 'Error de servidor', 'detalle' => $e->getMessage()], 500);
}
}
#[Route('/secure/convocatorias', name: 'obtenerConvocatoriasAbiertas', methods: ['GET'])]
public function obtenerConvocatoriasAbiertas(
PcConvocatoriasRepository $pcConvocatoriasRepository,
Security $security,
PcPostulacionRepository $pcPostulacionRepository
): JsonResponse
{
try {
$user = $security->getUser();
if (!$user) {
return new JsonResponse(['error' => 'Usuario no encontrado'], JsonResponse::HTTP_NOT_FOUND);
}
$rut = $user->getRut();
$dv = $user->getDv();
$convocatorias = $pcConvocatoriasRepository->findAbiertas();
$convocatoriasJson = [];
foreach ($convocatorias as $convocatoria) {
$pu_inscritos = [];
$postulaciones = $pcPostulacionRepository->findPuntoCulturaAndRutAndConvocatorias($rut, $dv, $convocatoria->getId());
foreach ($postulaciones as $postulacion) {
$pu_inscritos[] = $postulacion->getPuntoCultura()->getId();
}
$convocatoriasJson[] = [
'id' => $convocatoria->getId(),
'nombre' => $convocatoria->getNombre(),
'descripcion' => $convocatoria->getDescripcion(),
'anio' => $convocatoria->getAnio(),
'estado' => $convocatoria->getEstado(),
'pu_inscritos' => $pu_inscritos
];
}
return $this->json(['convocatorias' => $convocatoriasJson]);
} catch (\Exception $e) {
return new JsonResponse(['error' => 'Error de servidor', 'detalle' => $e->getMessage()], 500);
}
}
#[Route('/secure/postulacion', name: 'crearPostulacion', methods: ['POST'])]
public function crearPostulacion(
Request $request,
PcConvocatoriasRepository $pcConvocatoriaRepository,
PcPostulacionRepository $pcPostulacionRepository,
PcPuntoCulturaRepository $pcPuntoCulturaRepository,
Security $security,
ValidatorInterface $validator,
ValidacionService $validacionService
): JsonResponse
{
try {
$user = $security->getUser();
if (!$user) {
return new JsonResponse(['error' => 'Usuario no encontrado'], JsonResponse::HTTP_NOT_FOUND);
}
$rut = $user->getRut();
$dv = $user->getDv();
$data = json_decode($request->getContent(), true);
if (!$validacionService->validacionesOrNulo([
$data['convocatoriaId'],
$data['puntoCulturaId'],
], 'integer')) {
return new JsonResponse(['error' => 'Los campos de convocatoriaId y puntoCulturaId deben ser numericos'], JsonResponse::HTTP_BAD_REQUEST);
}
$convocatoriaId = $data['convocatoriaId'];
$puntoCulturaId = $data['puntoCulturaId'];
$convocatoria = $pcConvocatoriaRepository->find($convocatoriaId);
$puntoCultura = $pcPuntoCulturaRepository->findByIdAndRut($puntoCulturaId, $rut, $dv);
if (!$convocatoria) {
return new JsonResponse(['error' => 'Convocatoria no encontrada'], JsonResponse::HTTP_NOT_FOUND);
}
if($convocatoria->getEstado() !== '1'){
return new JsonResponse(['error' => 'Convocatoria no esta en fase de postulación'], JsonResponse::HTTP_BAD_REQUEST);
}
if (!$puntoCultura) {
return new JsonResponse(['error' => 'Punto Cultura no encontrado'], JsonResponse::HTTP_NOT_FOUND);
}
$postulacionExistente = $pcPostulacionRepository->findByPuntoCulturaAndRutAndConvocatoria($puntoCulturaId, $rut, $dv, $convocatoriaId);
if (!!$postulacionExistente) {
return new JsonResponse(['error' => 'Ya existe una postulación para esta convocatoria'], JsonResponse::HTTP_BAD_REQUEST);
}
if (!empty($data['estado']) && ($data['estado'] !== 'save' && $data['estado'] !== 'send')) {
return new JsonResponse(['error' => 'Solo se permite estado save y send'], JsonResponse::HTTP_BAD_REQUEST);
}
$formularioAdmisibilidad = [
1 => [
'pregunta'=> '¿Admisibilidad?',
'tipo'=> 'opcion',
'opciones'=> ['Si', 'No'],
'respuesta'=> '',
],
2 => [
'pregunta'=> 'Observaciones internas',
'tipo'=> 'texarea',
'respuesta'=> '',
],
3 => [
'pregunta'=> 'Observaciones publicas',
'tipo'=> 'texarea',
'respuesta'=> '',
],
];
$formularioSeleccion = [
1 => [
'pregunta'=> '',
'tipo'=> 'opcion',
'opciones'=> ['Seleccionado', 'No seleccionado'],
'respuesta'=> '',
],
2 => [
'pregunta'=> 'Monto adjudicado',
'tipo'=> 'text',
'respuesta'=> '',
],
3 => [
'pregunta'=> 'Observaciones',
'tipo'=> 'texarea',
'respuesta'=> '',
],
];
$criteriosData = $convocatoria->getCriterios();
$formularioEvaluacion = [];
foreach ($criteriosData as $criterioConvocatoria) {
$formularioEvaluacion[] = [
'tipo' => 'criterio',
'id' => $criterioConvocatoria->getId(),
'nombre' => $criterioConvocatoria->getCriterios()->getNombre(),
'descripcion' => $criterioConvocatoria->getCriterios()->getDescripcion(),
'peso' => $criterioConvocatoria->getPeso(),
'puntajes' => $criterioConvocatoria->getCriterios()->getPuntajes(),
'valor' => null,
'justificacion' => ''
];
}
$formularioEvaluacion[] = [
'tipo' => 'pregunta',
'pregunta'=> 'Justificación general',
'tipo'=> 'texarea',
'respuesta'=> '',
];
$formulario = array_map(function($cuestionario) {
$cuestionario['valor'] = null;
return $cuestionario;
}, $convocatoria->getCuestionarios());
$documentos = array_map(function($documento) {
$documento['valor'] = null;
return $documento;
}, $convocatoria->getDocumentos());
$postulacion = new PcPostulacion();
$postulacion->setConvocatoria($convocatoria);
$postulacion->setPuntoCultura($puntoCultura);
$postulacion->setFormularioPostulacion($formulario);
$postulacion->setDocumentosPostulacion($documentos);
$postulacion->setFormularioAdmisibilidad($formularioAdmisibilidad);
$postulacion->setFormularioSeleccion($formularioSeleccion);
$postulacion->setFormularioEvaluacion($formularioEvaluacion);
$postulacion->setEstado('save');
$now = new DateTime();
$postulacion->setCreatedAt($now);
$postulacion->updateTimestamps();
// Validar con Symfony Validator
$errors = $validator->validate($postulacion);
if (count($errors) > 0) {
$errorMessages = [];
foreach ($errors as $error) {
$errorMessages[] = $error->getMessage();
}
return new JsonResponse(['error' => $errorMessages], JsonResponse::HTTP_BAD_REQUEST);
}
$pcPostulacionRepository->save($postulacion, true);
$postulacionObj = [
'id' => $postulacion->getId(),
'montoRequerido' => $postulacion->getMontoRequerido(),
'formularioPostulacion' => $postulacion->getFormularioPostulacion(),
'documentosPostulacion' => $postulacion->getDocumentosPostulacion(),
'anexos' => $postulacion->getDocumentos(),
'convocatoriaId' => $postulacion->getConvocatoria()->getId(),
'convocatoriaNombre' => $postulacion->getConvocatoria()->getNombre(),
];
return new JsonResponse(['message' => 'Postulacion creada con éxito', 'postulacion' => $postulacionObj ], JsonResponse::HTTP_CREATED);
} catch (\Exception $e) {
return new JsonResponse(['error' => 'Error de servidor', 'detalle' => $e->getMessage()], 500);
}
}
#[Route('/secure/postulacion/{id}', name: 'actualizarPostulacion', methods: ['PUT'])]
public function actualizarPostulacion(
$id,
Request $request,
PcPostulacionRepository $pcPostulacionRepository,
Security $security,
ValidatorInterface $validator,
ValidacionService $validacionService
): JsonResponse
{
try {
$user = $security->getUser();
if (!$user) {
return new JsonResponse(['error' => 'Usuario no encontrado'], JsonResponse::HTTP_NOT_FOUND);
}
$rut = $user->getRut();
$dv = $user->getDv();
$postulacion = $pcPostulacionRepository->findByIdAndRut($id, $rut, $dv);
if (!$postulacion) {
return new JsonResponse(['error' => 'Postulacion no encontrada'], JsonResponse::HTTP_NOT_FOUND);
}
$punto = $postulacion->getPuntoCultura();
if(!$punto || !$punto->getActivo()){
return new JsonResponse(['error' => 'Punto de cultura no encontrado'], JsonResponse::HTTP_NOT_FOUND);
}
$convocatoria = $postulacion->getConvocatoria();
if (!$convocatoria) {
return new JsonResponse(['error' => 'Convocatoria no encontrada'], JsonResponse::HTTP_NOT_FOUND);
}
if($convocatoria->getEstado() !== '1'){
return new JsonResponse(['error' => 'Convocatoria no esta en fase de postulación'], JsonResponse::HTTP_BAD_REQUEST);
}
$estadoOriginal = $postulacion->getEstado();
if($estadoOriginal == 'send'){
return new JsonResponse(['error' => 'Postulacion ya fue enviada'], JsonResponse::HTTP_BAD_REQUEST);
}
$data = json_decode($request->getContent(), true);
if (!$validacionService->validacionesOrNulo([
$data['estado'],
], 'string')) {
return new JsonResponse(['error' => 'Los campos de estado deben ser texto'], JsonResponse::HTTP_BAD_REQUEST);
}
if (!$validacionService->validacionesOrNulo([
$data['montoRequerido']
], 'integer')) {
return new JsonResponse(['error' => 'Los campos de montoRequerido deben ser numerico'], JsonResponse::HTTP_BAD_REQUEST);
}
if (!$validacionService->validacionesOrNulo([
$data['formularioPostulacion'],
$data['documentosPostulacion'],
$data['anexos']
], 'array')) {
return new JsonResponse(['error' => 'Los campos de formularioPostulacion, documentosPostulacion y anexos deben ser objetos'], JsonResponse::HTTP_BAD_REQUEST);
}
if($data['estado'] == 'send'){
$now = new DateTime();
$postulacion->setPostulatedAt($now);
}
$postulacion->setMontoRequerido($data['montoRequerido']);
$postulacion->setFormularioPostulacion($data['formularioPostulacion']);
$postulacion->setDocumentosPostulacion($data['documentosPostulacion']);
$postulacion->setDocumentos($data['anexos']);
$postulacion->setEstado($data['estado'] ?? 'save');
$postulacion->updateTimestamps();
// Validar con Symfony Validator
$errors = $validator->validate($postulacion);
if (count($errors) > 0) {
$errorMessages = [];
foreach ($errors as $error) {
$errorMessages[] = $error->getMessage();
}
return new JsonResponse(['error' => $errorMessages], JsonResponse::HTTP_BAD_REQUEST);
}
$pcPostulacionRepository->save($postulacion, true);
$postulacionObj = [
'id' => $postulacion->getId(),
'montoRequerido' => $postulacion->getMontoRequerido(),
'formularioPostulacion' => $postulacion->getFormularioPostulacion(),
'documentosPostulacion' => $postulacion->getDocumentosPostulacion(),
'anexos' => $postulacion->getDocumentos(),
'convocatoriaId' => $postulacion->getConvocatoria()->getId(),
'convocatoriaNombre' => $postulacion->getConvocatoria()->getNombre(),
'nombrePuntoCultura' => $punto->getNombre(),
'idPuntoCultura' => $punto->getId(),
];
return new JsonResponse(['message' => 'Postulación actualizada con éxito', 'postulacion' => $postulacionObj]);
} catch (\Exception $e) {
return new JsonResponse(['error' => 'Error de servidor', 'detalle' => $e->getMessage()], 500);
}
}
#[Route('/secure/postulacion/{id}', name: 'obtenerPostulacion', methods: ['GET'])]
public function obtenerPostulacion(
$id,
PcPostulacionRepository $pcPostulacionRepository,
Security $security
): JsonResponse
{
try {
$user = $security->getUser();
if (!$user) {
return new JsonResponse(['error' => 'Usuario no encontrado'], JsonResponse::HTTP_NOT_FOUND);
}
$rut = $user->getRut();
$dv = $user->getDv();
$postulacion = $pcPostulacionRepository->findByIdAndRut($id, $rut, $dv);
if (!$postulacion) {
return new JsonResponse(['error' => 'Postulacion no encontrada'], JsonResponse::HTTP_NOT_FOUND);
}
$punto = $postulacion->getPuntoCultura();
if(!$punto || !$punto->getActivo()){
return new JsonResponse(['error' => 'Punto de cultura no encontrado'], JsonResponse::HTTP_NOT_FOUND);
}
$usuarioAdmisibilidad = $postulacion->getUsuarioAdmisibilidad();
$usuarioEvaluacion = $postulacion->getUsuarioEvaluacion();
$usuarioSeleccion = $postulacion->getUsuarioSeleccion();
return $this->json([
'id' => $postulacion->getId(),
'montoRequerido' => $postulacion->getMontoRequerido(),
'formularioPostulacion' => $postulacion->getFormularioPostulacion(),
'documentosPostulacion' => $postulacion->getDocumentosPostulacion(),
'certificadoPostulacion' => $postulacion->getCertificadoPostulacion(),
'resultadoAdmisibilidad' => $postulacion->getResultadoAdmisibilidad(),
'estadoAdmisibilidad' => $postulacion->getEstadoAdmisibilidad(),
'formularioAdmisibilidad' => $postulacion->getFormularioAdmisibilidad(),
'notaFinalEvaluacion' => $postulacion->getNotaFinalEvaluacion(),
'formularioEvaluacion' => $postulacion->getFormularioEvaluacion(),
'estadoEvaluacion' => $postulacion->getEstadoEvaluacion(),
'formularioSeleccion' => $postulacion->getFormularioSeleccion(),
'estado' => $postulacion->getEstado(),
'formularioSeleccion' => $postulacion->getFormularioSeleccion(),
'estadoSeleccion' => $postulacion->getEstadoSeleccion(),
'resultadoSeleccion' => $postulacion->getResultadoSeleccion(),
'montoAdjudicado' => $postulacion->getMontoAdjudicado(),
'anexos' => $postulacion->getDocumentos(),
'convocatoriaId' => $postulacion->getConvocatoria()->getId(),
'convocatoriaNombre' => $postulacion->getConvocatoria()->getNombre(),
'usuarioAdmisibilidad' => $usuarioAdmisibilidad ? $usuarioAdmisibilidad->getNombres() : null,
'usuarioEvaluacion' => $usuarioEvaluacion ? $usuarioEvaluacion->getNombres() : null,
'usuarioSeleccion' => $usuarioSeleccion ? $usuarioSeleccion->getNombres() : null,
'admisibilidadAt' => $postulacion->getAdmisibilidadAt(),
'evaluacionAt' => $postulacion->getEvaluacionAt(),
'seleccionAt' => $postulacion->getSeleccionAt(),
'nombrePuntoCultura' => $punto->getNombre(),
'idPuntoCultura' => $punto->getId(),
]);
} catch (\Exception $e) {
return new JsonResponse(['error' => 'Error de servidor', 'detalle' => $e->getMessage()], 500);
}
}
#[Route('/secure/postulaciones', name: 'obtenerPostulaciones', methods: ['GET'])]
public function obtenerPostulaciones(
PcPostulacionRepository $pcPostulacionRepository,
Security $security
): JsonResponse
{
try {
$user = $security->getUser();
if (!$user) {
return new JsonResponse(['error' => 'Usuario no encontrado'], JsonResponse::HTTP_NOT_FOUND);
}
$rut = $user->getRut();
$dv = $user->getDv();
$postulaciones = $pcPostulacionRepository->findByRut($rut, $dv);
$postulacionesJson = [];
foreach ($postulaciones as $postulacion) {
$puntoCultura = $postulacion->getPuntoCultura();
$convocatoria = $postulacion->getConvocatoria();
$postulacionesJson[] = [
'id' => $postulacion->getId(),
'nombre' => $convocatoria->getNombre(),
'convocatoriaEstado' => $convocatoria->getEstado(),
'estado' => $postulacion->getEtapaPostulacion(),
'resultadoEvaluacion' => $postulacion->getResultadoPostulacion(),
'editar' => $postulacion->getEstado() == 'send' ? false : true,
'puntoCultura' => $puntoCultura->getNombre(),
'pundoCulturaId' => $puntoCultura->getId(),
];
}
return $this->json(['postulaciones' => $postulacionesJson]);
} catch (\Exception $e) {
return new JsonResponse(['error' => 'Error de servidor', 'detalle' => $e->getMessage()], 500);
}
}
#[Route('/secure/mis-puntos', name: 'obtenerMisPuntosDeCultura', methods: ['GET'])]
public function obtenerMisPuntosDeCultura(
PcPuntoCulturaRepository $pcPuntoCulturaRepository,
Security $security
): JsonResponse
{
try {
$user = $security->getUser();
if (!$user) {
return new JsonResponse(['error' => 'Usuario no encontrado'], JsonResponse::HTTP_NOT_FOUND);
}
$rut = $user->getRut();
$dv = $user->getDv();
$puntos = $pcPuntoCulturaRepository->findByRut($rut, $dv);
$data = [];
$puntosResponse = [];
foreach ($puntos as $punto) {
$puntosResponse[] = [
'id' => $punto->getId(),
'nombre' => $punto->getNombre(),
];
}
return $this->json($puntosResponse);
} catch (\Exception $e) {
return new JsonResponse(['error' => 'Error de servidor', 'detalle' => $e->getMessage()], 500);
}
}
#[Route('/secure/mi-perfil', name: 'obtenerMiPerfil', methods: ['GET'])]
public function obtenerMiPerfil(
PcPuntoCulturaRepository $pcPuntoCulturaRepository,
RacService $racService,
Security $security
): JsonResponse
{
try {
$user = $security->getUser();
if (!$user) {
return new JsonResponse(['error' => 'Usuario no encontrado'], JsonResponse::HTTP_NOT_FOUND);
}
$rut = $user->getRut();
$dv = $user->getDv();
$puntos = $pcPuntoCulturaRepository->findByRut($rut, $dv);
$data = [];
$puntosResponse = [];
$userRut = strval(number_format((int) $rut, 0, '', '.')) . '-' . $dv;
$organizaciones = $racService->getRegisterRac($userRut);
$organizacionesById = [];
foreach($organizaciones as $org){
if(empty($org['org_id'])) continue;
$org_id = $org['org_id'];
$organizacionesById[$org_id] = $org;
}
foreach ($puntos as $punto) {
$organizacionId = (string) $punto->getOrganizacionComunitariaId();
$rac = $organizacionesById[$organizacionId] ?? [];
$puntosResponse[] = [
'id' => $punto->getId(),
'nombre' => $punto->getNombre() ?? '',
'resenia' => $punto->getResenia() ?? '',
'region' => $punto->getRegion() ?? '',
'comuna' => $punto->getComuna() ?? '',
'direccion' => $punto->getDireccion() ?? '',
'georeferencia' => $punto->getGeoreferencia() ?? '',
'nombre_contacto' => $punto->getNombreContacto() ?? '',
'email_contacto' => $punto->getEmailContacto() ?? '',
'redes_sociales' => $punto->getRedesSociales(),
'certificado_punto' => $punto->getCertificadoPunto() ?? '',
'nombre_persona_juridica' => $punto->getNombrePersonaJuridica() ?? '',
'nombre_representante_legal' => $punto->getNombreRepresentanteLegal() ?? '',
'rut_persona_juridica' => $punto->getRutPersonaJuridica() ?? '',
'rut_representante_legal' => $punto->getRutRepresentanteLegal() ?? '',
'direccion_postal' => $punto->getDireccionPostal() ?? '',
'correo_electronico_1' => $punto->getCorreoElectronico1() ?? '',
'correo_electronico_2' => $punto->getCorreoElectronico2() ?? '',
'telefono_1' => $punto->getTelefono1() ?? '',
'telefono_2' => $punto->getTelefono2() ?? '',
'organizacion_comunitaria_id' => $punto->getOrganizacionComunitariaId(),
'doc_estatuto_organizacion' => $punto->getDocEstatutoOrganizacion(),
'doc_certificado_vigencia_persona_juridica' => $punto->getDocCertificadoVigenciaPersonaJuridica(),
'doc_acredita_personeria_vigente' => $punto->getDocAcreditaPersoneriaVigente(),
'doc_listado_personas'=> $punto->getDocListadoPersonas(),
'documentos' => $punto->getDocumentos(),
'rut' => $punto->getRut(),
'dv' => $punto->getDv(),
'rac' => $rac,
];
}
return $this->json($puntosResponse);
} catch (\Exception $e) {
return new JsonResponse(['error' => 'Error de servidor', 'detalle' => $e->getMessage()], 500);
}
}
#[Route('/secure/convocatoria/{id}', name: 'obtenerConvocatoria', methods: ['GET'])]
public function obtenerConvocatoria(
$id,
PcConvocatoriasRepository $pcConvocatoriaRepository,
Security $security
): JsonResponse
{
try {
$convocatoria = $pcConvocatoriaRepository->find($id);
if (!$convocatoria) {
return new JsonResponse(['error' => 'Convocatoria no encontrada'], JsonResponse::HTTP_NOT_FOUND);
}
$criterios = [];
$criteriosData = $convocatoria->getCriterios();
foreach ($criteriosData as $criterioConvocatoria) {
$criterios[] = [
'id' => $criterioConvocatoria->getCriterios()->getId(),
'peso' => $criterioConvocatoria->getPeso()
];
}
return $this->json([
'id' => $convocatoria->getId(),
'nombre' => $convocatoria->getNombre(),
'descripcion' => $convocatoria->getDescripcion(),
'anio' => $convocatoria->getAnio(),
'bases' => $convocatoria->getBases(),
'presupuesto' => $convocatoria->getPresupuesto(),
'puntajeEvalCorte' => $convocatoria->getPuntajeEvalCorte(),
'cuestionarios' => $convocatoria->getCuestionarios(),
'documentos' => $convocatoria->getDocumentos(),
'estado' => $convocatoria->getEstado(),
'criterios' => $criterios,
]);
} catch (\Exception $e) {
return new JsonResponse(['error' => 'Error de servidor', 'detalle' => $e->getMessage()], 500);
}
}
#[Route('/secure/cargar', name: 'cargar', methods: ['POST'])]
public function cargarArchivos(
Request $request,
PcPostulacionRepository $pcPostulacionRepository,
PcPuntoCulturaRepository $pcPuntoCulturaRepository,
Security $security
): JsonResponse
{
try {
$user = $security->getUser();
if (!$user) {
return new JsonResponse(['error' => 'Usuario no encontrado'], JsonResponse::HTTP_NOT_FOUND);
}
$rut = $user->getRut();
$dv = $user->getDv();
$file = $request->files->get('file');
if (!$file) {
return new JsonResponse(['error' => 'No hay documento'], 400);
}
// Obtener configuración desde .env
$maxFileSizeMB = $_ENV['MAX_FILE_SIZE'] ?? 10;
$allowedExtensions = explode(',', $_ENV['ALLOWED_EXTENSIONS'] ?? '');
// Validar tamaño del archivo
$fileSizeMB = $file->getSize() / (1024 * 1024); // Convertir a MB
if ($fileSizeMB > $maxFileSizeMB) {
return new JsonResponse(['error' => "El archivo supera el tamaño máximo permitido de {$maxFileSizeMB}MB"], 400);
}
// Validar extensión
$extension = $file->guessExtension();
if (!in_array($extension, $allowedExtensions)) {
return new JsonResponse(['error' => "Extensión no permitida. Solo se aceptan: " . implode(', ', $allowedExtensions)], 400);
}
$postulacionId = $request->request->get('postulacionId');
$puntoCulturaId = $request->request->get('puntoCulturaId');
$tipoDocumento = '';
if(!empty($postulacionId)){
$tipoDocumento="/pcpostulaciones/postulacion_" . $postulacionId;
$postulacion = $pcPostulacionRepository->findByIdAndRut($postulacionId, $rut, $dv);
if (!$postulacion) {
return new JsonResponse(['error' => 'Postulacion no encontrada'], JsonResponse::HTTP_NOT_FOUND);
}
} else if (!empty($puntoCulturaId)){
$tipoDocumento="/puntoscultura/puntocultura_" . $puntoCulturaId;
$punto = $pcPuntoCulturaRepository->findByIdAndRut($puntoCulturaId, $rut, $dv);
if (!$punto) {
return new JsonResponse(['error' => 'Punto no encontrado'], JsonResponse::HTTP_NOT_FOUND);
}
} else {
return new JsonResponse(['error' => 'postulacionId, puntoCulturaId o convocatoriaId requerido'], 400);
}
try {
$originalName = $file->getClientOriginalName();
$newFilename = str_replace(' ', '_', $originalName) . '-' . uniqid() . '.' . $file->guessExtension();
$projectRoot = $this->getParameter('kernel.project_dir');
$dirToMove = $projectRoot . '/public/documentos' . $tipoDocumento;
if (!is_dir($dirToMove)) {
mkdir($dirToMove, 0777, true);
}
$file->move($dirToMove, $newFilename);
return new JsonResponse([
'message' => 'Documento subido con exito',
'original_name' => $originalName,
'new_filename' => $newFilename,
'path' => '/documentos' . $tipoDocumento . '/' . $newFilename,
], 200);
} catch (FileException $e) {
return new JsonResponse(['error' => 'Falla al subir archivo: ' . $e->getMessage()], 500);
}
} catch (\Exception $e) {
return new JsonResponse(['error' => 'Error de servidor', 'detalle' => $e->getMessage()], 500);
}
}
#[Route('/secure/descargas', name: 'descargas', methods: ['POST'])]
public function descargas(
Request $request,
PcPostulacionRepository $pcPostulacionRepository,
PcPuntoCulturaRepository $pcPuntoCulturaRepository,
PostulacionRepository $postulacionRepository,
Security $security
): Response
{
try {
$user = $security->getUser();
if (!$user) {
return new JsonResponse(['error' => 'Usuario no encontrado'], JsonResponse::HTTP_NOT_FOUND);
}
$rut = $user->getRut();
$dv = $user->getDv();
$data = json_decode($request->getContent(), true);
$path = $data['path'];
if(empty($path)){
return new JsonResponse(['error' => 'Falta enviar path'],
JsonResponse::HTTP_BAD_REQUEST);
}
$rutasArchivo = explode("/", $path);
$tipoDocumento = $rutasArchivo[2];
if($tipoDocumento == "postulaciones"){
$postulacionId = explode('_', $rutasArchivo[3])[1];
$postulacion = $postulacionRepository->findOneByRutId($rut, $postulacionId);
if (!$postulacion) {
return new JsonResponse(['error' => 'Postulacion no encontrada'], JsonResponse::HTTP_NOT_FOUND);
}
} else if($tipoDocumento == "puntoscultura"){
$puntoCulturaId = explode('_', $rutasArchivo[3])[1];
$punto = $pcPuntoCulturaRepository->findByIdAndRut($puntoCulturaId, $rut, $dv);
if (!$punto) {
return new JsonResponse(['error' => 'Punto no encontrado'], JsonResponse::HTTP_NOT_FOUND);
}
} else if($tipoDocumento == "pcpostulaciones"){
$postulacionId = explode('_', $rutasArchivo[3])[1];
$postulacion = $pcPostulacionRepository->findByIdAndRut($postulacionId, $rut, $dv);
if (!$postulacion) {
return new JsonResponse(['error' => 'Postulacion no encontrada'], JsonResponse::HTTP_NOT_FOUND);
}
}
$projectRoot = $this->getParameter('kernel.project_dir');
$filePath = $projectRoot . '/public' . $path;
if (!file_exists($filePath)) {
throw $this->createNotFoundException("Archivo no encontrado");
}
$filename = $rutasArchivo[count($rutasArchivo)-1];
// Devolver el archivo como una respuesta
$response = new BinaryFileResponse($filePath);
$response->setContentDisposition(ResponseHeaderBag::DISPOSITION_ATTACHMENT, $filename);
return $response;
} catch (\Exception $e) {
return new JsonResponse(['error' => 'Error de servidor', 'detalle' => $e->getMessage()], 500);
}
}
#[Route('/insecure/file', name: 'obtenerInfoFile', methods: ['GET'])]
public function obtenerInfoFile(): JsonResponse
{
try {
return $this->json([
'maxFileSize' => $_ENV['MAX_FILE_SIZE'] ?? 10,
'allowedExtensions' => explode(',', $_ENV['ALLOWED_EXTENSIONS'] ?? '')
]);
} catch (\Exception $e) {
return new JsonResponse(['error' => 'Error de servidor', 'detalle' => $e->getMessage()], 500);
}
}
}