<?php

namespace App\Controller;


use App\Controller\Base\AbstractRetencionController;
use App\Electronico\Comprobante;
use App\Entity\Model\Invoice;
use App\Entity\Model\ItemRetencion;
use App\Entity\Model\Payment;
use App\Entity\Model\Provider;
use App\Entity\Model\Retencion;
use App\Service\EmFactory;
use App\Util\ExportInvoicePartnerExcel;
use App\Util\ExportRetencionPartnerExcel;
use App\Util\Funciones;
use App\Util\RestApiFunciones;
use Knp\Component\Pager\PaginatorInterface;
use PhpOffice\PhpSpreadsheet\Writer\Xlsx;
use Psr\Log\LoggerInterface;
use Symfony\Component\Form\Extension\Core\Type\HiddenType;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\StreamedResponse;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
use Symfony\Contracts\Translation\TranslatorInterface;


/**
 * @Route("/retencion")
 */
class RetencionController extends AbstractRetencionController
{
    protected  $translator;
    /**
     * @Route("", name="retencion_index")
     *
     */
    public function indexAction(Request $request, EmFactory $emFactory, TranslatorInterface $translator, PaginatorInterface $paginator)
    {
        $this->translator= $translator;

        $this->denyAccessUnlessGranted('IS_AUTHENTICATED_FULLY');
        $user = $this->getUser();

        $em = $emFactory->getEm();
        $empresaRepo = $em->getRepository('App\Entity\Model\Empresa');
        $emisor = $empresaRepo->findOneByUser($user->getRuc());

        $puedeFacturar = Funciones::getValidaPuedeFacturar($emisor, $em);
        $emisor = Funciones::getValidaEmitidos($emisor, $em);

        $repo = $em->getRepository('App\Entity\Model\Retencion');
        $repo->setPaginator($paginator);
        // @todo Unhardcode this.
        $limit = 20;

        if ($request->query->has('pdf') || $request->query->has('excel'))
            $limit = 10000;

        $form = $this->createForm('App\Form\SearchGenericType', null, [
            'action' => $this->generateUrl('retencion_index'),
            'method' => 'GET',
        ]);
        $form->handleRequest($request);
        if ($form->isSubmitted() && $form->isValid()) {
            $pagination = $repo->paginatedSearch($form->getData(), $limit, $request->query->getInt('page', 1), $emisor->getId());
        } else {
            $pagination = $repo->paginatedSearch([], $limit, $request->query->getInt('page', 1), $emisor->getId());
        }

        $invoices = [];
        $reporte = [];
        foreach ($pagination->getItems() as $item) {
            $invoices[] = $item;
            if ($request->query->has('pdf') || $request->query->has('excel')){
                //$item = new Retencion();
                $aux['emision'] = $item->getIssueDate();
                $aux['serie'] = $item->getSerie();
                $aux['numero'] = $item->getNumber();

                $aux['comprafac'] = $item->getSerieCompra().'-'.str_pad($item->getNumeroCompra(),9,'0',STR_PAD_LEFT);
                $aux['retenido'] = $item->getGrossAmount();
                $aux['ruc'] = $item->getProviderIdentification();
                $aux['proveedor'] = $item->getProviderName();
                $aux['estado'] = $item->getEstado();
                $aux['clave'] = $item->getClaveAcceso();
                $aux['fecAutorizacion'] = $item->getFechaAutorizacion();
                $aux['anulado'] = $item->getAnulado() == true ? "1": "0";
                $reporte[] = $aux;
            }
        }

        if ($form->isSubmitted()) {
            if ($request->query->has('pdf')) {
                return $this->reportePdf($reporte);
            } elseif ($request->query->has('excel')) {
                return $this->reporteExcel($reporte);
            }
        }


        $listForm = $this->createForm('App\Form\ListGenericType', $invoices, [
            'action' => $this->generateUrl('retencion_index'),
        ]);

        $listForm->handleRequest($request);

        if ($listForm->isSubmitted() && $listForm->isValid()) {
            $data = $listForm->getData();
            if (empty($data['invoices'])) {
                $this->addTranslatedMessage('flash.nothing_selected', 'warning');
            } else {
                if ($request->request->has('delete')) {
                    return $this->bulkDelete($data['invoices']);
                } elseif ($request->request->has('pdf')) {
                    return $this->bulkPdf($data['invoices']);
                } elseif ($request->request->has('print')) {
                    return $this->bulkPrint($data['invoices']);
                } elseif ($request->request->has('email')) {
                    return $this->bulkEmail($data['invoices']);
                } elseif ($request->request->has('autorizar')) {
                    return $this->bulkAutorizar($data['invoices']);
                }
            }
        }

        return $this->render('Retencion\index.html.twig',
        array(
            'invoices' => $pagination,
            'currency' => $emisor == null ? 'USD' : $emisor->getCurrency(),
            'search_form' => $form->createView(),
            'list_form' => $listForm->createView(),
        ));
    }


