<?php

namespace App\Controllers\Presupuestos;

use App\Entities\Presupuestos\PresupuestoEntity;
use App\Models\Collection;
use App\Models\Configuracion\MaquinaModel;
use App\Models\Configuracion\PapelGenericoModel;
use App\Models\Configuracion\PapelFormatoModel;
use App\Models\Clientes\ClienteModel;
use App\Models\Configuracion\PapelImpresionModel;
use App\Models\Configuracion\TipoPresupuestoModel;
use App\Models\Presupuestos\PresupuestoAcabadosModel;
use App\Models\Presupuestos\PresupuestoDireccionesModel;
use App\Models\Presupuestos\PresupuestoEncuadernacionesModel;
use App\Models\Presupuestos\PresupuestoLineaModel;
use App\Models\Presupuestos\PresupuestoManipuladosModel;
use App\Models\Presupuestos\PresupuestoModel;
use App\Models\Presupuestos\PresupuestoPreimpresionesModel;
use App\Models\Presupuestos\PresupuestoServiciosExtraModel;
use App\Services\PresupuestoService;
use App\Services\PresupuestoClienteService;
use Hermawan\DataTables\DataTable;
use CodeIgniter\I18n\Time;
use Exception;

class Presupuestoadmin extends \App\Controllers\BaseResourceController
{

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

    protected static $singularObjectName = 'Presupuesto Admin';
    protected static $singularObjectNameCc = 'Presupuestoadmin';
    protected static $pluralObjectName = 'Presupuestos Admin';
    protected static $pluralObjectNameCc = 'PresupuestosAdmin';

    protected static $controllerSlug = 'presupuestoadmin';

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

    protected $indexRoute = 'presupuestoadminList';



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

        $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

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



