<?php 
namespace Noahtech\Sistemas\InterjamaBundle\Controller; 
 
use Noahtech\Sistemas\InterjamaBundle\Utils\Codes; 
use Symfony\Component\HttpFoundation\Response; 
use Symfony\Component\Routing\Annotation\Route; 
use Symfony\Component\HttpFoundation\Request; 
use Noahtech\Sistemas\InterjamaBundle\Controller\BaseController; 
use Noahtech\Sistemas\InterjamaBundle\Handler\McCajaHandler; 
use Noahtech\Sistemas\InterjamaBundle\Handler\McMonedaHandler; 
use Noahtech\Sistemas\InterjamaBundle\Handler\McMovimientoHandler; 
use Noahtech\Sistemas\InterjamaBundle\Handler\McCajaMonedaHandler; 
use Noahtech\Sistemas\InterjamaBundle\Handler\McChoferHandler; 
use Noahtech\Sistemas\InterjamaBundle\Handler\McClienteHandler; 
use Noahtech\Sistemas\InterjamaBundle\Handler\McDivisaHandler; 
use Symfony\Component\Security\Core\Exception\AccessDeniedException; 
use Noahtech\Sistemas\InterjamaBundle\Utils\Constants; 
 
class CajaController extends BaseController { 
 
    private function validarAdmin () { 
        $usuario = $this->getUser(); 
        $admin = false; 
        foreach ($usuario->getRoles() as $rol) {             
            if ($rol == 'ROLE_ADMIN'){ 
                $admin = true; 
            } 
        } 
        if (!$admin){ 
            throw new AccessDeniedException("No tiene permiso para acceder a esta pagina."); 
        } 
    } 
 
    private function validarCajaCerrada($cajaId) {         
        $caja = $this->get(McCajaHandler::class)->getCajaById($cajaId); 
        if ($caja) { 
            if ($caja->getCerrado()) { 
                throw new AccessDeniedException("No tiene permiso para acceder a esta pagina."); 
            } 
        } else { 
            throw new AccessDeniedException("No tiene permiso para acceder a esta pagina.");  
        }         
    } 
     
    private function validarDescargaCaja($cajaId) { 
        $caja = $this->get(McCajaHandler::class)->getCajaById($cajaId); 
        if ($caja) { 
            if (!$caja->getCerrado()) { 
                throw new AccessDeniedException("No tiene permiso para acceder a esta pagina."); 
            } 
        } else { 
            throw new AccessDeniedException("No tiene permiso para acceder a esta pagina.");  
        } 
    } 
 
    private function validarChofer ($tipo, $numero, $id=null) { 
        $chofer = $this->get(McChoferHandler::class)->getChoferDuplicate($tipo, $numero, $id); 
        if (!is_null($chofer)) { 
            throw new HttpException(409, "Ya existe un chofer con el tipo y nĂºmero de documento ingresados."); 
        } 
    } 
 
    private function validarMovimiento($cajaId, $movimientoId) { 
        $movimiento = $this->get(McMovimientoHandler::class)->getMovimientoById($movimientoId); 
        if ($movimiento) { 
            if ($movimiento->getCaja()->getId() != (int)$cajaId) { 
                throw new AccessDeniedException("No tiene permiso para acceder a esta pagina."); 
            } 
        } else { 
            throw new AccessDeniedException("No tiene permiso para acceder a esta pagina.");  
        } 
    } 
 
    /** 
     * @Route("/admin/cajas", name="admin_cajas_listado") 
     * @return type 
     */ 
    public function cajasListadoAction() { 
        $this->validarAdmin(); 
        $usuario = $this->getUser();                
        $this->setTitle("Listado de cajas | InterJama"); 
        $this->addBreadCrumb("Inicio - Admin", false, "admin_home"); 
        $this->addBreadCrumb("Listado de cajas", true); 
        $this->data['data'] = null; 
        return $this->render( 
                        '@NoahtechSistemasInterjama/admin/cajas/listado.html.twig', $this->data 
        ); 
    } 
 