    /**
     * @Route("/new", name="retencion_add")
     *
     */
    public function newAction(Request $request, EmFactory $emFactory, TranslatorInterface $translator)
    {
        $this->translator= $translator;

        $this->denyAccessUnlessGranted('IS_AUTHENTICATED_FULLY');
        $usuario = $this->getUser();

        $em = $emFactory->getEm($usuario->getUsername());
        $empresaRepo = $em->getRepository('App\Entity\Model\Empresa');
        $empresa = $empresaRepo->findOneByUser($usuario->getRuc());

        $puedeFacturar = Funciones::getValidaPuedeFacturar($empresa, $em);
        $empresa = Funciones::getValidaEmitidos($empresa, $em);

        if($empresa->getPuedefacturar() === false && $empresa->getTipoAmbiente() === "2"){
            $this->addTranslatedMessage($empresa->getMensaje()===null?'PLAN CADUCADO EL: '.$empresa->getFechaCaduca()->format('d/m/Y'):$empresa->getMensaje(), 'danger');
            return $this->redirect($this->generateUrl('retencion_index'));
        }

        $cambioplan = false;
        $total = $em->getRepository(Invoice::class)->getFacturasxMes($empresa->getId());
        $plan = $empresa->getPlan();
        $planes = null;
        $msgcambioplan ="";
        if($plan->getIlimitado() === false) {
            if ($total > floatval($plan->getNumFacMes())) {
                $planesRepo = $em->getRepository('App\Entity\Model\Planes');
                $planes = $planesRepo->findTodos();
                foreach ($planes as $key => $aux)
                {
                    if($aux === $plan){
                        unset($planes[$key]);
                        break;
                    }
                }
                //$this->addTranslatedMessage('Número de facturas emitidas excede del plan contratado', 'danger');
                $msgcambioplan ='Número de Retenciones emitidas excede del plan contratado.';
                $cambioplan = true;
            }
        }

        $retencion = new Retencion();
        $retencion->setEmpresa($empresa);
        $retencion->setMes(date("m"));
        $retencion->setAnio(date("Y"));
        $item = new ItemRetencion();

        $retencion->addItem($item);

        $form = $this->createForm('App\Form\RetencionType', $retencion, [
            'action' => $this->generateUrl('retencion_add'),
        ]);
        $form->handleRequest($request);

        if ($form->isSubmitted() && $form->isValid()) {

            if ($request->request->has('save_draft')) {
                $retencion->setStatus(Retencion::DRAFT);
            } else {
                // Any save action transforms this to opened.
                $retencion->setStatus(Retencion::OPENED);
            }

            //if ($retencion->getProvider() == null) {
            //    $this->addTranslatedMessage('Proveedor no se encuentra registrado', 'danger');
            //} else {
                $retencion = $this->cargarImpuestos($retencion);

            if ($retencion->getCodSustento())
                $retencion->setCodSustento($retencion->getCodSustento()->getCodigo());

            if ($retencion->getFormaPago())
                $retencion->setFormaPago($retencion->getFormaPago()->getCodigo());

            $serie = $retencion->getSeries()->getValue();
                $retencion->setSerie($serie);
                $retencion->setEmpresa($empresa);
                $retencion->setUsuario($usuario->getId());
                $retencion->setAmbiente($empresa->getTipoAmbiente());

            if($cambioplan === false) {

                $em->persist($retencion);
                $em->flush();

                $retencion = $this->generarXml($retencion);

                if ($empresa->getEnvioAutomatico()) {

                    if ($retencion !== null) {
                        $app_url = $this->getParameter('cola_url');

                        $error = false;

                        $resp = RestApiFunciones::enviarComprobanteCola($error,
                            $retencion->getProviderName(),
                            $retencion->getProviderEmail(),
                            $usuario->getId(),
                            $retencion->getXml(),
                            $retencion->getClaveAcceso(),
                            $app_url,
                            'retencion'
                        );

                        if ($error) {
                            $this->addTranslatedMessage($resp, 'danger');
                            $retencion->setMensajeError($resp);
                        }

                        $em->persist($retencion);
                        $em->flush();

                    }

                    return $this->redirect($this->generateUrl('retencion_index'));

                }

                return $this->redirect($this->generateUrl('retencion_show', ['id' => $retencion->getId(), 'slug' => $retencion->getSlug()]));
            }
        }

        $provider = new Provider();

        $formprovider = $this->createForm('App\Form\ProviderType', $provider, [
            'action' => $this->generateUrl('rest_provider_add'),
        ]);
        $formprovider->handleRequest($request);

        if($cambioplan){
            $formcambioplan = $this->createForm('App\Form\CambioPlanType', $provider, [
                'action' => $this->generateUrl('invoice_add'),
            ]);
            $formcambioplan->handleRequest($request);
        }

        return $this->render('Retencion\edit.html.twig',
        array(
            'form' => $form->createView(),
            'formprovider' => $formprovider->createView(),
            'provider' => $provider,
            'entity' => $retencion,
            'currency' => $empresa == null ? 'USD' : $empresa->getCurrency(),
            'cambioplan' => $cambioplan,
            'planes' => $planes,
            'msgcambioplan'=> $msgcambioplan,
            'formcambioplan' => $cambioplan ? $formcambioplan->createView(): null
        ));
    }

