<?php

namespace App\Controllers\Presupuestos;

use App\Controllers\GoBaseResourceController;
use App\Entities\Configuracion\Maquina;
use App\Models\Collection;

use App\Entities\Presupuestos\PresupuestoEntity;
use App\Models\Presupuestos\PresupuestoDireccionesModel;
use App\Models\Configuracion\PapelGenericoModel;
use App\Models\Configuracion\TipoPresupuestoModel;
use App\Models\Presupuestos\PresupuestoModel;
use App\Models\Presupuestos\PresupuestoLineaModel;

use App\Models\Presupuestos\PresupuestoEncuadernacionesModel;
use App\Models\Presupuestos\PresupuestoAcabadosModel;
use App\Models\Presupuestos\PresupuestoManipuladosModel;
use App\Models\Presupuestos\PresupuestoPreimpresionesModel;

use App\Services\PresupuestoService;
use App\Models\Configuracion\PapelImpresionModel;
use App\Models\Configuracion\MaquinaModel;
use App\Models\Configuracion\MaquinasTarifasImpresionModel;
use App\Models\Clientes\ClientePreciosModel;
use Exception;

class Cosidotapablanda extends \App\Controllers\GoBaseResourceController
{

    protected $modelName = "PresupuestoModel";
    protected $format = 'json';

    protected static $singularObjectName = 'Cosido Tapa Blanda';
    protected static $singularObjectNameCc = 'Cosidotapablanda';
    protected static $pluralObjectName = 'Cosidos Tapa Blanda';
    protected static $pluralObjectNameCc = 'cosidosTapaBlanda';

    protected static $controllerSlug = 'cosidotapablanda';

    protected static $viewPath = 'themes/backend/vuexy/form/presupuestos/cosidotapablanda/';

    protected $indexRoute = 'cosidotapablandaList';



    public function initController(\CodeIgniter\HTTP\RequestInterface $request, \CodeIgniter\HTTP\ResponseInterface $response, \Psr\Log\LoggerInterface $logger)
    {

        $this->viewData['pageTitle'] = lang('Presupuestos.moduleTitleCosidoTB');
        $this->viewData['usingSweetAlert'] = true;

        // Se indica que este controlador trabaja con soft_delete
        $this->soft_delete = true;
        // Se indica el flag para los ficheros borrados
        $this->delete_flag = 1;

        $this->viewData = ['usingServerSideDataTable' => true]; // JJO

        // Breadcrumbs
        $this->viewData['breadcrumb'] = [
            ['title' => lang("App.menu_presupuestos"), 'route' => "javascript:void(0);", 'active' => false],
            ['title' => lang("App.menu_libros_cosido_tapa_blanda"), 'route' => site_url('presupuestos/cosidotapablanda'), 'active' => true]
        ];

        parent::initController($request, $response, $logger);
        $this->model = new PresupuestoModel();
    }


    public function index()
    {

        $viewData = [
            'currentModule' => static::$controllerSlug,
            'pageSubTitle' => lang('Basic.global.ManageAllRecords', [lang('Presupuestos.presupuesto')]),
            'presupuestoEntity' => new PresupuestoEntity(),
            'usingServerSideDataTable' => true,

        ];

        $viewData = array_merge($this->viewData, $viewData); // merge any possible values from the parent controller class

        return view(static::$viewPath . 'viewCosidotapablandaList', $viewData);
    }


    public function add()
    {

        // JJO
        $session = session();

        $requestMethod = $this->request->getMethod();

        if ($requestMethod === 'post') :

            $nullIfEmpty = true; // !(phpversion() >= '8.1');

            $postData = $this->request->getPost();

            $sanitizedData = $this->sanitized($postData, $nullIfEmpty);

            // JJO
            $sanitizedData['user_created_id'] = $session->id_user;

            $noException = true;
            if ($successfulResult = $this->canValidate($this->model->validationRulesAdd, $this->model->validationMessagesAdd)) : // if ($successfulResult = $this->validate($this->formValidationRules) ) :

                if ($this->canValidate($this->model->validationRulesAdd, $this->model->validationMessagesAdd)) :
                    try {
                        $successfulResult = $this->model->skipValidation(true)->save($sanitizedData);
                    } catch (\Exception $e) {
                        $noException = false;
                        $this->dealWithException($e);
                    }
                else :
                    $this->viewData['errorMessage'] = lang('Basic.global.formErr1', [mb_strtolower(lang('Presupuestos.presupuesto'))]);
                    $this->session->setFlashdata('formErrors', $this->model->errors());
                endif;

                $thenRedirect = true;  // Change this to false if you want your user to stay on the form after submission
            endif;
            if ($noException && $successfulResult) :

                $id = $this->model->db->insertID();

                $message = lang('Basic.global.saveSuccess', [lang('Basic.global.record')]) . '.';

                if ($thenRedirect) :
                    if (!empty($this->indexRoute)) :
                        //return redirect()->to(route_to( $this->indexRoute )  )->with('sweet-success', $message);
                        return redirect()->to(site_url('presupuestos/cosidotapablanda/edit/' . $id))->with('sweet-success', $message);
                    else :
                        return $this->redirect2listView('sweet-success', $message);
                    endif;
                else :
                    $this->session->setFlashData('sweet-success', $message);
                endif;

            endif; // $noException && $successfulResult

        endif; // ($requestMethod === 'post')

        $this->viewData['tipo_impresion_id'] = 4; // Cosido tapa blanda JJO
        $this->viewData['presupuestoEntity'] = isset($sanitizedData) ? new PresupuestoEntity($sanitizedData) : new PresupuestoEntity();
        $this->viewData['isCosido'] = (new TipoPresupuestoModel())->get_isCosido($this->viewData['tipo_impresion_id']);

        $this->viewData['clienteList'] = $this->getClienteListItems($presupuestoEntity->cliente_id ?? null);
        $this->viewData['incReiList'] = array('incidencia' => lang('Presupuestos.incidencia'), 'reimpresion' => lang('Presupuestos.reimpresion'), 'sin_cargo' => lang('Presupuestos.sinCargo'));
        $this->viewData['paisList'] = $this->getPaisListItems();
        $this->viewData['papelFormatoList'] = $this->getPapelFormatoListItems($presupuestoEntity->papel_formato_id ?? null);

        $this->viewData['POD'] = $this->getPOD();

        $this->viewData['formAction'] = route_to('createCosidotapablanda');

        $this->viewData['boxTitle'] = lang('Basic.global.addNew') . ' ' . lang('Presupuestos.moduleTitleCosidoTB') . ' ' . lang('Basic.global.addNewSuffix');

        return $this->displayForm(__METHOD__);
    } // end function add()