    public function list($tipo_impresion_id = 4)
    {
        checkPermission('presupuesto.menu');

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

        $viewData = array_merge($viewData, $this->getStringsFromTipoImpresion($tipo_impresion_id));

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


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


    public function add($tipo_impresion_id = null)
    {
        checkPermission('presupuesto.create');

        if ($this->request->getPost()):

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

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

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

            // JJO
            $sanitizedData['user_created_id'] = auth()->user()->id;

            if (!isset($sanitizedData['papel_formato_id']) || $sanitizedData['papel_formato_id'] == null) {
                $sanitizedData['papel_formato_id'] = 0;
            }

            if (!isset($sanitizedData['is_duplicado']) || $sanitizedData['is_duplicado'] == null) {
                $sanitizedData['is_duplicado'] = 0;
            }

            $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();

                // Guardar los servicios de encuadernación por defecto
                $POD = model('App\Models\Configuracion\ConfigVariableModel')->getVariable('POD')->value;
                $ancho = 0;
                $alto = 0;
                if(isset($sanitizedData['papel_formato_personalizado']) && $sanitizedData['papel_formato_personalizado'] == '1'){
                    $ancho = $sanitizedData['papel_formato_ancho'];
                    $alto = $sanitizedData['papel_formato_alto'];
                }
                else{
                    $papelFormatoModel = new PapelFormatoModel();
                    $papelFormato = $papelFormatoModel->find($sanitizedData['papel_formato_id']);
                    $ancho = $papelFormato->ancho;
                    $alto = $papelFormato->alto;
                }
                $servDefectoEnc = PresupuestoCLienteService::getServiciosEncuadernacionDefault([
                    'tipo_impresion_id' => $sanitizedData['tipo_impresion_id'],
                    'tirada' => $sanitizedData['tirada'],
                    'paginas' => $sanitizedData['paginas'],
                    'ancho' => $ancho,
                    'alto' => $alto,
                    'POD' => $POD,
                    'solapas' => 0, // default
                    'paginasCuadernillo' => 32, // default
                ]);

                $model = new PresupuestoEncuadernacionesModel();
                foreach($servDefectoEnc as $servicio){

                    $data = [
                        'presupuesto_id' => $id,
                        'tarifa_encuadernado_id' => $servicio->tarifa_id,
                        'proveedor_id' => $servicio->proveedor_id,
                        'tiempo' => $servicio->tiempo,
                        'precio_total' => round($servicio->total, 2),
                        'precio_unidad' => round($servicio->precio_unidad, 2),
                        'margen' => $servicio->margen,
                    ];

                    // Se comprueba que $servicio tiene paginasCuadernillo
                    if (isset($servicio->paginas_por_cuadernillo)) {
                        $data['paginas_por_cuadernillo'] = $servicio->paginas_por_cuadernillo;
                    }

                    $model->insert($data);
                }

                $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('presupuestoadmin/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'] = $tipo_impresion_id; // Cosido tapa blanda JJO
        $presupuestoEntity = isset($sanitizedData) ? new PresupuestoEntity($sanitizedData) : new PresupuestoEntity();
        $this->viewData['presupuestoEntity'] = $presupuestoEntity;
        $this->viewData['isCosido'] = (new TipoPresupuestoModel())->get_isCosido($this->viewData['tipo_impresion_id']);
        $this->viewData['isTapaDura'] = (new TipoPresupuestoModel())->get_isTapaDura($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['POD'] = $this->getPOD();
        $this->viewData['pais_default_id'] = model('App\Models\Configuracion\ConfigVariableModel')->getVariable('id_pais_defecto')->value;
        $this->viewData['pais_default'] = model('App\Models\Configuracion\PaisModel')->find($this->viewData['pais_default_id'])->nombre;

        $this->viewData['formAction'] = route_to('createPresupuestoAdmin', $tipo_impresion_id);

        $this->viewData = array_merge($this->viewData, $this->getStringsFromTipoImpresion($tipo_impresion_id));

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

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


    public function edit($requestedId = null)
    {
        checkPermission('presupuesto.edit');

        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;



        if ($this->request->getPost()):

            $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);
            $sanitizedData['user_updated_id'] = auth()->user()->id;

            if(isset($sanitizedData['total_aceptado_revisado']) && $sanitizedData['total_aceptado_revisado'] != 0
                && $sanitizedData['total_aceptado_revisado'] != null && $sanitizedData['total_aceptado_revisado'] != ""){
                $sanitizedData['aprobado_at'] = $sanitizedData['updated_at'];
                $sanitizedData['aprobado_user_id'] = $sanitizedData['user_updated_id'];
            }

            if ($presupuestoEntity->estado_id == 1 && isset($postData['confirmar']) && $postData['confirmar'] == 1) {
                $sanitizedData['aprobado_at'] = $sanitizedData['updated_at'];
                $sanitizedData['aprobado_user_id'] = $sanitizedData['user_updated_id'];
                $sanitizedData['total_aceptado_revisado'] = $sanitizedData['total_presupuesto'];
            }

            if ($this->request->getPost('is_duplicado') == null) {
                $sanitizedData['is_duplicado'] = 0;
            }

            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;
            }
            if ($this->request->getPost('papel_formato_personalizado') == null) {
                $sanitizedData['papel_formato_personalizado'] = false;
            }

            if ($this->request->getPost('papel_formato_id') == null) {
                $sanitizedData['papel_formato_id'] = 0;
            }

            if ($this->request->getPost('solapas') == null) {
                $sanitizedData['solapas'] = 0;
            }
            if ($this->request->getPost('solapas_sobrecubierta') == null) {
                $sanitizedData['solapas_sobrecubierta'] = 0;
            }

            $tipoImpresionModel = new TipoPresupuestoModel();
            $sanitizedData['cosido'] = $tipoImpresionModel->get_isCosido($sanitizedData['tipo_impresion_id']);

            $noException = true;
            if (
                $sanitizedData['papel_formato_id'] == null && $sanitizedData['papel_formato_ancho'] == null
                && $sanitizedData['papel_formato_alto'] == null
            ) {
                if ($this->request->isAJAX()) {
                    $newTokenHash = csrf_hash();
                    $csrfTokenName = csrf_token();
                    $data = [
                        'errorMensaje' => lang('Presupuestos.errores.formato_papel'),
                        $csrfTokenName => $newTokenHash
                    ];
                    return $this->respond($data);
                } else {
                    $this->session->setFlashData('errorMessage', lang('Presupuestos.errores.formato_papel'));
                }
                $successfulResult = false;
            } else {

                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()) {

                        if ($presupuestoEntity->estado_id == 1 && $presupuestoEntity->confirmar == 1) {
                            $this->model->confirmarPresupuesto($id);
                            PresupuestoService::crearPedido($id);
                        }

                        // modificar los datos del pedido y de la factura si no está la factura validada
                        if ($presupuestoEntity->estado_id == 2){
                            $facturaModel = model('App\Models\Facturas\FacturaModel');
                            if(!$facturaModel->presupuestoHasFacturaValidada($id)){
                                // se actualiza primero el pedido
                                $pedidoModel = model('App\Models\Pedidos\PedidoLineaModel');
                                $pedidoLineaId = $pedidoModel->where('presupuesto_id', $id)->first()->id;
                                $linea_pedido = $this->model->generarLineaPedido($id)[0];
                                $idPedido = $pedidoModel->join('pedidos', 'pedidos_linea.pedido_id = pedidos.id')
                                    ->where('pedidos_linea.presupuesto_id', $id)
                                    ->first()->pedido_id;
                                $pedidoModel->update($pedidoLineaId, [
                                    'cantidad' => $linea_pedido->unidades,
                                    'descripcion' => $linea_pedido->concepto
                                ]);

                                // se actualiza el totalizador del pedido
                                $total_tirada = $pedidoModel
                                    ->selectSum('cantidad')
                                    ->where('pedido_id', $idPedido)
                                    ->first()->cantidad;
                                $pedidoModel = model('App\Models\Pedidos\PedidoModel');
                                $pedidoModel->update($idPedido, [
                                    'total_tirada' => $total_tirada
                                ]);

                                // se actualiza la factura
                                $linea_pedido = $this->model->generarLineaPedido($id, true, $idPedido)[0];
                                $facturaLineaModel = model('App\Models\Facturas\FacturaLineaModel');
                                $facturaLineaId = $facturaLineaModel->where('pedido_linea_impresion_id', $pedidoLineaId)->
                                    where('deleted_at', null)->first()->id;
                                $facturaLineaModel->update($facturaLineaId, [
                                    'cantidad' => $linea_pedido->unidades,
                                    'descripcion' => $linea_pedido->concepto
                                ]);

                            }

                        }

                        $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['presupuestoId'] = $id;
        $this->viewData['presupuestoEntity'] = $presupuestoEntity;
        $this->viewData['isCosido'] = (new TipoPresupuestoModel())->get_isCosido($presupuestoEntity->tipo_impresion_id);
        $this->viewData['isTapaDura'] = (new TipoPresupuestoModel())->get_isTapaDura($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['POD'] = $this->getPOD();

        $this->viewData['serviciosAutomaticos'] = [
            'solapas_cubierta' => model('App\Models\Configuracion\ConfigVariableModel')->getVariable('servicio_solapas_cubierta')->value,
            'solapas_sobrecubierta' => model('App\Models\Configuracion\ConfigVariableModel')->getVariable('servicio_solapas_sobrecubierta')->value,
            'solapas_faja' => model('App\Models\Configuracion\ConfigVariableModel')->getVariable('servicio_solapas_faja')->value,
            'retractilado' => model('App\Models\Configuracion\ConfigVariableModel')->getVariable('id_servicio_retractilado')->value,
            'retractilado5' => model('App\Models\Configuracion\ConfigVariableModel')->getVariable('id_servicio_retractilado5')->value,
            'ferro' => model('App\Models\Configuracion\ConfigVariableModel')->getVariable('id_servicio_ferro')->value,
            'prototipo' => model('App\Models\Configuracion\ConfigVariableModel')->getVariable('id_servicio_prototipo')->value,
            'solapas_grandes_cubierta' => model('App\Models\Configuracion\ConfigVariableModel')->getVariable('id_servicio_plegado_exceso_solapas_cubierta')->value,
            'solapas_grandes_sobrecubierta' => model('App\Models\Configuracion\ConfigVariableModel')->getVariable('id_servicio_plegado_exceso_solapas_sobrecubierta')->value,
            'solapas_grandes_faja' => model('App\Models\Configuracion\ConfigVariableModel')->getVariable('id_servicio_plegado_exceso_solapas_faja')->value,
            'lomo_redondo' => model('App\Models\Configuracion\ConfigVariableModel')->getVariable('id_servicio_lomo_redondo')->value,
            'ferro_digital' => model('App\Models\Configuracion\ConfigVariableModel')->getVariable('id_servicio_ferro_digital')->value,
        ];

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

        $this->viewData = array_merge($this->viewData, $this->getStringsFromTipoImpresion($presupuestoEntity->tipo_impresion_id));

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

        $this->viewData['cliente_id'] = $presupuestoEntity->cliente_id;

        $modelPedidoLinea = new \App\Models\Pedidos\PedidoLineaModel();
        $linea = $modelPedidoLinea->where('presupuesto_id', $id)->first();
        if($linea){
            $this->viewData['pedido_id'] = $linea->pedido_id;
            $modelOrden = new \App\Models\OrdenTrabajo\OrdenTrabajoModel();
            $orden = $modelOrden->where('pedido_id', $linea->pedido_id)->first();
            if($orden){
                $this->viewData['orden_id'] = $orden->id;
            }
        }

        // Si se ha llamado a esta funcion porque se ha duplicado el presupuesto
        // se actualiza la bbdd para que sólo ejecute algunas funciones una vez
        if ($presupuestoEntity->is_duplicado) {
            $this->model->removeIsDuplicado($presupuestoEntity->id);
        }

        $this->viewData['credito'] = model('App\Models\Clientes\ClienteModel')->getResumenPagos($presupuestoEntity->cliente_id);

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

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


    /**
     * Delete the designated resource object from the model.
     *
     * @param int $id
     *
     * @return array an array
     */
    public function delete($id = null)
    {
        if (!empty(static::$pluralObjectNameCc) && !empty(static::$singularObjectNameCc)) {
            $objName = mb_strtolower(lang(ucfirst(static::$pluralObjectNameCc) . '.' . static::$singularObjectNameCc));
        } else {
            $objName = lang('Basic.global.record');
        }

        if (!$this->soft_delete) {

            if (!$this->model->delete($id)) {
                return $this->failNotFound(lang('Basic.global.deleteError', [$objName]));
            }
        } else {
            $datetime = (new \CodeIgniter\I18n\Time("now"));
            $rawResult = $this->model->where('id', $id)
                ->set([
                    'deleted_at' => $datetime->format('Y-m-d H:i:s'),
                    'is_deleted' => $this->delete_flag
                ])
                ->update();
            if (!$rawResult) {
                return $this->failNotFound(lang('Basic.global.deleteError', [$objName]));
            }

        }

        // Se borran las lineas de presupuesto
        $model = new PresupuestoLineaModel();
        $model->where("presupuesto_id", $id)->delete();

        // Se borran las direcciones de presupuesto
        $model = new PresupuestoDireccionesModel();
        $model->where("presupuesto_id", $id)->delete();

        // Se borran los servicios de acabado
        $model = new PresupuestoAcabadosModel();
        $model->where("presupuesto_id", $id)->delete();

        // Se borran los servicios de preimpresion
        $model = new PresupuestoPreimpresionesModel();
        $model->where("presupuesto_id", $id)->delete();

        // Se borran los servicios de encuadernacion
        $model = new PresupuestoEncuadernacionesModel();
        $model->where("presupuesto_id", $id)->delete();

        // Se borran los servicios de manipulado
        $model = new PresupuestoManipuladosModel();
        $model->where("presupuesto_id", $id)->delete();

        // Se borran los servicios extra
        $model = new PresupuestoServiciosExtraModel();
        $model->where("presupuesto_id", $id)->delete();

        // $message = lang('Basic.global.deleteSuccess', [$objName]); IMN commented
        $message = lang('Basic.global.deleteSuccess', [lang('Basic.global.record')]);
        $response = $this->respondDeleted(['id' => $id, 'msg' => $message]);
        return $response;
    }

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

            $modelPapelFormato = new PapelFormatoModel();
            $modelCliente = new ClienteModel();
            $modelPapelGenerico = new PapelGenericoModel();


            $presupuesto = $this->model->find($id);
            $data = [];
            if ($presupuesto) {

                $data['lc'] = $presupuesto->lomo_cubierta;
                $data['lsc'] = $presupuesto->lomo_sobrecubierta;
                $data['tipo_impresion'] = $presupuesto->tipo_impresion_id;
                $data['cosido'] = $presupuesto->cosido;
                $data['POD'] = $this->getPOD();

                $data['datosGenerales']['id'] = $presupuesto->id;
                $data['datosGenerales']['state'] = intval($presupuesto->estado_id);
                $data['datosGenerales']['updated_at'] = date('d/m/Y', strtotime($presupuesto->updated_at));
                $data['datosGenerales']['created_at'] = date('d/m/Y', strtotime($presupuesto->created_at));
                $data['datosGenerales']['inc_rei'] = $presupuesto->inc_rei == null ? 0 : $presupuesto->inc_rei;
                $data['datosGenerales']['titulo'] = $presupuesto->titulo;
                $data['datosGenerales']['autor'] = $presupuesto->autor;
                $data['datosGenerales']['coleccion'] = $presupuesto->coleccion;
                $data['datosGenerales']['numero_edicion'] = $presupuesto->numero_edicion;
                $data['datosGenerales']['isbn'] = $presupuesto->isbn;
                $data['datosGenerales']['pais'] = $presupuesto->pais_id;
                $data['datosGenerales']['pais_nombre'] = model('App\Models\Configuracion\PaisModel')->find($presupuesto->pais_id)->nombre;
                $data['datosGenerales']['cliente']['id'] = $presupuesto->cliente_id;
                $data['datosGenerales']['cliente']['nombre'] = $modelCliente->getNombre($presupuesto->cliente_id);
                $data['datosGenerales']['referenciaCliente'] = $presupuesto->referencia_cliente;


                $data['datosLibro']['papelFormatoId'] = $presupuesto->papel_formato_id;
                $data['datosLibro']['papelFormatoNombre'] = $modelPapelFormato->getNombre($presupuesto->papel_formato_id);
                $data['datosLibro']['papelFormatoPersonalizado'] = $presupuesto->papel_formato_personalizado;
                $data['datosLibro']['papelFormatoAncho'] = $presupuesto->papel_formato_ancho;
                $data['datosLibro']['papelFormatoAlto'] = $presupuesto->papel_formato_alto;
                $data['datosLibro']['paginas'] = $presupuesto->paginas;
                $data['datosLibro']['tirada'] = $presupuesto->tirada;
                $data['datosLibro']['merma'] = $presupuesto->merma;
                $data['datosLibro']['mermaCubierta'] = $presupuesto->merma_cubierta;
                $data['datosLibro']['solapasCubierta'] = $presupuesto->solapas;
                $data['datosLibro']['solapasSobrecubierta'] = $presupuesto->solapas_sobrecubierta;
                $data['datosLibro']['solapasCubiertaAncho'] = $presupuesto->solapas_ancho;
                $data['datosLibro']['solapasSobrecubiertaAncho'] = $presupuesto->solapas_ancho_sobrecubierta;
                $data['datosLibro']['fajaColor'] = $presupuesto->faja_color;
                $data['datosLibro']['fajaColorSolapasAncho'] = $presupuesto->solapas_ancho_faja_color;
                $data['datosLibro']['fajaColorAlto'] = $presupuesto->alto_faja_color;

                $modelAcabado = model("App\Models\Tarifas\Acabados\ServicioAcabadoModel");
                $data['datosLibro']['acabadoCubierta']['id'] = $presupuesto->acabado_cubierta_id;
                if ($presupuesto->acabado_cubierta_id == 0) {
                    $data['datosLibro']['acabadoCubierta']['text'] = "Ninguno";
                } else {
                    $data['datosLibro']['acabadoCubierta']['text'] = $modelAcabado->find($presupuesto->acabado_cubierta_id)->nombre;
                }
                $data['datosLibro']['acabadoSobrecubierta']['id'] = $presupuesto->acabado_sobrecubierta_id;
                if ($presupuesto->acabado_sobrecubierta_id == 0) {
                    $data['datosLibro']['acabadoSobrecubierta']['text'] = "Ninguno";
                } else {
                    $data['datosLibro']['acabadoSobrecubierta']['text'] = $modelAcabado->find($presupuesto->acabado_sobrecubierta_id)->nombre;
                }
                $data['datosLibro']['acabadoFaja']['id'] = $presupuesto->acabado_faja_id;
                if ($presupuesto->acabado_faja_id == 0) {
                    $data['datosLibro']['acabadoFaja']['text'] = "Ninguno";
                } else {
                    $data['datosLibro']['acabadoFaja']['text'] = $modelAcabado->find($presupuesto->acabado_faja_id)->nombre;
                }
                $data['datosLibro']['prototipo'] = $presupuesto->prototipo;
                $data['datosLibro']['ferro'] = $presupuesto->ferro;
                $data['datosLibro']['ferroDigital'] = $presupuesto->ferro_digital;
                $data['datosLibro']['marcapaginas'] = $presupuesto->marcapaginas;
                $data['datosLibro']['retractilado'] = $presupuesto->retractilado;
                $data['datosLibro']['retractilado5'] = $presupuesto->retractilado5;

                $data['comparador']['tipo_impresion'] = $presupuesto->comp_tipo_impresion;
                $data['comparador']['json_data'] = json_decode($presupuesto->comparador_json_data, true);
                if ($data['comparador']['json_data'] != null) {
                    foreach ($data['comparador']['json_data'] as &$item) {
                        if(intval($item['papel_id'])>0)
                            $item['papel_nombre'] = $modelPapelGenerico->getNombre($item['papel_id'])['nombre'];
                    }
                }
                $data['comparador']['posPagColor'] = $presupuesto->comp_pos_paginas_color;
                $data['comparador']['lomoRedondo'] = $presupuesto->lomo_redondo;
                $data['comparador']['cabezada'] = $presupuesto->cabezada;

                $data['lineasPresupuesto'] = $this->loadLineasPresupuesto($presupuesto);

                $data['servicios'] = $this->getLineasServicios($presupuesto)[1];

                if (intval($presupuesto->envios_recoge_cliente) == 1) {
                    $data['direcciones']['entrega_taller'] = 1;
                } else {
                    $data['direcciones']['entrega_taller'] = 0;
                    $data['direcciones'] = $this->obtenerDireccionesEnvio($id, $presupuesto->cliente_id);
                }

                $data['comentarios_cliente'] = $presupuesto->comentarios_cliente;
                $data['comentarios_safekat'] = $presupuesto->comentarios_safekat;
                $data['comentarios_pdf'] = $presupuesto->comentarios_pdf;
                $data['comentarios_presupuesto'] = $presupuesto->comentarios_presupuesto;
                $data['comentarios_produccion'] = $presupuesto->comentarios_produccion;
                

                $data['tiradasAlternativas'] = json_decode($presupuesto->tirada_alternativa_json_data);

                $data['resumen']['total_coste_papel'] = $presupuesto->total_coste_papel;
                $data['resumen']['total_margenPercent_papel'] = $presupuesto->total_margenPercent_papel;
                $data['resumen']['total_margen_papel'] = $presupuesto->total_margen_papel;
                $data['resumen']['total_coste_impresion'] = $presupuesto->total_coste_impresion;
                $data['resumen']['total_margenPercent_impresion'] = $presupuesto->total_margenPercent_impresion;
                $data['resumen']['total_margen_impresion'] = $presupuesto->total_margen_impresion;
                $data['resumen']['total_coste_servicios'] = $presupuesto->total_coste_servicios;
                $data['resumen']['total_margenPercent_servicios'] = $presupuesto->total_margenPercent_servicios;
                $data['resumen']['total_margen_servicios'] = $presupuesto->total_margen_servicios;
                $data['resumen']['total_coste_envios'] = $presupuesto->total_coste_envios;
                $data['resumen']['total_precio_envios'] = $presupuesto->envio_base;
                $data['resumen']['total_margen_envios'] = $presupuesto->total_margen_envios;
                $data['resumen']['total_costes'] = $presupuesto->total_costes;
                $data['resumen']['porcentajeMargen'] =
                    round(($presupuesto->total_costes) > 0 ?
                        100 * $presupuesto->total_margenes / ($presupuesto->total_costes) :
                        0, 0);
                $data['resumen']['total_margenes'] = $presupuesto->total_margenes;
                $data['resumen']['total_antes_descuento'] = $presupuesto->total_antes_descuento;
                $data['resumen']['total_descuentoPercent'] = $presupuesto->total_descuentoPercent;
                $data['resumen']['total_descuento'] = $presupuesto->total_descuento;
                $data['resumen']['total_presupuesto'] = $presupuesto->total_presupuesto;
                $data['resumen']['total_precio_unidad'] = $presupuesto->total_precio_unidad;
                $data['resumen']['total_factor'] = is_numeric($presupuesto->total_factor) ? $presupuesto->total_factor : 0;
                $data['resumen']['total_factor_ponderado'] = is_numeric($presupuesto->total_factor_ponderado) ? $presupuesto->total_factor_ponderado : 0;

                $data['total_aceptado_revisado'] = $presupuesto->total_aceptado_revisado;
                $data['aprobado_by_at'] = ($presupuesto->aprobado_user_id != null)?
                    model('App\Models\Usuarios\UserModel')->getFullName($presupuesto->aprobado_user_id) . ', ' 
                    . date('d/m/Y H:i:s', strtotime($presupuesto->aprobado_at)):'';


                $data['resumen']['iva_reducido'] = $presupuesto->iva_reducido;

                $data['created_by'] = model('App\Models\Usuarios\UserModel')->getFullName($presupuesto->user_created_id);
                $data['updated_by'] = model('App\Models\Usuarios\UserModel')->getFullName($presupuesto->user_update_id);
                $data['created_at'] = date(' H:i d/m/Y', strtotime($presupuesto->created_at));
                $data['updated_at'] = date(' H:i d/m/Y', strtotime($presupuesto->updated_at));

                if ($presupuesto->estado_id == 2) {
                    $data['resumen']['total_aceptado'] = $presupuesto->total_aceptado;
                }
                return $this->respond([
                    'status' => 1,
                    'data' => $data
                ]);
            }
        } else {
            return $this->failUnauthorized('Invalid request', 403);
        }
    }


    public function obtenerComparadorInterior()
    {

        if ($this->request->isAJAX()) {

            $cliente_id = $this->request->getPost('cliente_id');
            $datosPedido = $this->request->getPost('datosPedido');
            $papel_generico = $this->request->getPost('papel_generico');
            $gramaje = $this->request->getPost('gramaje');
            $paginas_color = $this->request->getPost('paginas_color');
            $isColor = $this->request->getPost('isColor') ? 1 : 0;
            $isHq = $this->request->getPost('isHq') ? 1 : 0;
            $tipo_impresion_id = $this->request->getPost('tipo_impresion_id');
            $uso = $this->request->getPost('uso');

            $tipo_maquina = $this->request->getPost('tipo_maquina');

            $data = array(
                'cliente_id' => $cliente_id,
                'datosPedido' => (object) $datosPedido,
                'papel_generico' => $papel_generico,
                'gramaje' => $gramaje,
                'papelInteriorDiferente' => true,
                'paginas_color' => $paginas_color,
                'isColor' => $isColor,
                'isHq' => $isHq,
                'tipo_impresion_id' => $tipo_impresion_id,
                'uso' => $uso
            );

            if ($tipo_maquina == 'rotativa') {
                $data['papelInteriorDiferente'] = false;
                $lineas = PresupuestoClienteService::obtenerPresupuestoClienteInteriorRotativa($data, true);
            } else
                $lineas = PresupuestoClienteService::obtenerPresupuestoClienteInterior($data, true);
            return $this->respond(
                [
                    'status' => 1,
                    'data' => $lineas
                ]
            );
        } else {
            return $this->failUnauthorized('Invalid request', 403);
        }
    }


    public function obtenerComparadorExteriores()
    {

        $lineasCubierta = null;
        $lineasSobrecubierta = null;

        if ($this->request->isAJAX()) {

            $cubierta = $this->request->getPost('cubierta') ?? false;
            $sobrecubierta = $this->request->getPost('sobrecubierta') ?? false;

            // cubierta y sobrecubierta siempre colorhq
            $isColor = true;
            $isHq = true;

            if ($cubierta) {

                $cliente_id = $cubierta['cliente_id'];
                $datosPedido = $cubierta['datosPedido'];
                $papel_generico = $cubierta['papel_generico'];
                $gramaje = $cubierta['gramaje'];
                $paginas_color = $cubierta['datosPedido']['paginas'] ?? 0;
                $tipo_impresion_id = $cubierta['tipo_impresion_id'];
                $uso = $cubierta['uso'];
                $lomoRedondo = $cubierta['lomoRedondo'] ?? false;

                $data = array(
                    'cliente_id' => $cliente_id,
                    'datosPedido' => (object) $datosPedido,
                    'papel_generico' => $papel_generico,
                    'gramaje' => $gramaje,
                    'paginas_color' => $paginas_color,
                    'isColor' => 1, // cubierta y sobre cubierta colorhq
                    'isHq' => 1, // cubierta y sobre cubierta colorhq
                    'tipo_impresion_id' => $tipo_impresion_id,
                    'uso' => $uso,
                    'lomoRedondo' => $lomoRedondo
                );
                $lineasCubierta = PresupuestoClienteService::obtenerCubierta($data, true);
            }

            if ($sobrecubierta) {

                $cliente_id = $sobrecubierta['cliente_id'];
                $datosPedido = $sobrecubierta['datosPedido'];
                $papel_generico = $sobrecubierta['papel_generico'];
                $gramaje = $sobrecubierta['gramaje'];
                $paginas_color = $sobrecubierta['datosPedido']['paginas'] ?? 0;
                $tipo_impresion_id = $sobrecubierta['tipo_impresion_id'];
                $faja = intval($sobrecubierta['faja'] ?? 0);
                $uso = $faja==1? 'faja' : $sobrecubierta['uso'];


                $data = array(
                    'cliente_id' => $cliente_id,
                    'datosPedido' => (object) $datosPedido,
                    'papel_generico' => $papel_generico,
                    'gramaje' => $gramaje,
                    'paginas_color' => $paginas_color,
                    'isColor' => 1, // cubierta y sobre cubierta colorhq
                    'isHq' => 1, // cubierta y sobre cubierta colorhq
                    'tipo_impresion_id' => $tipo_impresion_id,
                    'uso' => $uso
                );
                $lineasSobrecubierta = PresupuestoClienteService::obtenerSobrecubierta($data, true);
            }

            return $this->respond(
                [
                    'status' => 1,
                    'data' => (object) array(
                        'cubierta' => $lineasCubierta,
                        'sobrecubierta' => $lineasSobrecubierta
                    )
                ]
            );
        } else {
            return $this->failUnauthorized('Invalid request', 403);
        }
    }


    public function obtenerComparadorGuardas()
    {

        if ($this->request->isAJAX()) {

            $cliente_id = $this->request->getPost('cliente_id');
            $datosPedido = $this->request->getPost('datosPedido');
            $papel_generico = $this->request->getPost('papel_generico');
            $gramaje = $this->request->getPost('gramaje');
            $paginas_color = $this->request->getPost('paginas_color');
            $isColor = $this->request->getPost('isColor');
            $isHq = $this->request->getPost('isHq');
            $tipo_impresion_id = $this->request->getPost('tipo_impresion_id');
            $uso = $this->request->getPost('uso');

            // guardas siempre hq
            $isHq = true;

            // Para el caso de Fresado y Cosido tapa dura, las guardas son un diptico
            // y hay que imprimirlas como "cosido" (dos hojas pegadas). En el caso de espiral
            // o wire-o tapa dura, las guardas se imprimen como hojas sueltas
            if ($tipo_impresion_id == 1 || $tipo_impresion_id == 3) {
                $datosPedido['isCosido'] = true;
            } else if ($tipo_impresion_id == 5 || $tipo_impresion_id == 7) {
                $datosPedido['isCosido'] = false;
            }

            $datosPedido['paginas_impresion'] = $this->request->getPost('paginas_impresion') ?? 0;

            $data = array(
                'cliente_id' => $cliente_id,
                'datosPedido' => (object) $datosPedido,
                'papel_generico' => $papel_generico,
                'gramaje' => $gramaje,
                'papelInteriorDiferente' => true,
                'paginas_color' => $paginas_color,
                'isColor' => $isColor,
                'isHq' => $isHq,
                'tipo_impresion_id' => $tipo_impresion_id,
                'uso' => $uso
            );

            $lineas = PresupuestoClienteService::obtenerGuardas($data, true);
            return $this->respond(
                [
                    'status' => 1,
                    'data' => $lineas
                ]
            );
        } else {
            return $this->failUnauthorized('Invalid request', 403);
        }
    }


    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';

            // por defecto, se deja cosido tapa blanda por ahora JJO
            $tipo_impresion_id = $reqData['tipo_impresion_id'] ?? 4;

            if (is_null($type)) {

                $searchValues = get_filter_datatables_columns($reqData);

                $resourceData = $this->model->getResource($searchValues, $tipo_impresion_id)->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;

            }

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


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

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

            $type = $reqData['type'] ?? null;
            // por defecto, se deja cosido tapa blanda por ahora JJO
            $tipo_impresion_id = $reqData['tipo_impresion_id'] ?? 4;

            $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,
                'a_favor_fibra' => $reqData['a_favor_fibra'] ?? 1,
                'isCosido' => intval((new TipoPresupuestoModel())->get_isCosido($tipo_impresion_id)), // JJO esto es custom por cada tipo de presupuesto
            );

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

            if ($papel_generico['id'] != 0 && $papel_generico['nombre'] == "") {
                $modelPapelGenerico = new PapelGenericoModel();
                $papel_generico['nombre'] = $modelPapelGenerico->getNombre($papel_generico['id'])['nombre'];
            }

            $gramaje = $reqData['gramaje'] ?? 0;

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

            $resourceData = [];

            if ($type == 'interior' || $type == 'guardas') {

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

                if ($type == 'guardas') {

                    $datosPedido->paginas_impresion = intval($reqData['paginas_impresion']) ?? 0;
                    // Para el caso de Fresado y Cosido tapa dura, las guardas son un diptico
                    // y hay que imprimirlas como "cosido" (dos hojas pegadas). En el caso de espiral
                    // o wire-o tapa dura, las guardas se imprimen como hojas sueltas
                    if ($tipo_impresion_id == 1 || $tipo_impresion_id == 3) {
                        $datosPedido->isCosido = true;
                    } else if ($tipo_impresion_id == 5 || $tipo_impresion_id == 7) {
                        $datosPedido->isCosido = false;
                    }
                }

                $a_favor_fibra = $reqData['a_favor_fibra'] ?? false;

                $input_data = array(
                    'uso' => $type,
                    'tipo_impresion_id' => $tipo_impresion_id,
                    'datosPedido' => $datosPedido,
                    'papel_generico' => $papel_generico,
                    'gramaje' => $gramaje,
                    'isColor' => $isColor,
                    'isHq' => $isHq,
                    'cliente_id' => $cliente_id,
                    'datosTipolog' => $datosTipolog,
                    'a_favor_fibra' => $a_favor_fibra
                );

                $resourceData = PresupuestoService::obtenerComparadorPlana($input_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' => floatval($reqData['negro']) ?? 0,
                        'cyan' => floatval($reqData['cyan']) ?? 0,
                        'magenta' => floatval($reqData['magenta']) ?? 0,
                        'amarillo' => floatval($reqData['amarillo']) ?? 0,
                        'gota_negro' => floatval($reqData['gota_negro']) ?? 0,
                        'gota_color' => floatval($reqData['gota_color']) ?? 0,
                    );
                    array_push($datosTipolog, $data);
                }

                $input_data = [
                    'datosPedido' => $datosPedido,
                    'papel_generico' => $papel_generico,
                    'gramaje' => $gramaje,
                    'paginas' => $paginas,
                    'cliente_id' => $cliente_id,
                    'datosTipolog' => $datosTipolog
                ];

                $resourceData = PresupuestoService::obtenerComparadorRotativa($input_data);

            } else if ($type == 'cubierta' || $type == 'sobrecubierta' || $type == 'faja') {

                $datosPedido->solapas = $reqData['solapas'];
                $datosPedido->solapas_ancho = $reqData['solapas_ancho'];
                $datosPedido->lomo = $reqData['lomo'];

                $input_data = array(
                    'uso' => $type,
                    'tipo_impresion_id' => $tipo_impresion_id,
                    'datosPedido' => $datosPedido,
                    'papel_generico' => $papel_generico,
                    'gramaje' => $gramaje,
                    'isColor' => 1, // Cubierta y sobrecubierta siempre color HQ
                    'isHq' => 1,
                    'cliente_id' => $cliente_id,
                );

                $resourceData = PresupuestoService::obtenerComparadorPlana($input_data);
            }