    /**
     * @Route("/show/{slug}rtn{id}", name="retencion_show")
     *
     */
    public function showAction($slug, Request $request, EmFactory $emFactory, $id, TranslatorInterface $translator)
    {
        $this->translator= $translator;

        $this->denyAccessUnlessGranted('IS_AUTHENTICATED_FULLY');
        $user = $this->getUser();

        $em = $emFactory->getEm();
        $empresaRepo = $em->getRepository('App\Entity\Model\Empresa');
        $empresa = $empresaRepo->findOneByUser($user->getRuc());

        $entity = $em->getRepository('App\Entity\Model\Retencion')->findBySlug($slug, $id);
        if (!$entity) {
            throw $this->createNotFoundException('Unable to find Retencion entity.');
        }

        $defaultData = ['slug' => $slug, 'id'=>$id, 'customerEmail' => $entity->getProviderEmail()];

        $form = $this->createFormBuilder($defaultData)
            ->add('slug', HiddenType::class)
            ->add('id', HiddenType::class)
            ->add('customerEmail')
            ->setAction($this->generateUrl('retencion_show', ['id' => $id, 'slug'=>$slug]))
            ->getForm();

        /*if (!$entity->isClosed()) {
            // When the retenciones is open send to the edit form by default.
            return $this->redirect($this->generateUrl('retencion_edit', array('id' => $id)));
        }
        */

        $form->handleRequest($request);

        if ($form->isSubmitted() && $form->isValid()) {
            // data is an array with "name", "email", and "message" keys
            $data = $form->getData();

            if ($request->request->has('Form-pdf')) {
                $this->generarPdf($entity);
            } elseif ($request->request->has('Form-email')) {
                if (isset($data['customerEmail'])) {
                    $email = $data['customerEmail'];
                    $this->enviarMail($email, $entity);
                } else
                    $this->addTranslatedMessage('Email del cliente nulo o en blanco', 'warning');
            } elseif ($request->request->has('Form-edit')) {
                if ($entity->getAutorizado() === false)
                    return $this->redirect($this->generateUrl('retencion_edit', ['id' => $entity->getId(), 'slug' => $slug]));
            } elseif ($request->request->has('Form-delete')) {
                $error = $this->delete($entity);
                if ($error)
                    return $this->redirect($this->generateUrl('retencion_index'));
            } elseif ($request->request->has('Form-anular')) {
                $entity->setAnulado(true);
                $em->persist($entity);
                $em->flush();
            } elseif ($request->request->has('Form-enviar')) {
                $this->enviarSriOnline($entity);
            } elseif ($request->request->has('Form-auto')) {
                if ($entity->getAutorizado() === false) {
                    $resp = $this->consultarAutorizacion($entity);
                    if ($resp != null)
                        $this->addTranslatedMessage($resp, 'danger');
                }

            }
        }

        if ($entity->getMensajeError()) {
            $this->addTranslatedMessage($entity->getMensajeError(), 'danger');
        }

        return $this->render('Retencion\show.html.twig',
        array(
            'entity' => $entity,
            'form' => $form->createView(),
            'currency' => $empresa == null ? 'USD' : $empresa->getCurrency(),
        ));
    }