    public function edit($requestedId = null)
    {

             // JJO
            $session = session();

            if ($requestedId == null) :
                return $this->redirect2listView();
            endif;
            $id = filter_var($requestedId, FILTER_SANITIZE_URL);
            $presupuestoEntity = $this->model->find($id);

            if ($presupuestoEntity == false) :
                $message = lang('Basic.global.notFoundWithIdErr', [mb_strtolower(lang('Presupuestos.presupuesto')), $id]);
                return $this->redirect2listView('sweet-error', $message);
            endif;

            $requestMethod = $this->request->getMethod();

            if ($requestMethod === 'post') :

                $nullIfEmpty = true; // !(phpversion() >= '8.1');

                $postData = $this->request->getPost();

                $postData['updated_at'] = gmdate('Y-m-d H:m:s', time());

                $sanitizedData = $this->sanitized($postData, $nullIfEmpty);
                
                // JJO
                $sanitizedData['user_updated_id'] = $session->id_user;

                if ($this->request->getPost('retractilado') == null) {
                    $sanitizedData['retractilado'] = false;
                }
                if ($this->request->getPost('retractilado5') == null) {
                    $sanitizedData['retractilado5'] = false;
                }
                if ($this->request->getPost('ferro') == null) {
                    $sanitizedData['ferro'] = false;
                }
                if ($this->request->getPost('ferro_digital') == null) {
                    $sanitizedData['ferro_digital'] = false;
                }
                if ($this->request->getPost('prototipo') == null) {
                    $sanitizedData['prototipo'] = false;
                }
                if ($this->request->getPost('marcapaginas') == null) {
                    $sanitizedData['marcapaginas'] = false;
                }
                if ($this->request->getPost('faja_color') == null) {
                    $sanitizedData['faja_color'] = false;
                }

                $noException = true;
                if ($successfulResult = $this->canValidate()) : // if ($successfulResult = $this->validate($this->formValidationRules) ) :



                    if ($this->canValidate()) :
                        try {
                            $successfulResult = $this->model->skipValidation(true)->update($id, $sanitizedData);
                        } catch (\Exception $e) {
                            $noException = false;
                            $this->dealWithException($e);
                        }
                    else :
                        $this->viewData['warningMessage'] = lang('Basic.global.formErr1', [mb_strtolower(lang('Presupuestos.presupuesto'))]);
                        $this->session->setFlashdata('formErrors', $this->model->errors());

                    endif;

                    $presupuestoEntity->fill($sanitizedData);

                    $thenRedirect = false;
                endif;
                if ($noException && $successfulResult) :
                    $id = $presupuestoEntity->id ?? $id;
                    $message = lang('Basic.global.updateSuccess', [mb_strtolower(lang('Presupuestos.presupuesto'))]) . '.';
                   // $message .= anchor("admin/presupuestos/{$id}/edit", lang('Basic.global.continueEditing') . '?');
                    //$message = ucfirst(str_replace("'", "\'", $message));

                    if ($thenRedirect) :
                        if (!empty($this->indexRoute)) :
                            return redirect()->to(route_to($this->indexRoute))->with('sweet-success', $message);
                        else :
                            if ($this->request->isAJAX()) {
                                $newTokenHash = csrf_hash();
                                $csrfTokenName = csrf_token();
                                $data = [
                                    'mensaje' => $message,
                                    $csrfTokenName => $newTokenHash
                                ];
                                return $this->respond($data);
                            }
                            else{
                                return $this->redirect2listView('sweet-success', $message);
                            }
                            
                        endif;
                    else :
                        if ($this->request->isAJAX()) {
                            $newTokenHash = csrf_hash();
                            $csrfTokenName = csrf_token();
                            $data = [
                                'mensaje' => $message,
                                $csrfTokenName => $newTokenHash
                            ];
                            return $this->respond($data);
                        }
                        else{
                            $this->session->setFlashData('sweet-success', $message);
                        }
                    endif;

                endif; // $noException && $successfulResult
            endif; // ($requestMethod === 'post')


        $this->viewData['presupuestoEntity'] = $presupuestoEntity;
        $this->viewData['isCosido'] = (new TipoPresupuestoModel())->get_isCosido($presupuestoEntity->tipo_impresion_id);

        if(!is_null($presupuestoEntity->comparador_json_data))
            $this->viewData['comp_data'] = json_decode($presupuestoEntity->comparador_json_data);
        else
            $this->viewData['comp_data'] = "";

        $this->viewData['clienteList'] = $this->getClienteListItems($presupuestoEntity->cliente_id ?? null);
        $this->viewData['paisList'] = $this->getPaisListItems();
        $this->viewData['ccaaList'] = $this->getCcaaListItems();

        $this->viewData['clienteList'] = $this->getClienteListItems($presupuestoEntity->cliente_id ?? null);
        $this->viewData['incReiList'] = array('incidencia' => lang('Presupuestos.incidencia'), 'reimpresion' => lang('Presupuestos.reimpresion'), 'sin_cargo' => lang('Presupuestos.sinCargo'));
        $this->viewData['papelFormatoList'] = $this->getPapelFormatoListItems($presupuestoEntity->papel_formato_id ?? null);
        $this->viewData['papelGenericoNegroList'] = $this->getPapelGenericoNegro();
        $this->viewData['papelGenericoNegroHQList'] = $this->getPapelGenericoNegroHQ();
        $this->viewData['papelGenericoColorList'] = $this->getPapelGenericoColor();
        $this->viewData['papelGenericoColorHQList'] = $this->getPapelGenericoColorHQ();
        $this->viewData['papelGenericoCubiertaList'] = $this->getPapelGenericoCubierta();
        $this->viewData['papelGenericoSobrecubiertaList'] = $this->getPapelGenericoSobreCubierta();
        $this->viewData['papelGenericoRotativaNegroList'] = $this->getPapelGenericoRotativaNegro();
        $this->viewData['papelGenericoRotativaColorList'] = $this->getPapelGenericoRotativaColor();

        // Lineas Presupuesto
        $this->viewData['lineasPresupuesto'] = (new PresupuestoLineaModel())->getLineasPresupuesto($id);

        // Tarifas
        $this->viewData['serviciosAcabado'] = $this->getServiciosAcabado();
        $this->viewData['serviciosPreimpresion'] = $this->getServiciosPreimpresion();
        $this->viewData['serviciosEncuadernacion'] = $this->getServiciosEncuadernacion();
        $this->viewData['serviciosManipulado'] = $this->getServiciosManipulado();
        $this->viewData['serviciosEncuadernacionList'] = (new PresupuestoEncuadernacionesModel())->getResource($id)->get()->getResultObject();
        $this->viewData['serviciosAcabadosList'] = (new PresupuestoAcabadosModel())->getResource($id)->get()->getResultObject();
        $this->viewData['serviciosManipuladoList'] = (new PresupuestoManipuladosModel())->getResource($id)->get()->getResultObject();
        $this->viewData['serviciosPreimpresionList'] = (new PresupuestoPreimpresionesModel())->getResource($id)->get()->getResultObject();

        // Direciones presupuesto
        $this->viewData['presupuestoDirecciones'] = (new PresupuestoDireccionesModel())->getResource("",$id)->get()->getResultObject();

        $this->viewData['POD'] = $this->getPOD();

        $this->viewData['serviciosCheckboxes'] = [
            'retractilado' => 3,
            'retractilado5' => 5,
            'ferro' => 24,
            'prototipo' => 9,
            'fajaColor' => 16,
        ];

        $this->viewData['tipo_impresion_id'] = 4; // Cosido tapa blanda JJO

        $this->viewData['formAction'] = route_to('updateCosidotapablanda', $id);

        $this->viewData['boxTitle'] = lang('Basic.global.edit2') . ' ' . lang('Presupuestos.moduleTitleCosidoTB') . ' ' . lang('Basic.global.edit3');


        return $this->displayForm(__METHOD__, $id);
    } // end function edit(...)