    /** 
     * consulta de cajas 
     * 
     * @Route("/admin/ajax/cajas/search", name="admin_ajax_cajas_listado", methods={"POST"}, condition="request.isXmlHttpRequest()") 
     */ 
    public function searchAction(Request $request) { 
        $this->validarAdmin(); 
        $searchParam = $request->request->all();         
        $usuario = $this->getUser(); 
        $searchParam['tipo'] = 'operador';            
        $currentPage = $request->query->get('page'); 
        $sortField = $request->query->get('sort'); 
        $sortDirection = $request->query->get('direction'); 
        $currentPage = null == $currentPage ? 1 : $currentPage; 
        $offset = ($currentPage - 1) * 100; 
        $limit = 100; 
        try { 
            /** @var McCajaHandler $handler */ 
            $handler = $this->get(McCajaHandler::class); 
            $lp = $handler->search($offset, $limit, $sortField, $sortDirection, $searchParam); 
            $lp->setCurrentPage($currentPage); 
            $lp->setPageSize(100); 
            $this->response->setData($lp); 
            $this->response->setCode(Codes::OK); 
        } catch (Exception $e) { 
            $this->response->setCode(Codes::ERROR); 
            $this->response->setMessage($e->getMessage()); 
        } 
        $serializedEntity = $this->container->get('serializer')->serialize($this->response, 'json'); 
        return new Response($serializedEntity); 
    } 
 
    /** 
     * @Route("/admin/cajas/nueva", name="admin_cajas_nueva") 
     * @return type 
     */ 
    public function cajaNuevoAction() { 
        $this->validarAdmin(); 
        $this->setTitle("Nueva Caja"); 
        $this->addBreadCrumb("Inicio - Admin ", false, "admin_home"); 
        $this->addBreadCrumb("Listado de cajas", false, "admin_cajas_listado"); 
        $this->addBreadCrumb("Nueva caja", true);      
        $monedas = $this->get(McMonedaHandler::class)->getAllMonedas(); 
        $this->data['data'] = null; 
        $this->data['monedas'] = $monedas;        
        return $this->render( 
                        '@NoahtechSistemasInterjama/admin/cajas/nueva.html.twig', $this->data 
        ); 
    } 
 
    /** 
     * Guarda una caja de operador de aduana 
     * 
     * @Route("/admin/ajax/cajas", name="admin_caja_save", methods={"POST"}, condition="request.isXmlHttpRequest()") 
     */ 
    public function postSaveAction(Request $request) { 
        $this->validarAdmin(); 
        $operadorOpen = $this->getUser(); 
        try { 
            $handler = $this->get(McCajaHandler::class);             
            $caja = $handler->getCajaFromRequest($request, $operadorOpen, 'operador'); 
            $result = $handler->save($request, $caja); 
            $this->response->setData($result); 
            $this->response->setCode(Codes::OK);             
        } catch (Exception $e) { 
            $this->response->setCode(Codes::ERROR); 
            $this->response->setMessage($e->getMessage()); 
        } 
        $serializedEntity = $this->container->get('serializer')->serialize($this->response, 'json'); 
        return new Response($serializedEntity);        
    } 
 
    /** 
     * @Route("/admin/cajas/{id}", name="admin_cajas_modificacion") 
     * @return type 
     */ 
    public function cajaModificacionAction($id) { 
        $this->validarAdmin(); 
        $this->validarCajaCerrada($id); 
        $this->setTitle("Modificar caja"); 
        $this->addBreadCrumb("Inicio - Admin ", false, "admin_home"); 
        $this->addBreadCrumb("Listado de cajas", false, "admin_cajas_listado"); 
        $this->addBreadCrumb("Modificar caja", true);         
        $monedas = $this->get(McMonedaHandler::class)->getAllMonedas(); 
        $this->data['data'] = $id; 
        $this->data['monedas'] = $monedas; 
        return $this->render( 
                        '@NoahtechSistemasInterjama/admin/cajas/modificacion.html.twig', $this->data 
        ); 
    } 
 
    /** 
     * Devuelve un caja 
     * 
     * @Route("/admin/ajax/cajas/{id}", name="admin_ajax_caja_get_by_id", methods={"GET"}, condition="request.isXmlHttpRequest()") 
     */ 
    public function getcajaByIdAction($id) { 
        $this->validarAdmin(); 
        try { 
            $handler = $this->get(McCajaHandler::class); 
            $caja = $handler->getById($id); 
            $this->response->setData($caja); 
            $this->response->setCode(Codes::OK); 
        } catch (Exception $e) { 
            $this->response->setCode(Codes::ERROR); 
            $this->response->setMessage($e->getMessage()); 
        } 
        $serializedEntity = $this->container->get('serializer')->serialize($this->response, 'json'); 
        return new Response($serializedEntity); 
    } 
 