    /**
     * @Route("/edit/{slug}rtn{id}", name="retencion_edit")
     *
     */
    public function editAction($id, Request $request, $slug, EmFactory $emFactory, TranslatorInterface $translator)
    {
        $this->translator= $translator;

        $this->denyAccessUnlessGranted('IS_AUTHENTICATED_FULLY');
        $user = $this->getUser();

        $em = $emFactory->getEm();
        $empresaRepo = $em->getRepository('App\Entity\Model\Empresa');
        $empresa = $empresaRepo->findOneByUser($user->getRuc());

        $entity = $em->getRepository('App\Entity\Model\Retencion')->findBySlug($slug, $id);
        if (!$entity) {
            throw $this->createNotFoundException('Unable to find Retencion entity.');
        }


        if(strlen($entity->getCodSustento() > 0)){
            $entity->setCodSustento($em->getRepository('App\Entity\Model\SustentoTributario')->findSustentoTributarioByCodigo($entity->getCodSustento()));
        }
        if(strlen($entity->getFormaPago() > 0)){
            $entity->setFormaPago($em->getRepository('App\Entity\Model\FormaPago')->findFormaPagoByCodigo($entity->getFormaPago()));
        }

        $form = $this->createForm('App\Form\RetencionType', $entity, [
            'action' => $this->generateUrl('retencion_edit', ['id' => $id, 'slug' => $slug]),
        ]);

        $form->handleRequest($request);

        if ($form->isSubmitted() && $form->isValid()) {
            $redirectRoute = 'retencion_show';

            if ($request->request->has('save_draft')) {
                $entity->setStatus(Retencion::DRAFT);
            } elseif ($request->request->has('save_close')) {
                $entity->setForcefullyClosed(true);
            } elseif ($entity->isDraft()) {
                // Any save action transforms this to opened.
                $entity->setStatus(Retencion::OPENED);
            }

            // See if one of PDF/Print buttons was clicked.
            /*if ($request->request->has('save_pdf')) {
                $redirectRoute = 'retenciones_show_pdf';
            } elseif ($request->request->has('save_print')) {
                $this->get('session')->set('retenciones_auto_print', $id);
            }
            */

            // Save.

            $this->cargarImpuestos($entity);

            $entity->setUsuario($user->getId());

            if ($entity->getCodSustento())
                $entity->setCodSustento($entity->getCodSustento()->getCodigo());

            if ($entity->getFormaPago())
                $entity->setFormaPago($entity->getFormaPago()->getCodigo());

            $em->persist($entity);
            $em->flush();
            //$this->addTranslatedMessage('flash.updated');

            $retencion = $this->generarXml($entity);

            return $this->redirect($this->generateUrl($redirectRoute, ['id' => $id, 'slug' => $slug]));
        }

        return $this->render('Retencion\edit.html.twig',
        array(
            'entity' => $entity,
            'form' => $form->createView(),
            'currency' =>  $empresa == null ? 'USD' : $empresa->getCurrency(),
        ));
    }

    public function enviarSriOnline(Retencion $retencion)
    {
        $retencion = $this->generarXml($retencion);
        $em = $this->getDoctrine()->getManager();

        if($retencion !== null) {
            $app_url = $this->getParameter('api_url');

            $error = false;
            $resp = RestApiFunciones::enviarComprobante($error, $retencion->getXml(), $retencion->getClaveAcceso(), $app_url);

            if ($error)
                $this->addTranslatedMessage($resp->message, 'danger');
            else {
                if ($resp->estado === 'recibido') {
                    $resp = $this->consultarAutorizacion($retencion);

                    if ($resp !== null)
                        $this->addTranslatedMessage($resp, 'danger');
                } else {
                    $retencion->setMensajeError($resp->message);
                    $this->addTranslatedMessage($resp->message, 'danger');
                    $em->persist($retencion);
                    $em->flush();
                }
            }

        }
    }