    public function datatable()
    {
        if ($this->request->isAJAX()) {
            $reqData = $this->request->getPost();

            $type = $reqData['type'] ?? null;
            
            if (is_null($type)) {
                if (!isset($reqData['draw']) || !isset($reqData['columns'])) {
                    $errstr = 'No data available in response to this specific request.';
                    $response = $this->respond(Collection::datatable([], 0, 0, $errstr), 400, $errstr);
                    return $response;
                }
                $search = $reqData['search']['value'];
            }
            $start = $reqData['start'] ?? 0;
            $length = $reqData['length'] ?? 5;
            
            $requestedOrder1 = $reqData['order']['0']['column'] ?? 0;
            $order1 = PresupuestoModel::SORTABLE[$requestedOrder1 >= 0 ? $requestedOrder1 : 0];
            $dir1 = $reqData['order']['0']['dir'] ?? 'asc';
            $requestedOrder2 = $reqData['order']['1']['column'] ?? 0;
            $order2 = PresupuestoModel::SORTABLE[$requestedOrder2 >= 0 ? $requestedOrder1 : 0];
            $dir2 = $reqData['order']['0']['dir'] ?? 'asc';
            $requestedOrder3 = $reqData['order']['2']['column'] ?? 0;
            $order3 = PresupuestoModel::SORTABLE[$requestedOrder3 >= 0 ? $requestedOrder1 : 0];
            $dir3 = $reqData['order']['0']['dir'] ?? 'asc';


            if (is_null($type)) {

                $searchValues = get_filter_datatables_columns($reqData);
                
                $resourceData = $this->model->getResource($searchValues)->orderBy($order1, $dir1)->orderBy($order2, $dir2)
                    ->orderBy($order3, $dir3)->limit($length, $start)->get()->getResultObject();
                foreach ($resourceData as $item) :
                    if (isset($item->comentarios_pdf) && strlen($item->comentarios_pdf) > 100) :
                        $item->comentarios_pdf = character_limiter($item->comentarios_pdf, 100);
                    endif;
                    if (isset($item->causa_cancelacion) && strlen($item->causa_cancelacion) > 100) :
                        $item->causa_cancelacion = character_limiter($item->causa_cancelacion, 100);
                    endif;
                    if (isset($item->comentarios_cliente) && strlen($item->comentarios_cliente) > 100) :
                        $item->comentarios_cliente = character_limiter($item->comentarios_cliente, 100);
                    endif;
                    if (isset($item->comentarios_safekat) && strlen($item->comentarios_safekat) > 100) :
                        $item->comentarios_safekat = character_limiter($item->comentarios_safekat, 100);
                    endif;
                    if (isset($item->comentarios_tarifa) && strlen($item->comentarios_tarifa) > 100) :
                        $item->comentarios_tarifa = character_limiter($item->comentarios_tarifa, 100);
                    endif;
                    if (isset($item->comentarios_produccion) && strlen($item->comentarios_produccion) > 100) :
                        $item->comentarios_produccion = character_limiter($item->comentarios_produccion, 100);
                    endif;
                    if (isset($item->tirada_alternativa_json_data) && strlen($item->tirada_alternativa_json_data) > 100) :
                        $item->tirada_alternativa_json_data = character_limiter($item->tirada_alternativa_json_data, 100);
                    endif;
                    if (isset($item->titulo) && strlen($item->titulo) > 100) :
                        $item->titulo = character_limiter($item->titulo, 100);
                    endif;
                    if (isset($item->paginas_color_posicion) && strlen($item->paginas_color_posicion) > 100) :
                        $item->paginas_color_posicion = character_limiter($item->paginas_color_posicion, 100);
                    endif;
                    if (isset($item->aprobado_json_data) && strlen($item->aprobado_json_data) > 100) :
                        $item->aprobado_json_data = character_limiter($item->aprobado_json_data, 100);
                    endif;
                    if (isset($item->comparador_json_data) && strlen($item->comparador_json_data) > 100) :
                        $item->comparador_json_data = character_limiter($item->comparador_json_data, 100);
                    endif;
                    if (isset($item->ws_externo_json_data) && strlen($item->ws_externo_json_data) > 100) :
                        $item->ws_externo_json_data = character_limiter($item->ws_externo_json_data, 100);
                    endif;
                endforeach;
            } else {

                $isColor = $reqData['color'] ?? false;
                $isHq = $reqData['hq'] ?? false;
                    
                $datosPedido = (object)array(
                    'paginas' => intval($reqData['paginas']) ?? 0,
                    'tirada' => intval($reqData['tirada']) ?? 0,
                    'merma' => intval($reqData['merma']) ?? 0,
                    'ancho' => intval($reqData['ancho']) ?? 100000,
                    'alto' => intval($reqData['alto']) ?? 100000,
                    'isCosido' => true, // JJO esto es custom por cada tipo de presupuesto
                );

                $papel_generico = [
                    'id' => $reqData['papel_generico_id'] ?? 0,
                    'nombre' => $reqData['papel_generico'] ?? "",
                ];
                
                $gramaje = $reqData['gramaje'] ?? 0;

                $cliente_id = $reqData['cliente_id'] ?? -1;
                
                

                if ($type=='interior') {

                    $datosTipolog = $reqData['negro'] ?? null;
                    if(!is_null($datosTipolog)){
                        $datosTipolog = [];
                        $data = (object)array(
                            'negro' => intval($reqData['negro']) ?? 0,
                            'cyan' => intval($reqData['cyan']) ?? 0,
                            'magenta' => intval($reqData['magenta']) ?? 0,
                            'amarillo' => intval($reqData['amarillo']) ?? 0,
                            'gota_negro' => intval($reqData['gota_negro']) ?? 0,
                            'gota_color' => intval($reqData['gota_color']) ?? 0,
                        );  
                        array_push($datosTipolog, $data);
                    }

                    $resourceData = $this->getCompIntData($type, $datosPedido, $papel_generico, $gramaje, $isColor, $isHq, $cliente_id, $datosTipolog);
                    
                    $newTokenHash = csrf_hash();
                    $csrfTokenName = csrf_token();
                    $data = [
                        'lineas' => $resourceData,
                        $csrfTokenName => $newTokenHash
                    ];
                    
                    return $this->respond($data);
                }
                else if ($type=='interior_rot') {

                    $paginas = (object)array(
                        'negro' => intval($reqData['paginas_negro']) ?? 0,
                        'color' => intval($reqData['paginas_color']) ?? 0,
                    );

                    $datosTipolog = $reqData['negro'] ?? null;
                    if(!is_null($datosTipolog)){
                        $datosTipolog = [];
                        $data = (object)array(
                            'negro' => intval($reqData['negro']) ?? 0,
                            'cyan' => intval($reqData['cyan']) ?? 0,
                            'magenta' => intval($reqData['magenta']) ?? 0,
                            'amarillo' => intval($reqData['amarillo']) ?? 0,
                            'gota_negro' => intval($reqData['gota_negro']) ?? 0,
                            'gota_color' => intval($reqData['gota_color']) ?? 0,
                        );  
                        array_push($datosTipolog, $data);
                    }

                    $resourceData = $this->getCompIntRotData($datosPedido, $papel_generico, $gramaje, $paginas, $cliente_id, $datosTipolog);
                    
                    $newTokenHash = csrf_hash();
                    $csrfTokenName = csrf_token();
                    $data = [
                        'lineas' => $resourceData,
                        $csrfTokenName => $newTokenHash
                    ];
                    
                    return $this->respond($data);
                }
                else if ($type=='cubierta' || $type=='sobrecubierta') {
                    
                    $datosPedido->solapas = $reqData['solapas'];
                    $datosPedido->solapas_ancho = $reqData['solapas_ancho'];

                    // Cubierta y sobrecubierta siempre color HQ
                    $resourceData = $this->getCompIntData($type, $datosPedido, $papel_generico, $gramaje, $isColor, 1, $cliente_id);
                    
                    $newTokenHash = csrf_hash();
                    $csrfTokenName = csrf_token();
                    $data = [
                        'lineas' => $resourceData,
                        $csrfTokenName => $newTokenHash
                    ];
                    
                    return $this->respond($data);
                }


            }

            return $this->respond(Collection::datatable(
                $resourceData,
                $this->model->getResource()->countAllResults(),
                $this->model->getResource($search)->countAllResults()
            ));
        } else {
            return $this->failUnauthorized('Invalid request', 403);
        }
    }