    /** 
     * Modifica una caja 
     * 
     * @Route("/admin/ajax/cajas/{id}", name="admin_ajax_caja_update", methods={"PUT"}, condition="request.isXmlHttpRequest()") 
     */ 
    public function putUpdateAction(Request $request, $id) { 
        $this->validarAdmin(); 
        $this->validarCajaCerrada($id); 
        $data = $request->request->all(); 
        $operadorOpen = $this->getUser(); 
        try { 
            $handler = $this->get(McCajaHandler::class);         
            $caja = $handler->getcajaFromRequest($request, $operadorOpen, 'operador', $id);         
            $result = $handler->update($request, $caja, $id); 
            $this->response->setData($result); 
            $this->response->setCode(Codes::OK); 
        } catch (Exception $e) { 
            $this->response->setCode(Codes::ERROR); 
            $this->response->setMessage($e->getMessage()); 
        } 
        $serializedEntity = $this->container->get('serializer')->serialize($this->response, 'json'); 
        return new Response($serializedEntity); 
    } 
 
    /** 
     * Modifica el estado de una caja 
     * 
     * @Route("/admin/ajax/cajas/{id}/estado", name="admin_ajax_caja_update_esatado", methods={"PUT"}, condition="request.isXmlHttpRequest()") 
     */ 
    public function putUpdateEstadoAction(Request $request, $id) { 
        $this->validarAdmin(); 
        $data = $request->request->all(); 
        $operadorClose = $this->getUser(); 
        try { 
            $handler = $this->get(McCajaHandler::class);         
            $caja = $handler->getCajaEstadoFromRequest($request, $operadorClose, 'operador', $id);         
            $result = $handler->update($request, $caja, $id); 
            $this->response->setData($result); 
            $this->response->setCode(Codes::OK); 
        } catch (Exception $e) { 
            $this->response->setCode(Codes::ERROR); 
            $this->response->setMessage($e->getMessage()); 
        } 
        $serializedEntity = $this->container->get('serializer')->serialize($this->response, 'json'); 
        return new Response($serializedEntity); 
    } 
 
    /** 
     *  
     * Descarga recibo de caja cerrada 
     *  
     * @Route("/admin/ajax/cajas/{cajaId}/descarga", name="admin_ajax_caja_recibo_descarga") 
     *  
     */ 
    public function descargaReciboCajaAction($cajaId) { 
        try {  
           $this->validarAdmin(); 
           $this->validarDescargaCaja($cajaId); 
           return $this->get(McCajaHandler::class)->descargaReciboCajaPdf($cajaId); 
        } catch (Exception $e) { 
           return $e->getMessage(); 
        } 
   } 
   /** SecciĂ³n moviemientos */ 
 
   /** 
     * @Route("/admin/caja/{cajaId}/movimientos", name="admin_caja_movimientos_listado") 
     * @return type 
     */ 
    public function movimientosListadoAction($cajaId) { 
        $this->validarAdmin(); 
        $usuario = $this->getUser(); 
        $this->validarCajaCerrada($cajaId); 
        $this->setTitle("Listado de movimientos | InterJama"); 
        $this->addBreadCrumb("Inicio - Admin", false, "admin_home"); 
        $this->addBreadCrumb("Listado de cajas", false, "admin_cajas_listado"); 
        $this->addBreadCrumb("Listado de movimientos", true); 
        $this->data['data'] = null; 
        $this->data['caja'] = $cajaId; 
        return $this->render( 
                        '@NoahtechSistemasInterjama/admin/cajas/movimientos/listado.html.twig', $this->data 
        ); 
    } 
 
    /** 
     * consulta de cajas 
     * 
     * @Route("/admin/ajax/caja/{cajaId}/movimientos/search", name="admin_ajax_caja_movimientos_listado", methods={"POST"}, condition="request.isXmlHttpRequest()") 
     */ 
    public function searchMovimientosAction(Request $request, $cajaId) { 
        $this->validarAdmin(); 
        $searchParam = $request->request->all(); 
        $searchParam['caja'] = $cajaId;         
        $usuario = $this->getUser();              
        $currentPage = $request->query->get('page'); 
        $sortField = $request->query->get('sort'); 
        $sortDirection = $request->query->get('direction'); 
        $currentPage = null == $currentPage ? 1 : $currentPage; 
        $offset = ($currentPage - 1) * 100; 
        $limit = 100; 
        try { 
            /** @var McMovimientoHandler $handler */ 
            $handler = $this->get(McMovimientoHandler::class); 
            $lp = $handler->search($offset, $limit, $sortField, $sortDirection, $searchParam); 
            $lp->setCurrentPage($currentPage); 
            $lp->setPageSize(100); 
            $this->response->setData($lp); 
            $this->response->setCode(Codes::OK); 
        } catch (Exception $e) { 
            $this->response->setCode(Codes::ERROR); 
            $this->response->setMessage($e->getMessage()); 
        } 
        $serializedEntity = $this->container->get('serializer')->serialize($this->response, 'json'); 
        return new Response($serializedEntity); 
    } 
 