    /**
     * @Route("/delete/{slug}rtn{id}", name="retencion_delete")
     */
    public function deleteAction($slug, EmFactory $emFactory, TranslatorInterface $translator)
    {
        $this->translator= $translator;

        $this->denyAccessUnlessGranted('IS_AUTHENTICATED_FULLY');
        $user = $this->getUser();

        $em = $emFactory->getEm();

        $retenciones = $em->getRepository('App\Entity\Model\Retencion')->findBySlug($slug);
        if (!$retenciones) {
            throw $this->createNotFoundException('Unable to find Retencion entity.');
        }
        if ($retenciones->getAmbiente() === 1) {
            $em->remove($retenciones);
            $em->flush();
            $this->addTranslatedMessage('flash.deleted');
        } else
            $this->addTranslatedMessage('NO se pueden eliminar facturas en ambiente de producion', 'danger');

        return $this->redirect($this->generateUrl('retencion_index'));
    }

    /**
     * @Route("/payments/{slug}rtn{id}", name="retenciones_payments")
     *
     */
    public function paymentsAction(Request $request, $slug, EmFactory $emFactory, TranslatorInterface $translator)
    {
        $this->translator= $translator;

        $this->denyAccessUnlessGranted('IS_AUTHENTICATED_FULLY');
        $user = $this->getUser();

        $em = $emFactory->getEm();

        // Return all payments
        $retenciones = $em->getRepository('App\Entity\Model\Retencion')->findBySlug($slug);
        if (!$retenciones) {
            throw $this->createNotFoundException('Unable to find Retencion entity.');
        }

        $payment = new Payment;
        $addForm = $this->createForm('App\Form\PaymentType', $payment, [
            'action' => $this->generateUrl('retenciones_payments', ['retencionesId' => $retencionesId]),
        ]);
        $addForm->handleRequest($request);
        if ($addForm->isSubmitted() && $addForm->isValid()) {
            $retenciones->addPayment($payment);
            $em->persist($retenciones);
            $em->flush();
            $this->addTranslatedMessage('payment.flash.added');

            // Rebuild the query, since we have new objects now.
            return $this->redirect($this->generateUrl('retenciones_index'));
        }

        $listForm = $this->createForm('App\Form\RetencionPaymentListType', $retenciones->getPayments()->getValues(), [
            'action' => $this->generateUrl('retenciones_payments', ['retencionesId' => $retencionesId]),
        ]);
        $listForm->handleRequest($request);

        if ($listForm->isSubmitted() && $listForm->isValid()) {
            $data = $listForm->getData();
            foreach ($data['payments'] as $payment) {
                $retenciones->removePayment($payment);
                $em->persist($retenciones);
                $em->flush();
            }
            $this->addTranslatedMessage('payment.flash.bulk_deleted');

            // Rebuild the query, since some objects are now missing.
            return $this->redirect($this->generateUrl('retenciones_index'));
        }

        return $this->render('Payment\list.html.twig',
         [
            'retencionesId' => $retencionesId,
            'add_form' => $addForm->createView(),
            'list_form' => $listForm->createView(),
            'currency' => $em->getRepository('SiwappConfigBundle:Property')->get('currency', 'EUR'),
        ]);
    }

    /**
     * @Route("/form-totals", name="retencion_form_totals")
     */
    public function getInvoiceFormTotals(EmFactory $emFactory, Request $request)
    {
        $this->denyAccessUnlessGranted('IS_AUTHENTICATED_FULLY');
        $user = $this->getUser();

        $em = $emFactory->getEm();

        $post = $request->request->get('retencion');
        if (!$post) {
            throw new NotFoundHttpException;
        }

        $response = $this->getRetencionesTotalsFromPost($post, new Retencion(), $request->getLocale());

        return new JsonResponse($response);
    }