    public function datatable_2()
    {
        if ($this->request->isAJAX()) {
            $reqData = $this->request->getPost();

            $tipo = $reqData['tipo'] ?? '';
            
            if($tipo=='lineasPresupuesto'){
            
                $model = model('App\Models\Presupuestos\PresupuestoLineaModel');
                
                $datos = $reqData['datos'] ?? null;
                $presupuesto_id = $reqData['presupuesto_id'] ?? -1;

                $model->where("presupuesto_id", $presupuesto_id)->delete();

                if($datos != null){

                    $model->insertLineasPresupuesto($presupuesto_id, $datos);
                }
                $newTokenHash = csrf_hash();
                $csrfTokenName = csrf_token();
                $data = [
                    $csrfTokenName => $newTokenHash
                ];
                
                return $this->respond($data);
            }

            $newTokenHash = csrf_hash();
            $csrfTokenName = csrf_token();
            $data = [
                $csrfTokenName => $newTokenHash
            ];
            
            return $this->respond($data);

        } else {
            return $this->failUnauthorized('Invalid request', 403);
        }
    }


    public function getCompIntData($uso, $datosPedido, $papel_generico, $gramaje, $isColor, $isHq, $cliente_id, $datosTipolog = null)
    {
        $tipo = $isColor? ($isHq?'colorhq':'color'): ($isHq?'negrohq':'negro');

        if( $uso == 'cubierta' ){
            $opciones_papel = array(
                'cubierta' => 1,
                //'color' => 1,
                'rotativa' => 0,
            );
        }
        else if ( $uso == 'sobrecubierta' ){
            $opciones_papel = array(
                'sobrecubierta' => 1,
                //'color' => 1,
                'rotativa' => 0,
            );
        }
        else if( $isColor ){
            $opciones_papel = array(
                'color' => 1,
                'rotativa' => 0,
            );
        }
        else{
            $opciones_papel = array(
                'bn' => 1,
                'rotativa' => 0,
            );
        }
        
        // Se obtienen los papeles disponibles
        $papelimpresionmodel = new PapelImpresionModel();
        $papeles = $papelimpresionmodel->getIdPapelesImpresionForPresupuesto(
            papel_generico_id: $papel_generico['id'],
            gramaje: $gramaje,
            options: $opciones_papel
        );

        $lineas = array();
        // Para cada papel, se obtienen las maquinas disponibles
        foreach ($papeles as $papel) {

            $maquinamodel = new MaquinaModel();
            $maquinas = $maquinamodel->getMaquinaImpresionForPresupuesto(
                is_rotativa: 0,
                tarifa_tipo: $tipo,
                uso_tarifa:  $uso,
                tirada: $datosPedido->tirada + $datosPedido->merma,
                papel_impresion_id: $papel->id,
            );

            // Se recorren las máquinas y se calcula el coste de linea por cada una
            foreach ($maquinas as $maquina) {

                if($maquina->is_inkjet){
                    $parametrosInkjet = (object)array(
                        'a_favor_fibra' => 1, // este parametro se cambia para comprobar 
                                              // en las dos direcciones (menos en rustica fresada que es siempre 1)
                        'bnPages' =>  $isColor?0:$datosPedido->paginas,
                        'colorPages' =>  $isColor?$datosPedido->paginas:0,
                        'rotativa_gota_negro' => 0,
                        'rotativa_gota_color' => 0,
                    );
                    
                    $papelImpresionTipologiaModel = new \App\Models\Configuracion\PapelImpresionTipologiaModel();
                    if(is_null($datosTipolog)){
                        $datosTipologias = $papelImpresionTipologiaModel
                            ->findTipologiasForPapelImpresion($papel->id, $parametrosInkjet->colorPages>0?'color':'negro')
                            ->get()->getResultObject();

                        
                        if(count($datosTipologias)==0){
                            continue;
                        }
                    }
                    else{
                        $datosTipologias = $datosTipolog;
                    }
                    
                    $parametrosInkjet->rotativa_gota_negro =  $datosTipologias[0]->gota_negro;
                    $parametrosInkjet->rotativa_gota_color =  $datosTipologias[0]->gota_color;
                    $parametrosInkjet->rotativa_negro =  $datosTipologias[0]->negro;
                    $parametrosInkjet->rotativa_cyan =  $datosTipologias[0]->cyan;
                    $parametrosInkjet->rotativa_magenta =  $datosTipologias[0]->magenta;
                    $parametrosInkjet->rotativa_amarillo =  $datosTipologias[0]->amarillo;
                }

                $tarifamodel = new MaquinasTarifasImpresionModel();
                [$tarifaId, $tarifa] = $tarifamodel->getTarifa($maquina->maquina_id, $uso, $tipo);
                if(!is_float($tarifa)){
                    continue;
                }

                if($maquina->is_inkjet){
                    $linea['fields'] = PresupuestoService::getCostesLineaRotativa($maquina, $papel, $datosPedido,  $parametrosInkjet);
                    [$precio_pliego_impresion, $margen_pliego_impresion] = PresupuestoService::getPrecioPliego($maquina, $papel, $datosPedido->paginas);
                    $linea['fields']['precios_pliegos'] = $precio_pliego_impresion;
                    $linea['fields']['precio_libro'] = $linea['fields']['pliegos_libro'] * $precio_pliego_impresion;
                    $linea['fields']['a_favor_fibra'] = $parametrosInkjet->a_favor_fibra;
                    $linea['fields']['paginas_color'] = $isColor?$datosPedido->paginas:0;
                    $linea['fields']['datosTipologias'] = $datosTipologias[0];
                }
                else{
                    $linea = PresupuestoService::getCostesLinea($uso, $datosPedido, $maquina, $papel, $opciones_papel, $tarifa);
                }
                
                if(array_key_exists('error', $linea))
                    continue;
                
                $linea['fields']['tarifa_impresion_id'] = $tarifaId;
                $linea['fields']['maquina'] = $maquina->maquina;
                $linea['fields']['maquina_id'] = $maquina->maquina_id;
                $linea['fields']['maquina_velocidad'] = $maquina->velocidad;
                $linea['fields']['papel_impresion'] = $papel->nombre;
                $linea['fields']['papel_impresion_id'] = $papel->id;
                $linea['fields']['paginas'] = $datosPedido->paginas;
                $linea['fields']['gramaje'] = $gramaje;
                $linea['fields']['papel_generico_id'] = $papel_generico['id'];
                $linea['fields']['papel_generico'] = $papel_generico['nombre'];

                if($maquina->is_inkjet){
                    $linea['fields']['precio_click'] = $tarifa;
                    $linea['fields']['precio_click_pedido'] = $linea['fields']['clicks_pedido'] * $linea['fields']['precio_click'];
                }
                $linea['fields']['tiempo_maquina'] = PresupuestoService::getTiempoMaquina(
                                $linea['fields']['precio_click_pedido'], 
                                $linea['fields']['precio_click'], 
                                $maquina->velocidad);

                $clientePreciosModel = new ClientePreciosModel();
                $config = (object)[
                    "tipo" => $uso,
                    "tipo_maquina" => $maquina->is_inkjet?'inkjet':'toner',
                    "tipo_impresion" => $tipo
                ];
                $tiempo = PresupuestoService::getHorasMaquina(
                    $linea['fields']['precio_click_pedido'], 
                    $linea['fields']['precio_click'], 
                    $maquina->velocidad);
                [$precio_hora, $margen_precio_hora] =  $clientePreciosModel->get_precio_hora($cliente_id, $config, $tiempo);

                if(is_null($precio_hora)){
                    continue;
                }

                $linea['fields']['tipo_maquina'] = $maquina->is_inkjet?'inkjet':'toner';
                $linea['fields']['precio_hora'] = $precio_hora*$margen_precio_hora/100.0;
                $linea['fields']['precio_hora_margen'] = $margen_precio_hora; 
                $linea['fields']['horas_maquina'] = $tiempo; 
                $linea['fields']['precio_impresion_horas'] = $precio_hora*$tiempo*1.0;
                $linea['fields']['margen_impresion_horas'] = $precio_hora*$tiempo*1.0*$margen_precio_hora/100.0; 

                if($maquina->is_inkjet){
                    $linea['fields']['precio_pedido'] = $linea['fields']['precio_libro'] * ($datosPedido->tirada + $datosPedido->merma);  
                    $linea['fields']['margen_papel_pedido'] = $linea['fields']['pliegos_libro']*$margen_pliego_impresion* ($datosPedido->tirada + $datosPedido->merma);  ;      
                    $linea['fields']['total_impresion'] = 
                                    $linea['fields']['precio_pedido'] + // papel
                                    $linea['fields']['precio_impresion_horas'] + $linea['fields']['margen_impresion_horas'] +  // horas de maquina
                                    $linea['fields']['precio_tinta'];  // tinta
                }
                else{
                    $linea['fields']['total_impresion'] = $linea['fields']['precio_pedido'] + // papel
                            $linea['fields']['precio_impresion_horas']; // impresion
                }

                
                
                array_push($lineas, $linea);
            }
        }
        return $lineas;
    }