    /** 
     * @Route("/admin/caja/{cajaId}/movimientos/nuevo", name="admin_caja_movimientos_nuevo") 
     * @return type 
     */ 
    public function movimientoNuevoAction($cajaId) { 
        $this->validarAdmin(); 
        $this->validarCajaCerrada($cajaId); 
        $this->setTitle("Nuevo Movimiento"); 
        $this->addBreadCrumb("Inicio - Admin", false, "admin_home"); 
        $this->addBreadCrumb("Listado de cajas", false, "admin_cajas_listado"); 
        $this->addBreadCrumb("Listado de movimientos", false, "admin_caja_movimientos_listado", array('cajaId' =>$cajaId)); 
        $this->addBreadCrumb("Nuevo Movimiento", true); 
        $monedas = $this->get(McCajaMonedaHandler::class)->getAllMonedasByCaja($cajaId); 
        $divisas = $this->get(McDivisaHandler::class)->getAllDivisas(); 
        $this->data['data'] = null; 
        $this->data['caja'] = $cajaId; 
        $this->data['monedas'] = $monedas; 
        $this->data['divisas'] = $divisas; 
        return $this->render( 
                        '@NoahtechSistemasInterjama/admin/cajas/movimientos/nuevo.html.twig', $this->data 
        ); 
    } 
 
    /** 
     * Guarda un movimiento de una caja 
     * 
     * @Route("/admin/ajax/caja/{cajaId}/movimientos", name="admin_caja_movimiento_save", methods={"POST"}, condition="request.isXmlHttpRequest()") 
     */ 
    public function postMovimientoSaveAction(Request $request, $cajaId) { 
        $this->validarAdmin(); 
        $usuario = $this->getUser(); 
        $this->validarCajaCerrada($cajaId); 
        try { 
            $handler = $this->get(McMovimientoHandler::class); 
            $result = $handler->getMovimientoFromRequest($request, $usuario, $cajaId); 
            $this->response->setData($result); 
            $this->response->setCode(Codes::OK);             
        } catch (Exception $e) { 
            $this->response->setCode(Codes::ERROR); 
            $this->response->setMessage($e->getMessage()); 
        } 
        $serializedEntity = $this->container->get('serializer')->serialize($this->response, 'json'); 
        return new Response($serializedEntity);        
    } 
 
    /** 
     * Devuelve un chofer segun el termino de busqueda 
     * 
     * @Route("/admin/ajax/choferes/search/By/Termino", name="admin_ajax_chofer_search_by_termino", methods={"GET"}, condition="request.isXmlHttpRequest()") 
     */ 
    public function searchChoferByTerminoAction(Request $request) { 
        $this->validarAdmin(); 
        $userCurrent = $this->getUser(); 
        $searchParam = $request->query->get('q'); 
        try { 
            $handler = $this->get(McChoferHandler::class); 
            $choferes = $handler->searchChoferesByTermino($searchParam); 
            $this->response->setData($choferes); 
            $this->response->setCode(Codes::OK); 
        } catch (Exception $e) { 
            $this->response->setCode(Codes::ERROR); 
            $this->response->setMessage($e->getMessage()); 
        } 
        $serializedEntity = $this->container->get('serializer')->serialize($this->response, 'json'); 
        return new Response($serializedEntity); 
    } 
 
    /** 
     * Devuelve todos los clientes 
     * 
     * @Route("/admin/ajax/clientes/all", name="admin_ajax_clientes_all", methods={"GET"}, condition="request.isXmlHttpRequest()") 
     */ 
    public function searchClientesAction() { 
        $this->validarAdmin(); 
        $userCurrent = $this->getUser(); 
        try { 
            $handler = $this->get(McClienteHandler::class); 
            $choferes = $handler->getClientes(); 
            $this->response->setData($choferes); 
            $this->response->setCode(Codes::OK); 
        } catch (Exception $e) { 
            $this->response->setCode(Codes::ERROR); 
            $this->response->setMessage($e->getMessage()); 
        } 
        $serializedEntity = $this->container->get('serializer')->serialize($this->response, 'json'); 
        return new Response($serializedEntity); 
    } 
 