    /**
     * @Route("/pdfpreview/{slug}inv{id}", name="retencion_show_pdf_preview")
     *
     */
    public function showOnlinePdfAction($id,  $slug, EmFactory $emFactory, TranslatorInterface $translator, Request $request, LoggerInterface $logger)
    {
        $this->logger = $logger;
        $this->translator = $translator;
        $this->denyAccessUnlessGranted('IS_AUTHENTICATED_FULLY');
        $user = $this->getUser();

        $em = $emFactory->getEm();
        $empresaRepo = $em->getRepository('App\Entity\Model\Empresa');
        $empresa = $empresaRepo->findOneByUser($user->getRuc());

        $invoice = $em->getRepository('App\Entity\Model\Retencion')->findBySlug($slug, $id);
        if (!$invoice) {
            throw $this->createNotFoundException('Unable to find Invoice entity.');
        }

        $filename = 'RE_' . $invoice->getSerie() . "-" . str_pad($invoice->getNumber(), 9, '0', STR_PAD_LEFT) . '.pdf';

        if ($invoice->getAutorizado())
            $xml = $invoice->getXmlAutorizado();
        else
            $xml = $invoice->getXml();

        $app_url = $this->getParameter('api_url').'retencionride.php';

        $error = false;
        $mensaje = "";

        $docPdf = RestApiFunciones::getPdf($error, $app_url, $invoice->getClaveAcceso(), $xml, $mensaje, $empresa->getRuc());

        if ($error) {
            $this->addTranslatedMessage('ERRROR AL GENERAR EL PDF, ' . $mensaje, 'danger');
        } else {
            file_put_contents($filename, $docPdf);

            $pdf = base64_encode(file_get_contents($filename));

            $response = new Response($pdf);
            $response->headers->set('Content-Type', 'application/octet-stream');
            $response->headers->set('Content-Description', 'File Transfer');
            $response->headers->set('Content-Disposition', 'attachment; filename="'.$filename.'"');
            // $response->headers->set('Expires', '0');
            // $response->headers->set('Content-Transfer-Encoding', 'binary');
            $response->headers->set('Content-length', strlen($pdf));
            $response->headers->set('Cache-Control', 'no-cache private');
            // $response->headers->set('Pragma', 'public');
            // Send headers before outputting anything
            $response->sendHeaders();



            try {
                unlink($filename);
            } catch (\Exception $ex) {

            }
            return $response;
        }
    }

    /**
     * @Route("download/xml/{slug}inv{id}", name="retencion_download_xml")
     *
     */
    public function xmldownloadAction($id, $slug, EmFactory $emFactory, Request $request, TranslatorInterface $translator, LoggerInterface $logger)
    {
        $this->logger = $logger;
        $this->translator = $translator;
        $this->denyAccessUnlessGranted('IS_AUTHENTICATED_FULLY');
        $user = $this->getUser();

        $em = $emFactory->getEm();
        $empresaRepo = $em->getRepository('App\Entity\Model\Empresa');
        $empresa = $empresaRepo->findOneByUser($user->getRuc());

        $invoice = $em->getRepository(Retencion::class)->findBySlug($slug, $id);
        if (!$invoice) {
            throw $this->createNotFoundException('Unable to find Retencion entity.');
        }

        if ($invoice->getAutorizado()) {
            $filename = 'RE-' . $invoice->getSerie() . "-" . str_pad($invoice->getNumber(), 9, '0', STR_PAD_LEFT) . '.xml';
            try {
                $xml = $invoice->getXmlAutorizado();

                file_put_contents($filename, $xml);

                $contentType = 'application/xml';

                $content = file_get_contents($filename);
                $response = new Response();
                $response->headers->set('Content-Type', $contentType);
                $response->headers->set('Content-Disposition', 'attachment;filename="' . $filename . '"');

                $response->headers->addCacheControlDirective('no-cache', true);
                $response->headers->addCacheControlDirective('must-revalidate', true);

                $response->setContent($content);
                return $response;
            } catch (\Exception $ex) {

            } finally {
                try {
                    unlink($filename);
                } catch (\Exception $ex) {

                }
            }

        } else
            $xml = $invoice->getXml();

    }

    private function reporteExcel($invoices){

        $format = 'xlsx';
        $filename = 'retenciones' . '.' . $format;

        $exportExcel = new ExportRetencionPartnerExcel();

        $titulo = "REPORTE RETENCIONES";

        $spreadsheet = $exportExcel->createSpreadsheet($invoices, $titulo);

        switch ($format) {
            /*case 'ods':
                $contentType = 'application/vnd.oasis.opendocument.spreadsheet';
                $writer = new Ods($spreadsheet);
                break;
            case 'csv':
                $contentType = 'text/csv';
                $writer = new Csv($spreadsheet);
                break;*/
            case 'xlsx':
                $contentType = 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet';
                $writer = new Xlsx($spreadsheet);
                break;

        }

        //$writer->save($filename);

        $response = new StreamedResponse();
        $response->headers->set('Content-Type', $contentType);
        $response->headers->set('Content-Disposition', 'attachment;filename="'.$filename.'"');
        $response->setPrivate();
        $response->headers->addCacheControlDirective('no-cache', true);
        $response->headers->addCacheControlDirective('must-revalidate', true);
        $response->setCallback(function() use ($writer) {
            $writer->save('php://output');
        });

        return $response;

    }
}