    public function getCompIntRotData($datosPedido, $papel_generico, $gramaje, $paginas, $cliente_id, $datosTipolog = null)
    {

        $uso = 'interior';

        $tipo = $paginas->color>0? 'color': 'negro';


        $parametrosRotativa = (object)array(
            'a_favor_fibra' => 0, // este parametro se cambia para comprobar 
                                  // en las dos direcciones (menos en rustica fresada que es siempre 1)
            'bnPages' =>  $paginas->negro,
            'colorPages' =>  $paginas->color,
            'rotativa_gota_negro' => 0,
            'rotativa_gota_color' => 0,
        );

        $opciones_papel = array(
            'rotativa' => 1,
        );

        $tipo = array();
        if( $paginas->color > 0 ){
            $tipo[] = 'color';
            $opciones_papel['color'] = 1;
        }
        if( $paginas->negro > 0 ){
            $opciones_papel['bn'] = 1;
            $tipo[] = 'negro';
        }
        
        // Se obtienen los papeles disponibles
        $papelimpresionmodel = new PapelImpresionModel();
        $papeles = $papelimpresionmodel->getIdPapelesImpresionForPresupuesto(
            papel_generico_id: $papel_generico['id'],
            gramaje: $gramaje,
            options: $opciones_papel
        );

        $lineas = array();
        // Para cada papel, se obtienen las maquinas disponibles
        foreach ($papeles as $papel) {

            $papelImpresionTipologiaModel = new \App\Models\Configuracion\PapelImpresionTipologiaModel();
            if(is_null($datosTipolog)){
                $datosTipologias = $papelImpresionTipologiaModel
                    ->findTipologiasForPapelImpresion($papel->id, $parametrosRotativa->colorPages>0?'color':'negro')
                    ->get()->getResultObject();

                
                if(count($datosTipologias)==0){
                    continue;
                }
            }
            else{
                $datosTipologias = $datosTipolog;
            }
            
            $parametrosRotativa->rotativa_gota_negro =  $datosTipologias[0]->gota_negro;
            $parametrosRotativa->rotativa_gota_color =  $datosTipologias[0]->gota_color;
            $parametrosRotativa->rotativa_negro =  $datosTipologias[0]->negro;
            $parametrosRotativa->rotativa_cyan =  $datosTipologias[0]->cyan;
            $parametrosRotativa->rotativa_magenta =  $datosTipologias[0]->magenta;
            $parametrosRotativa->rotativa_amarillo =  $datosTipologias[0]->amarillo;
            
            $maquinamodel = new MaquinaModel();
            
            $maquinas = $maquinamodel->getMaquinaImpresionForPresupuesto(
                is_rotativa: 1,
                tarifa_tipo: $tipo,
                uso_tarifa:  $uso,
                tirada: $datosPedido->tirada + $datosPedido->merma,
                papel_impresion_id: $papel->id,
            );

            // Se recorren las máquinas y se calcula el coste de linea por cada una
            foreach ($maquinas as $maquina) {

                for ($i = 0; $i <= 1; $i++) {

                    $parametrosRotativa->a_favor_fibra = $i;

                    $tarifamodel = new MaquinasTarifasImpresionModel();
                    [$tarifaId, $tarifa] = $tarifamodel->getTarifa($maquina->maquina_id, $uso, is_array($tipo)?'color':$tipo);
                    if(!is_float($tarifa)){
                        continue;
                    }
                    
                    // precio del pliego de impresion
                    $linea['fields'] = PresupuestoService::getCostesLineaRotativa($maquina, $papel, $datosPedido,  $parametrosRotativa);
                    
                    [$precio_pliego_impresion, $margen_pliego_impresion] = PresupuestoService::getPrecioPliego($maquina, $papel, $datosPedido->paginas);
                    
                    $linea['fields']['tarifa_impresion_id'] = $tarifaId;

                    $linea['fields']['precios_pliegos'] = $precio_pliego_impresion;

                    $linea['fields']['precio_libro'] = $linea['fields']['pliegos_libro'] * $precio_pliego_impresion;
                    // Precio papel pedido
                    $linea['fields']['precio_pedido'] = $linea['fields']['precio_libro'] * ($datosPedido->tirada + $datosPedido->merma);  
                    $linea['fields']['margen_papel_pedido'] = $linea['fields']['pliegos_libro']*$margen_pliego_impresion* ($datosPedido->tirada + $datosPedido->merma);  ;      

                    $linea['fields']['a_favor_fibra'] = $parametrosRotativa->a_favor_fibra;
                    $linea['fields']['maquina'] = $maquina->maquina;
                    $linea['fields']['maquina_id'] = $maquina->maquina_id;
                    $linea['fields']['maquina_velocidad'] = $maquina->velocidad;
                    $linea['fields']['tipo_maquina'] = 'inkjet';
                    $linea['fields']['papel_impresion'] = $papel->nombre;
                    $linea['fields']['papel_impresion_id'] = $papel->id;
                    $linea['fields']['paginas'] = $datosPedido->paginas;
                    $linea['fields']['paginas_color'] = $paginas->color;
                    $linea['fields']['gramaje'] = $gramaje;
                    $linea['fields']['papel_generico_id'] = $papel_generico['id'];
                    $linea['fields']['papel_generico'] = $papel_generico['nombre'];

                    $linea['fields']['posicion_formas'] = $parametrosRotativa->a_favor_fibra ? 'h' : 'v';
                    $linea['fields']['num_formas_horizontales'] = floor($linea['fields']['factor_anchura']);
                    $linea['fields']['num_formas_verticales'] = floor($linea['fields']['factor_altura']);

                    

                    $linea['fields']['datosTipologias'] = $datosTipologias[0];

                    // impresion
                    $linea['fields']['precio_click'] = $tarifa;
                    $linea['fields']['precio_click_pedido'] = $linea['fields']['clicks_pedido'] * $linea['fields']['precio_click'];

                    $linea['fields']['tiempo_maquina'] = PresupuestoService::getTiempoMaquina(
                        $linea['fields']['precio_click_pedido'], 
                        $linea['fields']['precio_click'], 
                        $maquina->velocidad);


                    $clientePreciosModel = new ClientePreciosModel();
                    $config = (object)[
                        "tipo" => $uso,
                        "tipo_maquina" => 'inkjet',
                        "tipo_impresion" => $tipo
                    ];
                    $tiempo = PresupuestoService::getHorasMaquina(
                        $linea['fields']['precio_click_pedido'], 
                        $linea['fields']['precio_click'], 
                        $maquina->velocidad);
                    [$precio_hora, $margen_precio_hora] =  $clientePreciosModel->get_precio_hora($cliente_id, $config, $tiempo);
    
                    if(is_null($precio_hora)){
                        continue;
                    }
    
                    $linea['fields']['precio_hora'] = $precio_hora*$margen_precio_hora/100.0;
                    $linea['fields']['precio_hora_margen'] = $margen_precio_hora; 
                    $linea['fields']['horas_maquina'] = $tiempo; 
                    $linea['fields']['precio_impresion_horas'] = $precio_hora*$tiempo*1.0;
                    $linea['fields']['margen_impresion_horas'] = $precio_hora*$tiempo*1.0*$margen_precio_hora/100.0; 

                    // total linea rotativa
                    //$linea['fields']['total_impresion'] = $linea['fields']['precio_pedido'] + $linea['fields']['precio_click_pedido'] + $linea['fields']['precio_tinta'] + 
                    //                $linea['fields']['total_corte'];
                    $linea['fields']['total_impresion'] = 
                                    $linea['fields']['precio_pedido'] + // papel
                                    $linea['fields']['precio_impresion_horas'] + $linea['fields']['margen_impresion_horas'] +  // horas de maquina
                                    $linea['fields']['precio_tinta'] +   // tinta
                                    $linea['fields']['total_corte'];    // corte

                    array_push($lineas, $linea);
                }
            }
        }
        return $lineas;
    }