    /** 
     * Guarda un chofer 
     * 
     * @Route("/admin/ajax/chofer", name="admin_ajax_chofer_save", methods={"POST"}, condition="request.isXmlHttpRequest()") 
     */ 
    public function registrarChoferAction(Request $request) { 
        $this->validarAdmin(); 
        $this->validarChofer($request->request->get('tipo'), $request->request->get('numero')); 
        try { 
            $handler = $this->get(McChoferHandler::class);             
            $chofer = $handler->getChoferFromRequest($request); 
            $result = $handler->save($chofer); 
            $this->response->setData($result); 
            $this->response->setCode(Codes::OK);             
        } catch (Exception $e) { 
            $this->response->setCode(Codes::ERROR); 
            $this->response->setMessage($e->getMessage()); 
        } 
        $serializedEntity = $this->container->get('serializer')->serialize($this->response, 'json'); 
        return new Response($serializedEntity);        
    } 
 
    /** 
     * @Route("/admin/caja/{cajaId}/movimientos/{movimientoId}", name="admin_caja_movimientos_modificacion") 
     * @return type 
     */ 
    public function movimientoModificacionAction($cajaId, $movimientoId) { 
        $this->validarAdmin(); 
        $this->validarCajaCerrada($cajaId); 
        $this->validarMovimiento($cajaId, $movimientoId); 
        $this->setTitle("Modificar movimiento"); 
        $this->addBreadCrumb("Inicio - Admin", false, "admin_home"); 
        $this->addBreadCrumb("Listado de cajas", false, "admin_cajas_listado"); 
        $this->addBreadCrumb("Listado de movimientos", false, "admin_caja_movimientos_listado", array('cajaId' =>$cajaId)); 
        $this->addBreadCrumb("Modificar movimiento", true);         
        $monedas = $this->get(McCajaMonedaHandler::class)->getAllMonedasByCaja($cajaId); 
        $this->data['data'] = $movimientoId; 
        $this->data['caja'] = $cajaId; 
        $this->data['monedas'] = $monedas; 
        return $this->render( 
                        '@NoahtechSistemasInterjama/admin/cajas/movimientos/modificacion.html.twig', $this->data 
        ); 
    } 
 
    /** 
     * Devuelve un movimiento 
     * 
     * @Route("/admin/ajax/caja/{cajaId}/movimientos/{id}", name="admin_ajax_caja_movimiento_get_by_id", methods={"GET"}, condition="request.isXmlHttpRequest()") 
     */ 
    public function getMovimientoByIdAction($cajaId, $id) { 
        $this->validarAdmin(); 
        $this->validarCajaCerrada($cajaId); 
        $this->validarMovimiento($cajaId, $id); 
        try { 
            $handler = $this->get(McMovimientoHandler::class); 
            $movimiento = $handler->getById($id); 
            $this->response->setData($movimiento); 
            $this->response->setCode(Codes::OK); 
        } catch (Exception $e) { 
            $this->response->setCode(Codes::ERROR); 
            $this->response->setMessage($e->getMessage()); 
        } 
        $serializedEntity = $this->container->get('serializer')->serialize($this->response, 'json'); 
        return new Response($serializedEntity); 
    } 
 
    /** 
     * Edita un movimiento de una caja 
     * 
     * @Route("/admin/ajax/caja/{cajaId}/movimientos/{movimientoId}", name="admin_caja_movimiento_update", methods={"PUT"}, condition="request.isXmlHttpRequest()") 
     */ 
    public function putMovimientoSaveAction(Request $request, $cajaId, $movimientoId) { 
        $this->validarAdmin(); 
        $usuario = $this->getUser(); 
        $this->validarCajaCerrada($cajaId); 
        $this->validarMovimiento($cajaId, $movimientoId); 
        try { 
            $handler = $this->get(McMovimientoHandler::class); 
            $movimiento = $handler->getMovimientoFromRequest($request, $usuario, $cajaId, $movimientoId); 
            $result = $handler->update($movimiento, $movimientoId); 
            $this->response->setData($result); 
            $this->response->setCode(Codes::OK);             
        } catch (Exception $e) { 
            $this->response->setCode(Codes::ERROR); 
            $this->response->setMessage($e->getMessage()); 
        } 
        $serializedEntity = $this->container->get('serializer')->serialize($this->response, 'json'); 
        return new Response($serializedEntity);        
    } 
    
}