            $newTokenHash = csrf_hash();
            $csrfTokenName = csrf_token();
            $data = [
                'lineas' => $resourceData,
                $csrfTokenName => $newTokenHash
            ];

            return $this->respond($data);

        } 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);
            } else if ($tipo == 'duplicar') {
                $presupuesto_id = $reqData['presupuesto_id'] ?? -1;
                $result = $this->duplicarPresupuesto($presupuesto_id);
                $newTokenHash = csrf_hash();
                $csrfTokenName = csrf_token();
                if ($result['success']) {
                    $data = [
                        'id' => $result['id'],
                        $csrfTokenName => $newTokenHash
                    ];
                    return $this->respond($data);
                } else {
                    $data = [
                        'error' => $result['message'],
                        $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 getPapelGenerico()
    {

        if ($this->request->isAJAX()) {

            $POD_value = $this->getPOD();
            $tirada = $this->request->getGet("tirada");
            $isPOD = intval($tirada) <= intval($POD_value);

            $tipo_impresion_id = $this->request->getGet("tipo_impresion");
            $tapa_dura = model('App\Models\Configuracion\TipoPresupuestoModel')->get_isTapaDura(intval($tipo_impresion_id));

            $ancho = $this->request->getGet('ancho') ?? 0;
            $alto = $this->request->getGet('alto') ?? 0;
            $solapas = $this->request->getGet('solapas') ?? 0;
            $lomo = $this->request->getGet('lomo') ?? 0;

            $tipo = $this->request->getGet("tipo");

            $uso = $this->request->getGet("uso") ?? 'interior';

            $anchoLibro = $ancho;

            $cubierta = false;
            if ($uso == 'cubierta') {
                $cubierta = true;
                $anchoLibro = 2* $ancho + 2 * $solapas + $lomo;
            }
            $sobrecubierta = false;
            if ($uso == 'sobrecubierta') {
                $sobrecubierta = true;
                $anchoLibro = 2* $ancho + 2 * $solapas + $lomo;
            }
            $guardas = false;
            if ($uso == 'guardas') {
                $guardas = true;
                $isColor = $this->request->getGet("isColor") ?? 1;

            }
            $rotativa = false;
            if ($uso == 'rotativa') {
                $rotativa = true;
            }

            $model = model('App\Models\Configuracion\PapelGenericoModel');
            $query = $model->getPapelForComparador(
                $tipo,
                $cubierta,
                $sobrecubierta,
                $rotativa,
                $guardas,
                $tapa_dura,
                $isPOD,
                $anchoLibro,
                $alto,
                $tirada);
            if ($this->request->getGet("q")) {
                $query->groupStart()
                    ->orLike("t1.nombre", $this->request->getGet("q"))
                    ->groupEnd();
            }

            return $this->response->setJSON($query->orderBy("t1.nombre", "asc")->get()->getResultObject());
        } else {
            return $this->failUnauthorized('Invalid request', 403);
        }
    }

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

            $papel_generico_id = $this->request->getGet("papel_generico");

            $POD_value = $this->getPOD();
            $tirada = $this->request->getGet("tirada");
            $isPOD = intval($tirada) <= intval($POD_value);

            $ancho = $this->request->getGet('ancho') ?? 0;
            $alto = $this->request->getGet('alto') ?? 0;
            $solapas = $this->request->getGet('solapas') ?? 0;
            $lomo = $this->request->getGet('lomo') ?? 0;

            $anchoLibro = $ancho;

            $tipo_impresion_id = $this->request->getGet("tipo_impresion");
            $tapa_dura = model('App\Models\Configuracion\TipoPresupuestoModel')->get_isTapaDura(intval($tipo_impresion_id));

            $tipo = $this->request->getGet("tipo");

            $uso = $this->request->getGet("uso") ?? 'interior';
            $cubierta = false;
            if ($uso == 'cubierta') {
                $cubierta = true;
                $anchoLibro = 2* $ancho + 2 * $solapas + $lomo;
            }
            $sobrecubierta = false;
            if ($uso == 'sobrecubierta') {
                $sobrecubierta = true;
                $anchoLibro = 2* $ancho + 2 * $solapas + $lomo;
            }
            $guardas = false;
            if ($uso == 'guardas') {
                $guardas = true;
            }
            $rotativa = false;
            if ($uso == 'rotativa') {
                $rotativa = true;
            }

            $model = model('App\Models\Configuracion\PapelGenericoModel');
            $query = $model->getGramajeForComparador($tipo,
                $papel_generico_id,
                $cubierta,
                $sobrecubierta,
                $rotativa,
                $guardas,
                $tapa_dura,
                $isPOD,
                $anchoLibro,
                $alto,
                $tirada);
            if ($this->request->getGet("q")) {
                $query->groupStart()
                    ->orLike("t2.gramaje", $this->request->getGet("q"))
                    ->groupEnd();
            }

            return $this->response->setJSON($query->orderBy("t2.gramaje", "asc")->get()->getResultObject());
        } else {
            return $this->failUnauthorized('Invalid request', 403);
        }
    }


    public function getPapelImpresion()
    {

        if ($this->request->isAJAX()) {

            $papel_generico_id = $this->request->getGet('papel_generico');
            $gramaje = $this->request->getGet('gramaje');

            $tipo_impresion_id = $this->request->getGet("tipo_impresion");
            $tapa_dura = model('App\Models\Configuracion\TipoPresupuestoModel')->get_isTapaDura(intval($tipo_impresion_id));

            $tipo = $this->request->getGet("tipo");

            $uso = $this->request->getGet("uso") ?? 'interior';

            $model = model('App\Models\Configuracion\PapelImpresionModel');
            $query = $model->getPapelesImpresionForMenu(
                $papel_generico_id,
                $gramaje,
                $tipo,
                $uso,
                $tapa_dura,
                false
            );
            if ($this->request->getGet("q")) {
                $query->groupStart()
                    ->orLike("lg_papel_impresion.nombre", $this->request->getGet("q"))
                    ->groupEnd();
            }

            return $this->response->setJSON($query->orderBy("t1.nombre", "asc")->get()->getResultObject());
        } else {
            return $this->failUnauthorized('Invalid request', 403);
        }
    }


    public function getMaquinas()
    {

        if ($this->request->isAJAX()) {

            $ancho = $this->request->getGet('ancho');
            $alto = $this->request->getGet('alto');
            $tirada = $this->request->getGet('tirada');
            $merma = $this->request->getGet('merma');
            $tipo_impresion_id = $this->request->getGet('tipo_impresion');
            $isCosido = (new TipoPresupuestoModel())->get_isCosido($tipo_impresion_id);
            $papel_impresion_id = $this->request->getGet('papel_impresion');
            $tarifa_tipo = $this->request->getGet("tarifa_tipo"); // negro, color, negrohq, colorhq
            $uso_tarifa = $this->request->getGet("uso_tarifa") ?? 'interior'; // interior, cubierta, sobrecubierta
            $is_rotativa = $this->request->getGet('is_rotativa') ?? 0;
            $lomo_redondo = $this->request->getGet('lomo_redondo');
            $lomo = $this->request->getGet('lomo');
            $solapas = $this->request->getGet('solapas');
            $solapas_ancho = $this->request->getGet('solapas_ancho');

            $model = model('App\Models\Configuracion\MaquinaModel');
            $query = $model->getMaquinaImpresionForPresupuesto(
                $is_rotativa,
                $tarifa_tipo,
                $uso_tarifa,
                intval($tirada) + intval($merma),
                $papel_impresion_id
            );
            if ($this->request->getGet("q")) {
                $query->groupStart()
                    ->orLike("lg_maquinas.nombre", $this->request->getGet("q"))
                    ->groupEnd();
            }
            $data = $query->orderBy("t1.nombre", "asc")->get()->getResultObject();

            $query = $model->db->getLastQuery();
            $datosPedido = ((object) array(
                'ancho' => $ancho,
                'alto' => $alto,
                'isCosido' => $isCosido,
                'lomo' => $lomo,
                'solapas' => $solapas,
                'solapas_ancho' => $solapas_ancho,
            ));

            for ($i = 0; $i < count($data); $i++) {

                if ($is_rotativa) {

                    $has_error = true;
                    for ($f = 0; $f < 2; $f++) {

                        $parametrosRotativa = (object) array(
                            'a_favor_fibra' => $f,
                        );
                        $values = [];
                        [$values['ancho'], $values['alto']] = PresupuestoService::calculoDimForma($datosPedido, $parametrosRotativa);

                        $factor_anchura = round($data[$i]->ancho_impresion / $values['ancho'], 2);

                        if (floor($factor_anchura) != 0) {
                            $has_error = false;
                        }
                    }
                    if ($has_error) {
                        unset($data[$i]);
                    }
                } else {

                    if ($uso_tarifa != 'interior') {
                        $datosPedido->anchoExteriores = PresupuestoService::getAnchoTotalExteriores($uso_tarifa, $tipo_impresion_id, $datosPedido, $data[$i]->maquina_id, $lomo_redondo);
                        $datosPedido->altoExteriores = PresupuestoService::getAltoTotalExteriores($uso_tarifa, $tipo_impresion_id, $datosPedido);
                    }

                    $ancho_calculo = ($uso_tarifa == 'cubierta' || $uso_tarifa == 'sobrecubierta') ? $datosPedido->anchoExteriores : $datosPedido->ancho;
                    $alto_calculo = ($uso_tarifa == 'cubierta' || $uso_tarifa == 'sobrecubierta') ? $datosPedido->altoExteriores : $datosPedido->alto;
                    $formas = PresupuestoService::getNumFormasPlana($uso_tarifa, $data[$i], $ancho_calculo, $alto_calculo, $datosPedido->isCosido);
                    if ($formas['num_formas']['posicion_formas'] == 'n/a') {
                        unset($data[$i]);
                    }
                }
            }

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

    private function getStringsFromTipoImpresion($tipo_impresion_id)
    {

        $breadcrumbTitle = "";

        switch ($tipo_impresion_id) {

            // Fresado tapa dura
            case 1:
                $viewData['pageTitle'] = lang('Presupuestos.moduleTitleFresadoTD');
                $viewData['isCosido'] = 0;
                $viewData['isTapaDura'] = 1;
                $breadcrumbTitle = lang("App.menu_libros_fresasdo_tapa_dura");
                break;

            // Fresado tapa blanda
            case 2:
                $viewData['pageTitle'] = lang('Presupuestos.moduleTitleFresadoTB');
                $viewData['isCosido'] = 0;
                $viewData['isTapaDura'] = 0;
                $breadcrumbTitle = lang("App.menu_libros_fresasdo_tapa_blanda");
                break;

            // Cosido tapa dura
            case 3:
                $viewData['pageTitle'] = lang('Presupuestos.moduleTitleCosidoTD');
                $viewData['isCosido'] = 1;
                $viewData['isTapaDura'] = 1;
                $breadcrumbTitle = lang("App.menu_libros_cosido_tapa_dura");
                break;

            // Cosido tapa blanda
            case 4:
                $viewData['pageTitle'] = lang('Presupuestos.moduleTitleCosidoTB');
                $viewData['isCosido'] = 1;
                $viewData['isTapaDura'] = 0;
                $breadcrumbTitle = lang("App.menu_libros_cosido_tapa_blanda");
                break;

            // Espiral tapa dura
            case 5:
                $viewData['pageTitle'] = lang('Presupuestos.moduleTitleEspiralTD');
                $viewData['isCosido'] = 0;
                $viewData['isTapaDura'] = 1;
                $breadcrumbTitle = lang("App.menu_libros_espiral_tapa_dura");
                break;

            // Espiral tapa blanda
            case 6:
                $viewData['pageTitle'] = lang('Presupuestos.moduleTitleEspiralTB');
                $viewData['isCosido'] = 0;
                $viewData['isTapaDura'] = 0;
                $breadcrumbTitle = lang("App.menu_libros_espiral_tapa_blanda");
                break;

            // Wire-o tapa dura
            case 7:
                $viewData['pageTitle'] = lang('Presupuestos.moduleTitleWireoTD');
                $viewData['isCosido'] = 0;
                $viewData['isTapaDura'] = 1;
                $breadcrumbTitle = lang("App.menu_libros_wireo_tapa_dura");
                break;

            // Wire-o tapa blanda
            case 8:
                $viewData['pageTitle'] = lang('Presupuestos.moduleTitleWireoTB');
                $viewData['isCosido'] = 0;
                $viewData['isTapaDura'] = 0;
                $breadcrumbTitle = lang("App.menu_libros_wireo_tapa_blanda");
                break;

            // Grapado
            case 21:
                $viewData['pageTitle'] = lang('Presupuestos.moduleTitleGrapado');
                $viewData['isCosido'] = 0;
                $viewData['isTapaDura'] = 0;
                $breadcrumbTitle = lang("App.menu_libros_grapados");
                break;

            default:
                return "A IMPLEMENTAR!";
        }

        // Breadcrumbs
        $viewData['breadcrumb'] = [
            ['title' => lang("App.menu_presupuestos"), 'route' => "javascript:void(0);", 'active' => false],
            ['title' => $breadcrumbTitle, 'route' => site_url('presupuestoadmin/list/' . $tipo_impresion_id), 'active' => true]
        ];

        return $viewData;
    }


    /**
     * Duplica un presupuesto dado por su ID.
     *
     * Esta función duplica un presupuesto y todas sus entidades relacionadas como acabados, encuadernaciones, manipulados,
     * preimpresiones, direcciones y lineas. El presupuesto duplicado se marca como tal y a su título se le añade
     * una cadena 'duplicado'. La función devuelve un array con un estado de éxito y el ID del nuevo presupuesto.
     *
     * @param int $id El ID del presupuesto a duplicar.
     * @return array Un array asociativo que contiene una clave 'success' que indica el estado de éxito de la operación,
     *               y una clave 'id' que contiene el ID del nuevo presupuesto si la operación fue exitosa.
     *               Si ocurre una excepción, la clave 'success' será false y una clave 'message' contendrá el mensaje de la excepción.
     * @throws \Exception Si ocurre un error durante la operación.
     */
    private function duplicarPresupuesto($id)
    {

        try {

            $presupuesto = $this->model->find($id);
            $presupuesto->titulo = $presupuesto->titulo . ' - ' . lang('Presupuestos.duplicado');
            $presupuesto->is_duplicado = 1;
            $presupuesto->estado_id = 1;
            $new_id = $this->model->insert($presupuesto);

            $presupuestoAcabadosModel = model('App\Models\Presupuestos\PresupuestoAcabadosModel');
            foreach ($presupuestoAcabadosModel->where('presupuesto_id', $presupuesto->id)->findAll() as $acabado) {
                $acabado->presupuesto_id = $new_id;
                $presupuestoAcabadosModel->insert($acabado);
            }

            $presupuestoEncuadernacionesModel = model('App\Models\Presupuestos\PresupuestoEncuadernacionesModel');
            foreach ($presupuestoEncuadernacionesModel->where('presupuesto_id', $presupuesto->id)->findAll() as $encuadernacion) {
                $encuadernacion->presupuesto_id = $new_id;
                $presupuestoEncuadernacionesModel->insert($encuadernacion);
            }

            $presupuestoManipuladosModel = model('App\Models\Presupuestos\PresupuestoManipuladosModel');
            foreach ($presupuestoManipuladosModel->where('presupuesto_id', $presupuesto->id)->findAll() as $manipulado) {
                $manipulado->presupuesto_id = $new_id;
                $presupuestoManipuladosModel->insert($manipulado);
            }

            $presupuestoPreimpresionesModel = model('App\Models\Presupuestos\PresupuestoPreimpresionesModel');
            foreach ($presupuestoPreimpresionesModel->where('presupuesto_id', $presupuesto->id)->findAll() as $preimpresion) {
                $preimpresion->presupuesto_id = $new_id;
                $presupuestoPreimpresionesModel->insert($preimpresion);
            }

            $presupuestoServiciosExtraModel = model('App\Models\Presupuestos\PresupuestoServiciosExtraModel');
            foreach ($presupuestoServiciosExtraModel->where('presupuesto_id', $presupuesto->id)->findAll() as $servicioExtra) {
                $servicioExtra->presupuesto_id = $new_id;
                $presupuestoServiciosExtraModel->insert($servicioExtra);
            }

            $presupuestoDireccionesModel = model('App\Models\Presupuestos\PresupuestoDireccionesModel');
            foreach ($presupuestoDireccionesModel->where('presupuesto_id', $presupuesto->id)->findAll() as $direccion) {
                $direccion->presupuesto_id = $new_id;
                $presupuestoDireccionesModel->insert($direccion);
            }

            $presupuestoLineaModel = model('App\Models\Presupuestos\PresupuestoLineaModel');
            $presupuestoLineaModel->duplicateLineasPresupuesto($presupuesto->id, $new_id);

            return [
                'success' => true,
                'id' => $new_id
            ];

        } catch (\Exception $e) {
            return [
                'success' => false,
                'message' => $e->getMessage()
            ];
        }
    }

    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
                    $tirada = $reqData['tirada'] ?? 0;
                    $merma = $reqData['merma'] ?? 0;
                    $model = new PapelGenericoModel();
                    $menu = $model->getGramajeComparador($datos, $uso, intval($tirada + $merma));

                    $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);
        }
    }


    public function tablaClienteForm()
    {

        $clienteId = $this->request->getGet('cliente_id') ?? -1;

        $q = $this->model->getPresupuestosClienteForm($clienteId);

        $searchValue = $this->request->getGet('fecha') ?? '';
        if (!empty($searchValue)) {
            // Extraer las fechas del formato "YYYY-MM-DD|YYYY-MM-DD"
            $dates = explode('|', $searchValue);
            if (count($dates) == 2) {
                $q->where('p.created_at >=', $dates[0] . ' 00:00:00')
                    ->where('p.created_at <=', $dates[1] . ' 23:59:59');
            }
        }

        $result = DataTable::of($q)
            ->edit(
                'fecha',
                fn($q) => $q->fecha?Time::createFromFormat("Y-m-d H:i:s", $q->fecha)->format("d/m/Y"):""
            )
            ->edit(
                'estado', fn($q) => match ($q->estado) {
                    "1" => lang('Presupuestos.borrador'),
                    "2" => lang('Presupuestos.confirmado'),
                    default => '--'
                }
            )->add("action", callback: function ($q) {
                return '
                        <div class="btn-group btn-group-sm">
                            <a href="javascript:void(0);"><i class="ti ti-eye ti-sm btn-edit mx-2" data-id="' . $q->id . '"></i></a>
                        </div>
                    ';
                
            });
        
        return $result->toJson(returnAsObject: true) ;
    }

    public function obtenerTotalPresupuestosCliente($cliente_id){

        $error = false;
        $result = [
            'total_impresion' => 0,
            'total_maquetacion' => 0,
        ];
        $data = $this->model
            ->where('presupuestos.cliente_id', $cliente_id)
            ->select('SUM(presupuestos.total_aceptado) as total')
            ->groupBy('presupuestos.cliente_id')->get()->getResultObject();
        if(count($data) > 0){
            $result['total_impresion'] = round(floatval($data[0]->total), 2);
        }
        else{
            $error = true;
        }
        $result['total'] = $result['total_impresion'] + $result['total_maquetacion'];
        return $this->respond(['status' => $error?'error':'success', 'totales' => $result]);
    }

    public function obtenerTotalPedidosCliente($cliente_id){

        $error = false;
        $result = [
            'total_impresion' => 0,
            'total_maquetacion' => 0,
        ];
        $data = $this->model
            ->where('presupuestos.cliente_id', $cliente_id)->whereNotIn('pedidos.estado', ['cancelado'])
            ->select('SUM(pedidos.total_precio) as total')
            ->join('pedidos_linea', 'pedidos_linea.pedido_id = pedidos.id')
            ->join('presupuestos', 'presupuestos.id = pedidos_linea.presupuesto_id')
            ->groupBy('presupuestos.cliente_id')->get()->getResultObject();
        if(count($data) > 0){
            $result['total_impresion'] = round(floatval($data[0]->total), 2);
        }
        else{
            $error = true;
        }
        $result['total'] = $result['total_impresion'] + $result['total_maquetacion'];
        return $this->respond(['status' => $error?'error':'success', 'totales' => $result]);
    }


    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 getPOD()
    {
        return model('App\Models\Configuracion\ConfigVariableModel')->getVariable('POD')->value;
    }

    protected function loadLineasPresupuesto($presupuestoEntity)
    {
        $lineas = (new PresupuestoLineaModel())->getLineasPresupuesto($presupuestoEntity->id);

        $modelPapel = new PapelGenericoModel();
        foreach ($lineas as $linea) {
            $linea->papel_generico = (new PapelGenericoModel())->find($linea->papel_id)->nombre;
            if($linea->tipo == 'lp_faja'){
                $linea->alto_faja = $presupuestoEntity->alto_faja_color;
            }
        }

        $input_data = [];
        $input_data['presupuesto'] = $presupuestoEntity;

        return [false, $lineas];
    }

    protected function getLineasServicios($presupuestoEntity)
    {

        $serviciosPresupuesto = (object) array();

        $serviciosPresupuesto->serviciosAcabado = (new PresupuestoAcabadosModel())->getResource($presupuestoEntity->id)->get()->getResultObject();
        $serviciosPresupuesto->serviciosPreimpresion = (new PresupuestoPreimpresionesModel())->getResource($presupuestoEntity->id)->get()->getResultObject();
        $serviciosPresupuesto->serviciosEncuadernacion = (new PresupuestoEncuadernacionesModel())->getResource($presupuestoEntity->id)->get()->getResultObject();
        $serviciosPresupuesto->serviciosManipulado = (new PresupuestoManipuladosModel())->getResource($presupuestoEntity->id)->get()->getResultObject();
        $serviciosPresupuesto->serviciosExtra = (new PresupuestoServiciosExtraModel())->getResource($presupuestoEntity->id)->get()->getResultObject();

        $input_data = [];
        $input_data['presupuesto_id'] = $presupuestoEntity->id;
        $input_data['tipo_impresion_id'] = $presupuestoEntity->tipo_impresion_id;
        $input_data['tirada'] = (intval($presupuestoEntity->tirada) + intval($presupuestoEntity->merma));
        $input_data['POD'] = $this->getPOD();
        $input_data['paginas'] = $presupuestoEntity->paginas;
        $input_data['is_duplicado'] = $presupuestoEntity->is_duplicado;

        if ($presupuestoEntity->papel_formato_personalizado) {
            $input_data['ancho'] = $presupuestoEntity->papel_formato_ancho;
            $input_data['alto'] = $presupuestoEntity->papel_formato_alto;
        } else {
            $model = model("App\Models\Configuracion\PapelFormatoModel");
            $papel = $model->find($presupuestoEntity->papel_formato_id);
            if ($papel) {
                $input_data['ancho'] = $papel->ancho;
                $input_data['alto'] = $papel->alto;
            } else {
                $input_data['ancho'] = 0;
                $input_data['alto'] = 0;
            }
        }

        return PresupuestoService::checkLineasServicios($input_data, $serviciosPresupuesto);
    }

    protected function getLineasDirecciones($presupuestoEntity)
    {

        $model = model('App\Models\Presupuestos\PresupuestoDireccionesModel');
        $direccionesEnvio = $model->where('presupuesto_id', $presupuestoEntity->id)->findAll();

        return PresupuestoService::checkLineasEnvios($direccionesEnvio);
    }

    protected function obtenerDireccionesEnvio($id, $cliente_id)
    {
        $model = model('App\Models\Presupuestos\PresupuestoDireccionesModel');
        $model_direcciones = model('App\Models\Clientes\ClienteDireccionesModel');
        $direcciones = $model
            ->join('lg_proveedores', 'presupuesto_direcciones.proveedor_id = lg_proveedores.id')
            ->join('lg_paises', 'presupuesto_direcciones.pais_id = lg_paises.id')
            ->select('presupuesto_direcciones.*, lg_proveedores.nombre AS proveedor, lg_paises.nombre AS pais')
            ->where('presupuesto_id', $id)->findAll();

        return $direcciones;
    }
}