    public function allItemsSelect()
    {
        if ($this->request->isAJAX()) {
            $onlyActiveOnes = true;
            $reqVal = $this->request->getPost('val') ?? 'id';
            $menu = $this->model->getAllForMenu($reqVal . ', titulo', 'titulo', $onlyActiveOnes, false);
            $nonItem = new \stdClass;
            $nonItem->id = '';
            $nonItem->titulo = '- ' . lang('Basic.global.None') . ' -';
            array_unshift($menu, $nonItem);

            $newTokenHash = csrf_hash();
            $csrfTokenName = csrf_token();
            $data = [
                'menu' => $menu,
                $csrfTokenName => $newTokenHash
            ];
            return $this->respond($data);
        } else {
            return $this->failUnauthorized('Invalid request', 403);
        }
    }

    public function menuItems()
    {
        if ($this->request->isAJAX()) {

            $reqData = $this->request->getPost();
            try{

                $tipo = $reqData['tipo'] ?? null;
                $uso = $reqData['uso'] ?? null;
                $datos = $reqData['datos'] ?? null;
                //$searchStr = goSanitize($this->request->getPost('searchTerm'))[0];

                $newTokenHash = csrf_hash();
                $csrfTokenName = csrf_token();

                if ($tipo == 'gramaje') {
                    // En este caso contiene el nombre del papel generico
                    $model = new PapelGenericoModel();
                    $menu = $model->getGramajeComparador($datos, $uso );

                    $data = [
                        'menu' => $menu,
                        $csrfTokenName => $newTokenHash
                    ];
                }
                elseif ($tipo == 'gramajeLineasPresupuesto') {
                    $tipoLinea = $reqData['tipoLinea'] ?? null;
                    // En este caso contiene el id del papel generico
                    $model = new PapelGenericoModel();
                    $menu = $model->getGramajeLineasPresupuesto($datos, $tipoLinea, $uso );

                    $data = [
                        'menu' => $menu,
                        $csrfTokenName => $newTokenHash
                    ];
                }
                elseif ($tipo == 'papelImpresion') {
                    $gramaje = $reqData['gramaje'] ?? null;
                    $tipoLinea = $reqData['tipoLinea'] ?? null;
                    // En este caso contiene el nombre del papel generico
                    // Uso: negro, negrohq, color, colorhq, rot_bn, rot_color, 
                    $model = new PapelImpresionModel();
                    $menu = $model->getPapelesImpresionForMenu($datos, $gramaje, $tipoLinea, $uso );

                    $data = [
                        'menu' => $menu,
                        $csrfTokenName => $newTokenHash
                    ];
                }

                elseif ($tipo == 'maquina') {
                    $is_rotativa = $reqData['is_rotativa'] ?? null;
                    $papel_impresion = $reqData['papel_impresion'] ?? null;
                    $tipo_linea = $reqData['tipoLinea'] ?? null;
                    $ancho = $reqData['ancho'] ?? null;
                    $alto = $reqData['alto'] ?? null;
                    // Datos contiene la tirada
                    // uso: negro, negrohq, color, colorhq, 
                    $uso_tarifa = $reqData['uso_tarifa'] ?? 'interior';
                    $model = new MaquinaModel();
                    $maquinas = $model->getMaquinaImpresionForPresupuesto($is_rotativa, $uso, $uso_tarifa ,$datos, $papel_impresion );
                    $menu = [];
                    foreach ($maquinas as $maquina){
                        
                        $formas = PresupuestoService::getNumFormasPlana($tipo_linea, $maquina, floatval($ancho), floatval($alto), true);
                        
                        if($formas['num_formas'] != 'n/a'){
                            array_push($menu, $maquina);
                        }
                    }

                    $data = [
                        'menu' => $menu,
                        $csrfTokenName => $newTokenHash
                    ];
                }

                else{
                    
                    $data = [
                        'tipo' => $tipo,
                        $csrfTokenName => $newTokenHash
                    ];
                }
            }
            catch(Exception $e){
                $data = [
                    'error' => $e,
                    $csrfTokenName => $newTokenHash
                ];
            }
            finally{
                return $this->respond($data);
            }
                
        } else {
            return $this->failUnauthorized('Invalid request', 403);
        }
    }


    protected function getClienteListItems($selId = null)
    {
        $data = ['' => lang('Basic.global.pleaseSelectA', [mb_strtolower(lang('Clientes.cliente'))])];
        if (!empty($selId)) :
            $clienteModel = model('App\Models\Clientes\ClienteModel');

            $selOption = $clienteModel->where('id', $selId)->findColumn('nombre');
            if (!empty($selOption)) :
                $data[$selId] = $selOption[0];
            endif;
        endif;
        return $data;
    }

    protected function getPaisListItems()
    {
        $paisModel = model('App\Models\Configuracion\PaisModel');
        $onlyActiveOnes = true;
        $data = $paisModel->getAllForMenu('id, nombre', 'nombre', $onlyActiveOnes);

        return $data;
    }

    protected function getCcaaListItems($selId = null)
    {
        $ccaaModel = model('App\Models\Configuracion\ComunidadAutonomaModel');
        $onlyActiveOnes = true;
        $data = $ccaaModel->getAllForMenu('id, nombre', 'nombre', $onlyActiveOnes);

        return $data;
    }


    protected function getPapelFormatoListItems($selId = null)
    {
        $papelFormatoModel = model('App\Models\Configuracion\PapelFormatoModel');
        $data = $papelFormatoModel->getElementsForMenu();
        array_shift($data);
        array_unshift($data, (object)['id' => '', 'tamanio' => lang('Basic.global.pleaseSelectA', [mb_strtolower(lang('Presupuestos.papelFormatoId'))])]);
        return $data;
    }


    protected function getPapelGenericoRotativaNegro()
    {
        $model = model('App\Models\Configuracion\PapelGenericoModel');
        $data = $model->getPapelForComparador('negro', false, false, true);
        array_unshift($data, (object)array(
            "id" => 0,
            "nombre" => lang('Basic.global.pleaseSelectA', [mb_strtolower(lang('Presupuestos.papel'))])
        ));
        return $data;
    }

    protected function getPapelGenericoRotativaColor()
    {
        $model = model('App\Models\Configuracion\PapelGenericoModel');
        $data = $model->getPapelForComparador('color', false, false, true);
        array_unshift($data, (object)array(
            "id" => 0,
            "nombre" => lang('Basic.global.pleaseSelectA', [mb_strtolower(lang('Presupuestos.papel'))])
        ));
        return $data;
    }

    protected function getPapelGenericoNegro()
    {
        $model = model('App\Models\Configuracion\PapelGenericoModel');
        $data = $model->getPapelForComparador('negro', false, false);
        array_unshift($data, (object)array(
            "id" => 0,
            "nombre" => lang('Basic.global.pleaseSelectA', [mb_strtolower(lang('Presupuestos.papel'))])
        ));
        return $data;
    }

    protected function getPapelGenericoNegroHQ()
    {
        $model = model('App\Models\Configuracion\PapelGenericoModel');
        $data = $model->getPapelForComparador('negrohq', false, false);
        array_unshift($data, (object)array(
            "id" => 0,
            "nombre" => lang('Basic.global.pleaseSelectA', [mb_strtolower(lang('Presupuestos.papel'))])
        ));
        return $data;
    }

    protected function getPapelGenericoColor()
    {
        $model = model('App\Models\Configuracion\PapelGenericoModel');
        $data = $model->getPapelForComparador('color', false, false);
        array_unshift($data, (object)array(
            "id" => 0,
            "nombre" => lang('Basic.global.pleaseSelectA', [mb_strtolower(lang('Presupuestos.papel'))])
        ));
        return $data;
    }

    protected function getPapelGenericoColorHQ()
    {
        $model = model('App\Models\Configuracion\PapelGenericoModel');
        $data = $model->getPapelForComparador('colorhq', false, false);
        array_unshift($data, (object)array(
            "id" => 0,
            "nombre" => lang('Basic.global.pleaseSelectA', [mb_strtolower(lang('Presupuestos.papel'))])
        ));
        return $data;
    }

    protected function getPapelGenericoCubierta()
    {
        $model = model('App\Models\Configuracion\PapelGenericoModel');
        $data = $model->getPapelForComparador('colorhq', true, false);
        array_unshift($data, (object)array(
            "id" => 0,
            "nombre" => lang('Basic.global.pleaseSelectA', [mb_strtolower(lang('Presupuestos.papel'))])
        ));
        return $data;
    }

    protected function getPapelGenericoSobreCubierta()
    {
        $model = model('App\Models\Configuracion\PapelGenericoModel');
        $data = $model->getPapelForComparador('colorhq', false, true);
        array_unshift($data, (object)array(
            "id" => 0,
            "nombre" => lang('Basic.global.pleaseSelectA', [mb_strtolower(lang('Presupuestos.papel'))])
        ));
        return $data;
    }

    protected function getServiciosPreimpresion()
    {
        $model = model('App\Models\Tarifas\TarifapreimpresionModel');
        $data = $model->getServiciosPreimpresionSelector();
        array_unshift($data, (object)array(
            "value" => 0,
            "label" => lang('Basic.global.pleaseSelectA', [mb_strtolower(lang('Presupuestos.servicioPreimpresion'))])
        ));
        return $data;
    }

    protected function getServiciosEncuadernacion()
    {
        $model = model('App\Models\Tarifas\TarifaEncuadernacionModel');
        $data = $model->getServiciosEncuadernacionSelector();
        /*array_unshift($data, (object)array(
            "value" => 0,
            "label" => lang('Basic.global.pleaseSelectA', [mb_strtolower(lang('Presupuestos.servicioEncuadernado'))])
        ));*/
        return $data;
    }

    protected function getServiciosAcabado()
    {
        $model = model('App\Models\Tarifas\TarifaacabadoModel');
        $data = $model->getServiciosAcabadoSelector();
        /*array_unshift($data, (object)array(
            "value" => 0,
            "label" => lang('Basic.global.pleaseSelectA', [mb_strtolower(lang('Presupuestos.servicioAcabado'))])
        ));*/
        return $data;
    }

    protected function getServiciosManipulado()
    {
        $model = model('App\Models\Tarifas\TarifaManipuladoModel');
        $data = $model->getServiciosManipuladoSelector();
        array_unshift($data, (object)array(
            "value" => 0,
            "label" => lang('Basic.global.pleaseSelectA', [mb_strtolower(lang('Presupuestos.servicioManipulado'))])
        ));
        return $data;
    }

    protected function getPOD()
    {
        $model = model('App\Models\Configuracion\ConfiguracionSistemaModel');
        return $model->getPOD();
    }

}
