<?php

namespace App\Controladores;

use App\Modelos\CarritoVentasModel;
use App\Modelos\EmpleadosComisionesEmplAgente;
use App\Modelos\Motor;
use App\Modelos\MovimientoModel;
use App\Modelos\Notadecredito;
use App\Modelos\NotadeCreditoDetalles;
use App\Modelos\Ordendeentrega;
use App\Modelos\OrdendeentregaArticulos;
use App\Modelos\OrdendeentregaDocumentos;
use App\Modelos\PlanillaCategoriaEmpleado;
use App\Modelos\PlanillaOrdenDeEntrega;
use App\Modelos\PlanillaPreOrden;
use App\Modelos\PlanillaPreOrdenPartes;
use App\Modelos\PlanillaPreOrdenServicios;
use App\Modelos\Productos;
use App\Modelos\VentasHistoricoEmail;
use Core\Controller;
use Core\Helpers\Documento;
use Core\Helpers\Moneda;
use Core\Helpers\Notifica;
use Core\Librerias\CarritoVentasEditar;
use Core\Librerias\Http;
use Core\Librerias\Module;
use Core\Vista;
use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\PHPMailer\Exception;

final class OrdendeentregaeditarControlador extends Controller
{
    private $array_errors = [];
    private $notas_entrega_model;
    private $divisa_master;
    private $module;
    private $carritoVentas;

    public function __construct()
    {
        parent::__construct();
        $this->module = new Module();
        $this->notas_entrega_model = new Ordendeentrega();
        $this->carritoVentas = new CarritoVentasEditar();
        $this->divisa_master = $this->notas_entrega_model->obtenerDivisaMaster();
    }

    public function verFactura(int $id_factura)
    {
        if ($_SERVER['REQUEST_METHOD'] == 'GET') {

            $id_factura = filter_var($id_factura, FILTER_SANITIZE_NUMBER_INT);
            $factura = $this->notas_entrega_model->obtenerFactura($id_factura);

            $doc = $this->carritoVentas->obtenerDocumentosPendientesPorPagarPorCliente($factura['n_cliid']);
            $pagot=Moneda::moneda($doc['total'],$this->divisa_master['div_locale'], $this->divisa_master['div_simbolo']);


                $clp=$this->carritoVentas->obtenerCliente($factura['n_cliid']);
                $rt=str_replace('(','',$clp['cli_telefono']);
                $rt=str_replace(')','',$rt);
                $rt=str_replace('-','',$rt);
                $rt=str_replace(' ','',$rt);

            if ($factura) {

                $newVentasHistoricoEmail = new VentasHistoricoEmail();
                $newPlanilla = new PlanillaOrdenDeEntrega();

                $orden_planilla = $newPlanilla->obtenerOrden($id_factura);

                $empleados = $GLOBALS['newDBIni']->consultar("SELECT einfo_id id, einfo_eliminado, CONCAT(einfo_nombres, ' ', einfo_apellidos) empleado FROM app_empleados_info WHERE einfo_id != 1 AND einfo_eliminado = 0")->all();

                $data_factura = [
                    'id_orden_planilla'     => $orden_planilla['po_preid'] ?? null,
                    'doc_'                  => Documento::obtener(12),
                    'pagot'                 => $pagot,
                    'telefonocli'           => $rt,
                    'cambiar_factor'        => $this->module->has_module_action_permission('facturacion', 'cambiar_factor', $_SESSION['user_data']['emp_id']),
                    'doc_pendientes'        => $this->carritoVentas->totalDocumentosPendientes($factura['n_cliid']),
                    'total_doc_pendientes'  => $this->carritoVentas->obtenerDocumentosPendientesPorPagarPorCliente($factura['n_cliid']),
                    'per_pagar'             => $this->module->has_module_action_permission('facturacion', 'pagar', $_SESSION['user_data']['emp_id']),
                    'impresoras'            => $this->notas_entrega_model->consultar("SELECT imp_id id, imp_descripcion impresora, imp_tipo tipo FROM app_impresoras WHERE imp_tipo = 3 AND imp_estatus = 1")->all(),
                    'imp_ticket'            => $this->notas_entrega_model->consultar("SELECT imp_id id, imp_descripcion impresora FROM app_impresoras WHERE imp_estatus = 1 AND imp_tipo = 2")->all(),
                    'historico_email'       => $newVentasHistoricoEmail->obtenerHistorico($id_factura),
                    'ruta'                  => $this->notas_entrega_model->rutaDocumento($factura['n_id']),
                    'anular_doc'            => $this->module->has_module_action_permission('facturacion', 'anular_doc', $_SESSION['user_data']['emp_id']),
                    'eliminar_pago'         => $this->module->has_module_action_permission('facturacion', 'eliminar_pagos', $_SESSION['user_data']['emp_id']),
                    'factura'               => $factura,
                    'empleados'             => $empleados,
                    'empleado'              => $this->carritoVentas->obtenerEmpleado($factura['n_empleadoid']),
                    'empresa'               => $this->carritoVentas->obtenerDatosEmpresa(),
                    'cliente'               => $this->carritoVentas->obtenerCliente($factura['n_cliid']),
                    'tipos_de_documentos'   => $this->carritoVentas->obternerTiposDeDocumentos(),
                    'impuestos'             => $this->carritoVentas->obtenerImpuestos(),
                    'paises'                => $this->carritoVentas->obtenerPaises(),
                    'almacenes'             => $this->carritoVentas->obtenerAlmacenesEmpleado(),
                    'series'                => $this->carritoVentas->obtenerSeriesEmpleado(),
                    'divisas'               => $this->carritoVentas->obtenerDivisasParaFacturar()
                ];

                if ($factura['n_estatus'] < 3 || $factura['n_estatus'] == 4) {
                    return Vista::view('ordendeentregaeditar/ver', $data_factura);
                } elseif ($factura['n_estatus'] == 3) {
                    return Vista::view('ordendeentregaeditar/anulado', $data_factura);
                }
            } else {
                header('Location: ' . ruta_base() . 'facturacion');
            }
        }
    }

    public function obtenerFactura(int $id_factura)
    {
        if ($_SERVER['REQUEST_METHOD'] == 'GET' && isAjax()) {

            $result = $this->carritoVentas->obtenerFactura('app_orden_de_entrega', 'oreditar', $id_factura);

            if (isset($result['errors'])) {
                return Http::json_response(['errors' => $result['errors']]);
            } else {
                return Http::json_response($result);
            }
        }
    }

    public function obtenerCreditosFactura(int $id_factura)
    {
        if ($_SERVER['REQUEST_METHOD'] == 'GET' && isAjax()) {
            Http::json_response($this->carritoVentas->obtenerCreditosFactura($id_factura, 12));
        }
    }

    public function predeterminarDivisa()
    {
        if ('GET' == $_SERVER['REQUEST_METHOD'] && isAjax()) {

            if (empty($_GET['id_factura']))
                $this->array_errors[] = 'La Factura es obligatorio';
            if (empty($_GET['id_divisa']))
                $this->array_errors[] = 'La Divisa es obligatorio';

            if (empty($this->array_errors)) {

                $id_divisa          = filter_input(INPUT_GET, 'id_divisa', FILTER_VALIDATE_INT);
                $id_factura         = filter_input(INPUT_GET, 'id_factura', FILTER_VALIDATE_INT);
                $descuento_global   = filter_input(INPUT_GET, 'descuento', FILTER_SANITIZE_STRING) ?? 0;

                if ($id_factura && $id_divisa) {
                    $data_factura = $this->notas_entrega_model->obtenerFactura($id_factura);
                    if ($data_factura) {
                        if ($this->esEditable($id_factura)) {
                            $result = $this->carritoVentas->predeterminarDivisa('oreditar', $id_factura, $data_factura['n_cliid'], $id_divisa, $descuento_global);
                            if (isset($result['errors'])) {
                                return Http::json_response(['errors' => $result['errors']]);
                            } else {
                                return Http::json_response($result);
                            }
                        } else {
                            $this->array_errors[] = 'Acción prohibida';
                        }
                    } else {
                        $this->array_errors[] = 'Acción prohibida';
                    }
                } else {
                    $this->array_errors[] = 'Acción prohibida';
                }
            }

            Http::json_response(['errors' => $this->array_errors]);
        }
    }

    public function agregarProductoBarcode()
    {
        if ('POST' == $_SERVER['REQUEST_METHOD'] && isAjax()) {

            if (empty($_POST['id_factura']))
                $this->array_errors[] = 'La Factura es obligatorio';
            if (empty($_POST['producto']))
                $this->array_errors[] = 'El Producto es obligatorio';
            if (empty($_POST['id_almacen']))
                $this->array_errors[] = 'El Almacen es obligatorio';
            if (empty($_POST['id_divisa']))
                $this->array_errors[] = 'La Divisa es obligatorio';

            if (empty($this->array_errors)) {

                $id_factura         = filter_input(INPUT_POST, 'id_factura', FILTER_VALIDATE_INT);
                $producto           = filter_input(INPUT_POST, 'producto', FILTER_SANITIZE_STRIPPED);
                $id_almacen         = filter_input(INPUT_POST, 'id_almacen', FILTER_VALIDATE_INT);
                $id_divisa          = filter_input(INPUT_POST, 'id_divisa', FILTER_VALIDATE_INT);
                $descuento_global   = filter_input(INPUT_POST, 'descuento_global', FILTER_SANITIZE_STRING) ?? 0;

                if ($id_factura && $id_almacen && $id_divisa) {
                    $data_factura = $this->notas_entrega_model->obtenerFactura($id_factura);
                    if ($data_factura) {
                        if ($this->esEditable($id_factura)) {
                            $result = $this->carritoVentas->agregarProductoBarcode('app_orden_de_entrega', 'oreditar', $id_factura, $data_factura['n_cliid'], $producto, $id_almacen, $id_divisa, $descuento_global);
                            if (isset($result['errors'])) {
                                return Http::json_response(['errors' => $result['errors']]);
                            } else {
                                return Http::json_response($result);
                            }
                        } else {
                            $this->array_errors[] = 'Acción prohibida';
                        }
                    }
                } else {
                    $this->array_errors[] = 'Acción prohibida';
                }
            }

            Http::json_response(['errors' => $this->array_errors]);
        }
    }

    public function agregarProducto()
    {
        if ('POST' == $_SERVER['REQUEST_METHOD'] && isAjax()) {

            if (empty($_POST['id_factura']))
                $this->array_errors[] = 'La Factura es obligatorio';
            if (empty($_POST['id_producto']))
                $this->array_errors[] = 'El Producto es obligatorio';
            if (empty($_POST['id_almacen']))
                $this->array_errors[] = 'El Almacen es obligatorio';
            if (empty($_POST['id_divisa']))
                $this->array_errors[] = 'La Divisa es obligatorio';

            if (empty($this->array_errors)) {

                $id_factura         = filter_input(INPUT_POST, 'id_factura', FILTER_VALIDATE_INT);
                $id_producto        = filter_input(INPUT_POST, 'id_producto', FILTER_VALIDATE_INT);
                $id_almacen         = filter_input(INPUT_POST, 'id_almacen', FILTER_VALIDATE_INT);
                $id_divisa          = filter_input(INPUT_POST, 'id_divisa', FILTER_VALIDATE_INT);
                $descuento_global   = filter_input(INPUT_POST, 'descuento_global', FILTER_SANITIZE_STRING) ?? 0;

                if ($id_factura && $id_producto && $id_almacen && $id_divisa) {
                    $data_factura = $this->notas_entrega_model->obtenerFactura($id_factura);
                    if ($data_factura) {
                        if ($this->esEditable($id_factura)) {
                            $result = $this->carritoVentas->agregarProducto('app_orden_de_entrega', 'oreditar', $id_factura, $data_factura['n_cliid'], $id_producto, $id_almacen, $id_divisa, $descuento_global);
                            if (isset($result['errors'])) {
                                return Http::json_response(['errors' => $result['errors']]);
                            } else {
                                return Http::json_response($result);
                            }
                        } else {
                            $this->array_errors[] = 'Acción prohibida';
                        }
                    } else {
                        $this->array_errors[] = 'Acción prohibida';
                    }
                } else {
                    $this->array_errors[] = 'Acción prohibida';
                }
            }

            Http::json_response(['errors' => $this->array_errors]);
        }
    }

    public function actualizarPrecio()
    {
        if ('POST' == $_SERVER['REQUEST_METHOD'] && isAjax()) {

            if (empty($_POST['id_factura']))
                $this->array_errors[] = 'El Factura es obligatorio';
            if (empty($_POST['unique']))
                $this->array_errors[] = 'El Producto es obligatorio';

            if (empty($this->array_errors)) {

                $id_factura         = filter_input(INPUT_POST, 'id_factura', FILTER_VALIDATE_INT);
                $unique             = filter_input(INPUT_POST, 'unique', FILTER_SANITIZE_STRIPPED);
                $precio             = filter_input(INPUT_POST, 'precio', FILTER_SANITIZE_STRING) ?? 0;
                $descuento_global   = filter_input(INPUT_POST, 'descuento_global', FILTER_SANITIZE_STRING) ?? 0;

                if ($id_factura) {
                    $data_factura = $this->notas_entrega_model->obtenerFactura($id_factura);
                    if ($data_factura) {
                        if ($this->esEditable($id_factura)) {
                            $result = $this->carritoVentas->actualizarPrecio('oreditar', $id_factura, $data_factura['n_cliid'], $unique, $precio, $descuento_global);
                            if (isset($result['errors'])) {
                                return Http::json_response(['errors' => $result['errors']]);
                            } else {
                                return Http::json_response($result);
                            }
                        } else {
                            $this->array_errors[] = 'Acción prohibida';
                        }
                    } else {
                        $this->array_errors[] = 'Acción prohibida';
                    }
                } else {
                    $this->array_errors[] = 'Acción prohibida';
                }
            }

            Http::json_response(['errors' => $this->array_errors]);
        }
    }

    public function pagoACredito()
    {
        if ('POST' == $_SERVER['REQUEST_METHOD'] && isAjax()) {

            if (empty($_POST['id_factura']))
                $this->array_errors[] = 'El Factura es obligatorio';
            if (empty($_POST['orden']))
                $this->array_errors[] = 'La orden es obligatorio';

            if (empty($this->array_errors)) {

                $orden         = filter_input(INPUT_POST, 'orden', FILTER_VALIDATE_INT);
                $id_factura         = filter_input(INPUT_POST, 'id_factura', FILTER_VALIDATE_INT);

                $newOrden = new PlanillaPreOrden();

                if ($id_factura) {
                    if ($this->esEditable($id_factura)) {

                        if (isset($result['errors'])) {
                            return Http::json_response(['errors' => $result['errors']]);
                        } else {

                            if ($orden && $newOrden->existe('pre_id', $orden)) {
                                $newOrden->editar($orden, [
                                    'pre_estatus' => 5
                                ]);
                            }


                            return Http::json_response($this->notas_entrega_model->editar($id_factura, [
                                'n_estatus'            => 4
                            ]));
                        }
                    } else {
                        return Http::json_response($this->notas_entrega_model->editar($id_factura, [
                            'n_estatus'            => 4
                        ]));
                    }
                } else {
                    $this->array_errors[] = 'Acción prohibida';
                }
            }

            Http::json_response(['errors' => $this->array_errors]);
        }
    }

    public function actualizarCantidad()
    {
        if ('POST' == $_SERVER['REQUEST_METHOD'] && isAjax()) {

            if (empty($_POST['id_factura']))
                $this->array_errors[] = 'El Factura es obligatorio';
            if (empty($_POST['id_producto']))
                $this->array_errors[] = 'El Producto es obligatorio';
            if (empty($_POST['cantidad']))
                $this->array_errors[] = 'El Cantidad es obligatorio';

            if (empty($this->array_errors)) {

                $id_factura         = filter_input(INPUT_POST, 'id_factura', FILTER_VALIDATE_INT);
                $id_producto        = filter_input(INPUT_POST, 'id_producto', FILTER_VALIDATE_INT);
                $cantidad           = filter_input(INPUT_POST, 'cantidad', FILTER_VALIDATE_FLOAT);
                $descuento_global   = filter_input(INPUT_POST, 'descuento_global', FILTER_SANITIZE_STRING) ?? 0;

                if ($id_factura && $id_producto && $cantidad) {
                    $data_factura = $this->notas_entrega_model->obtenerFactura($id_factura);
                    if ($data_factura) {
                        if ($this->esEditable($id_factura)) {
                            $result = $this->carritoVentas->actualizarCantidad('oreditar', 'app_orden_de_entrega', $id_factura, $data_factura['n_cliid'], $id_producto, $cantidad, $descuento_global);
                            if (isset($result['errors'])) {
                                return Http::json_response(['errors' => $result['errors']]);
                            } else {
                                return Http::json_response($result);
                            }
                        } else {
                            $this->array_errors[] = 'Acción prohibida';
                        }
                    } else {
                        $this->array_errors[] = 'Acción prohibida';
                    }
                } else {
                    $this->array_errors[] = 'Acción prohibida';
                }
            }

            Http::json_response(['errors' => $this->array_errors]);
        }
    }

    public function actualizarDescripcion()
    {
        if ('POST' == $_SERVER['REQUEST_METHOD'] && isAjax()) {

            if (empty($_POST['id_factura']))
                $this->array_errors[] = 'El Factura es obligatorio';
            if (empty($_POST['unique']))
                $this->array_errors[] = 'El Producto es obligatorio';
            if (empty($_POST['descripcion']))
                $this->array_errors[] = 'La Descripción es obligatorio';

            if (empty($this->array_errors)) {

                $id_factura         = filter_input(INPUT_POST, 'id_factura', FILTER_VALIDATE_INT);
                $unique             = filter_input(INPUT_POST, 'unique', FILTER_SANITIZE_STRING);
                $descripcion        = $this->solicitud->sanitize($_POST['descripcion'], FILTER_SANITIZE_STRING);

                if ($id_factura) {
                    $data_factura = $this->notas_entrega_model->obtenerFactura($id_factura);
                    if ($data_factura) {
                        if ($this->esEditable($id_factura)) {
                            $result = $this->carritoVentas->actualizarDescripcion('oreditar', $id_factura, $unique, $descripcion);
                            if (isset($result['errors'])) {
                                return Http::json_response(['errors' => $result['errors']]);
                            } else {
                                return Http::json_response($result);
                            }
                        } else {
                            $this->array_errors[] = 'Acción prohibida';
                        }
                    } else {
                        $this->array_errors[] = 'Acción prohibida';
                    }
                } else {
                    $this->array_errors[] = 'Acción prohibida';
                }
            }

            Http::json_response(['errors' => $this->array_errors]);
        }
    }

    public function aplicarNuevoIva()
    {
        if ('POST' == $_SERVER['REQUEST_METHOD'] && isAjax()) {

            if (empty($_POST['id_factura']))
                $this->array_errors[] = 'El Factura es obligatorio';
            if (empty($_POST['unique']))
                $this->array_errors[] = 'El Producto es obligatorio';
            if (empty($_POST['id_iva']))
                $this->array_errors[] = 'El IVA es obligatorio';

            if (empty($this->array_errors)) {

                $id_factura         = filter_input(INPUT_POST, 'id_factura', FILTER_VALIDATE_INT);
                $unique             = filter_input(INPUT_POST, 'unique', FILTER_SANITIZE_STRIPPED);
                $id_iva             = filter_input(INPUT_POST, 'id_iva', FILTER_VALIDATE_INT);
                $descuento_global   = filter_input(INPUT_POST, 'descuento_global', FILTER_SANITIZE_STRING) ?? 0;

                if ($id_factura && $id_iva) {
                    $data_factura = $this->notas_entrega_model->obtenerFactura($id_factura);
                    if ($data_factura) {
                        if ($this->esEditable($id_factura)) {
                            $result = $this->carritoVentas->aplicarNuevoIva('oreditar', $id_factura, $data_factura['n_cliid'], $unique, $id_iva, $descuento_global);
                            if (isset($result['errors'])) {
                                return Http::json_response(['errors' => $result['errors']]);
                            } else {
                                return Http::json_response($result);
                            }
                        } else {
                            $this->array_errors[] = 'Acción prohibida';
                        }
                    } else {
                        $this->array_errors[] = 'Acción prohibida';
                    }
                } else {
                    $this->array_errors[] = 'Acción prohibida';
                }
            }

            Http::json_response(['errors' => $this->array_errors]);
        }
    }

    public function aplicarDescuentoProducto()
    {
        if ('POST' == $_SERVER['REQUEST_METHOD'] && isAjax()) {

            if (empty($_POST['id_factura']))
                $this->array_errors[] = 'La Factura es obligatorio';
            if (empty($_POST['unique']))
                $this->array_errors[] = 'El Producto es obligatorio';

            if (empty($this->array_errors)) {

                $id_factura         = filter_input(INPUT_POST, 'id_factura', FILTER_VALIDATE_INT);
                $unique             = filter_input(INPUT_POST, 'unique', FILTER_SANITIZE_STRIPPED);
                $descuento          = filter_input(INPUT_POST, 'descuento', FILTER_SANITIZE_STRING) ?? 0;
                $descuento_global   = filter_input(INPUT_POST, 'descuento_global', FILTER_SANITIZE_STRING) ?? 0;

                if ($id_factura) {
                    $data_factura = $this->notas_entrega_model->obtenerFactura($id_factura);
                    if ($data_factura) {
                        if ($this->esEditable($id_factura)) {
                            $result = $this->carritoVentas->aplicarDescuentoProducto('oreditar', $id_factura, $data_factura['n_cliid'], $unique, $descuento, $descuento_global);
                            if (isset($result['errors'])) {
                                return Http::json_response(['errors' => $result['errors']]);
                            } else {
                                return Http::json_response($result);
                            }
                        } else {
                            $this->array_errors[] = 'Acción prohibida';
                        }
                    } else {
                        $this->array_errors[] = 'Acción prohibida';
                    }
                } else {
                    $this->array_errors[] = 'Acción prohibida';
                }
            }

            Http::json_response(['errors' => $this->array_errors]);
        }
    }

    public function aplicarDescuentoAdicional()
    {
        if ('POST' == $_SERVER['REQUEST_METHOD'] && isAjax()) {

            if (empty($_POST['id_factura'])) {
                $this->array_errors[] = 'La Factura es obligatorio';
            } else {

                $id_factura = filter_input(INPUT_POST, 'id_factura', FILTER_VALIDATE_INT);
                $descuento_global = filter_input(INPUT_POST, 'descuento', FILTER_SANITIZE_STRING) ?? 0;

                if ($id_factura) {
                    $data_factura = $this->notas_entrega_model->obtenerFactura($id_factura);
                    if ($data_factura) {
                        if ($this->esEditable($id_factura)) {
                            $result = $this->carritoVentas->aplicarDescuentoAdicional('oreditar', $id_factura, $data_factura['n_cliid'], $descuento_global);
                            if (isset($result['errors'])) {
                                return Http::json_response(['errors' => $result['errors']]);
                            } else {
                                return Http::json_response($result);
                            }
                        } else {
                            $this->array_errors[] = 'Acción prohibida';
                        }
                    } else {
                        $this->array_errors[] = 'Acción prohibida';
                    }
                } else {
                    $this->array_errors[] = 'Acción prohibida';
                }
            }

            Http::json_response(['errors' => $this->array_errors]);
        }
    }

    public function eliminarProducto()
    {
        if ('POST' == $_SERVER['REQUEST_METHOD'] && isAjax()) {

            if (empty($_POST['id_factura']))
                $this->array_errors[] = 'El Cliente es obligatorio';
            if (empty($_POST['id_producto']))
                $this->array_errors[] = 'El Producto es obligatorio';

            if (empty($this->array_errors)) {

                $id_factura         = filter_input(INPUT_POST, 'id_factura', FILTER_VALIDATE_INT);
                $unique             = filter_input(INPUT_POST, 'id_producto', FILTER_SANITIZE_STRING);
                $descuento_global   = filter_input(INPUT_POST, 'descuento_global', FILTER_SANITIZE_STRING) ?? 0;

                if ($id_factura) {
                    $data_factura = $this->notas_entrega_model->obtenerFactura($id_factura);
                    if ($data_factura) {
                        if ($this->esEditable($id_factura)) {
                            $result = $this->carritoVentas->eliminarProducto('oreditar', 'app_orden_de_entrega', $id_factura, $data_factura['n_cliid'], $unique, $descuento_global);
                            if (isset($result['errors'])) {
                                return Http::json_response(['errors' => $result['errors']]);
                            } else {
                                return Http::json_response($result);
                            }
                        } else {
                            $this->array_errors[] = 'Acción prohibida';
                        }
                    } else {
                        $this->array_errors[] = 'Acción prohibida';
                    }
                } else {
                    $this->array_errors[] = 'Acción prohibida';
                }
            }

            Http::json_response(['errors' => $this->array_errors]);
        }
    }

    public function guardarDetallesCliente()
    {
        if ('POST' === $_SERVER['REQUEST_METHOD'] && isAjax()) {

            if (empty($_POST['cli_tipodoc']))
                $this->array_errors[] = 'El campo Cedula de identidad es obligatorio';
            if (empty($_POST['cli_dni']))
                $this->array_errors[] = 'El campo Tipo de documento es obligatorio';
            if (empty($_POST['cli_razon_social']))
                $this->array_errors[] = 'El campo Razón social es obligatorio';
            if (empty($_POST['cli_direccion']))
                $this->array_errors[] = 'El campo Dirección es obligatorio';

            if (empty($this->array_errors)) {

                $cli_id             = filter_input(INPUT_POST, 'id', FILTER_SANITIZE_NUMBER_INT);
                $cli_tipodoc        = filter_input(INPUT_POST, 'cli_tipodoc', FILTER_SANITIZE_NUMBER_INT);
                $cli_dni            = filter_input(INPUT_POST, 'cli_dni', FILTER_SANITIZE_STRING);
                $cli_nombres        = $this->solicitud->sanitize($_POST['cli_razon_social'], FILTER_SANITIZE_STRING);
                $cli_direccion      = $this->solicitud->sanitize($_POST['cli_direccion'], FILTER_SANITIZE_STRING);
                $cli_pais           = filter_input(INPUT_POST, 'cli_paisid', FILTER_SANITIZE_NUMBER_INT);
                $cli_estado         = $this->solicitud->sanitize($_POST['cli_estado'], FILTER_SANITIZE_STRING);
                $cli_ciudad         = $this->solicitud->sanitize($_POST['cli_ciudad'], FILTER_SANITIZE_STRING);
                $cli_codigopostal   = filter_input(INPUT_POST, 'cli_codigopostal', FILTER_SANITIZE_STRING);

                $result = $this->carritoVentas->editarDetallesCliente($cli_id, [
                    'cli_tipodocid'     => $cli_tipodoc,
                    'cli_dni'           => $cli_dni,
                    'cli_razon_social'  => $cli_nombres,
                    'cli_direccion'     => $cli_direccion,
                    'cli_paisid'        => $cli_pais,
                    'cli_estado'        => $cli_estado,
                    'cli_ciudad'        => $cli_ciudad,
                    'cli_codpostal'     => $cli_codigopostal
                ]);

                if (isset($result['errors'])) {
                    return Http::json_response(['errors' => $result['errors']]);
                } else {
                    return Http::json_response($result);
                }
            }

            Http::json_response(['errors' => $this->array_errors]);
        }
    }

    public function enviarDocumento()
    {
        if ('POST' === $_SERVER['REQUEST_METHOD'] && isAjax()) {

            if (empty($_POST['id_factura']))
                $this->array_errors[] = 'Acción prohibida';
            if (empty($_POST['descripcion']))
                $this->array_errors[] = 'El campo Descripcion es obligatorio.';
            if (empty($_FILES['documento']))
                $this->array_errors[] = 'El documento es obligatorio.';

            if (empty($this->array_errors)) {

                $id_factura = filter_var($_POST['id_factura'], FILTER_VALIDATE_INT);
                $descripcion = $this->solicitud->sanitize($_POST['descripcion'], FILTER_SANITIZE_STRING);

                if ($id_factura) {
                    $result = $this->carritoVentas->enviarDocumento('app_orden_de_entrega', $id_factura, $_FILES, $descripcion);
                    if (isset($result['errors'])) {
                        return Http::json_response(['errors' => $result['errors']]);
                    } else {
                        return Http::json_response($result);
                    }
                } else {
                    $this->array_errors[] = 'Acción prohibida';
                }
            }

            Http::json_response(['errors' => $this->array_errors]);
        }
    }

    public function guardarClienteCambiar()
    {
        if ('POST' === $_SERVER['REQUEST_METHOD'] && isAjax()) {

            if (empty($_POST['id_factura']))
                $this->array_errors[] = 'Acción prohibida';
            if (empty($_POST['cli_tipodoc']))
                $this->array_errors[] = 'El campo Cedula de identidad es obligatorio';
            if (empty($_POST['cli_dni']))
                $this->array_errors[] = 'El campo Tipo de documento es obligatorio';
            if (empty($_POST['cli_razon_social']))
                $this->array_errors[] = 'El campo Razón social es obligatorio';
            if (empty($_POST['cli_direccion']))
                $this->array_errors[] = 'El campo Dirección es obligatorio';

            if (empty($this->array_errors)) {

                $id_factura         = filter_input(INPUT_POST, 'id_factura', FILTER_SANITIZE_NUMBER_INT);
                $cli_id             = filter_input(INPUT_POST, 'id', FILTER_SANITIZE_NUMBER_INT);
                $cli_tipodoc        = filter_input(INPUT_POST, 'cli_tipodoc', FILTER_SANITIZE_NUMBER_INT);
                $cli_dni            = filter_input(INPUT_POST, 'cli_dni', FILTER_SANITIZE_STRING);
                $cli_email          = filter_input(INPUT_POST, 'cli_email', FILTER_SANITIZE_STRING);
                $cli_telefono       = filter_input(INPUT_POST, 'cli_telefono', FILTER_SANITIZE_STRING);
                $cli_nombres        = $this->solicitud->sanitize($_POST['cli_razon_social'], FILTER_SANITIZE_STRING);
                $cli_direccion      = $this->solicitud->sanitize($_POST['cli_direccion'], FILTER_SANITIZE_STRING);
                $cli_natural        = ('true' == filter_input(INPUT_POST, 'cli_natural')) ? 1 : 0;

                if ($this->esEditable($id_factura)) {
                    $result = $this->carritoVentas->guardarClienteCambiar('app_orden_de_entrega', $id_factura, [
                        'cli_tipodocid'     => $cli_tipodoc,
                        'cli_dni'           => $cli_dni,
                        'cli_razon_social'  => $cli_nombres,
                        'cli_direccion'     => $cli_direccion,
                        'cli_natural'       => $cli_natural,
                        'cli_email'         => $cli_email,
                        'cli_telefono'      => $cli_telefono
                    ]);
                    if (isset($result['errors'])) {
                        return Http::json_response(['errors' => $result['errors']]);
                    } else {
                        return Http::json_response($result);
                    }
                } else {
                    $this->array_errors[] = 'Documento no editable';
                }
            }

            Http::json_response(['errors' => $this->array_errors]);
        }
    }

    public function cambiarCliente()
    {
        if ($_SERVER['REQUEST_METHOD'] == 'GET' && isAjax()) {

            $id_cliente     = filter_input(INPUT_GET, 'id_cliente', FILTER_SANITIZE_NUMBER_INT);
            $id_factura     = filter_input(INPUT_GET, 'id_factura', FILTER_SANITIZE_NUMBER_INT);

            if (!empty($id_cliente) && !empty($id_factura)) {
                if ($this->esEditable($id_factura)) {
                    $result = $this->carritoVentas->cambiarCliente('app_orden_de_entrega', $id_cliente, $id_factura);
                    if (isset($result['errors'])) {
                        return Http::json_response(['errors' => $result['errors']]);
                    } else {
                        $planilla = $GLOBALS['newDBIni']->consultar("SELECT * FROM app_planilla_orden_de_entrega WHERE po_nid = $id_factura")->row();

                        if ($planilla['po_preid'] > 0) {
                            $GLOBALS['newDBIni']->consultar("UPDATE app_preorden_master SET pre_cliid = {$id_cliente} WHERE pre_id = {$planilla['po_preid']}")->run();
                        }

                        return Http::json_response($result);
                    }
                } else {
                    $this->array_errors[] = 'Documento no editable';
                }
            } else {
                $this->array_errors[] = 'Acción prohibida';
            }

            Http::json_response(['errors' => $this->array_errors]);
        }
    }

    //METODOS PROPIO DEL CONTRALADOR

    public function ventaEnEsperaEditar()
    {
        if ($_SERVER['REQUEST_METHOD'] == 'POST' && isAjax()) {

            $id_serie       = filter_input(INPUT_POST, 'id_serie', FILTER_SANITIZE_NUMBER_INT);
            $id_factura     = filter_input(INPUT_POST, 'id_factura', FILTER_SANITIZE_NUMBER_INT);
            $desci          = ('true' == filter_input(INPUT_POST, 'descontar_inventario')) ? true : false;
            $fecha          = filter_input(INPUT_POST, 'fecha', FILTER_SANITIZE_STRING);
            $observaciones  = filter_input(INPUT_POST, 'observaciones', FILTER_SANITIZE_STRING) ?? '';
            $cantidad_descontada = 0;

            if (!empty($id_factura)) {

                if (empty($id_serie))
                    $this->array_errors[] = 'El campo Serie es obligatorio.';
                if (empty($fecha))
                    $this->array_errors[] = 'Debe seleccionar una fecha.';

                if (empty($this->array_errors)) {

                    $notas_entrega_articulos_model = new OrdendeentregaArticulos();
                    $serie = $this->carritoVentas->obtenerSerie($id_serie);
                    $factura = $this->notas_entrega_model->obtenerFactura($id_factura);
                    $cliente = $this->carritoVentas->obtenerCliente($factura['n_cliid']);
                    $fecha = date('Y-m-d', strtotime($fecha)) . ' ' . date('H:i:s');
                    $factor = 1;
                    $total_procosto = 0;
                    $total_costo_servicio = 0;

                    if ($cliente && $serie && $factura) {

                        if ($this->esEditable($id_factura)) {

                            $articulos = $this->carritoVentas->contenidoCarrito('oreditar', $id_factura);
                            $ne_decontado = $factura['n_descontado'];

                            foreach ($articulos as $row) {
                                if ($row['precio'] == 0 || $row['total'] == 0) {
                                    $this->array_errors[] = "Lo siento el total del producto <strong>{$row['nombre']}</strong> no puede quedar en cero";
                                }
                            }

                            $planilla = $GLOBALS['newDBIni']->consultar("SELECT * FROM app_planilla_orden_de_entrega WHERE po_nid = $id_factura")->row();

                            if (empty($this->array_errors) && ($factura['n_descontado'] == 1 || $desci == true)) {
                                $ne_decontado = 1;

                                foreach ($articulos as $row) {
                                    $detalles_producto = $notas_entrega_articulos_model->obtenerDetalleProductoFacturado($id_factura, $row['id'], $row['id_almacen']);
                                    $cantidad = $this->carritoVentas->chuequearStock($row['id'], $row['id_almacen']);
                                    $data_p = $this->carritoVentas->obtenerProducto($row['id']);
                                    if ($planilla && $data_p['pro_tipo'] == 3) {
                                        if (!$GLOBALS['newDBIni']->consultar("SELECT serv_id FROM app_planillas_servicios WHERE serv_proid = {$row['id']}")->row()) {
                                            $this->array_errors[] = "Lo siento el servicio que intenta agregar no se encuentra asociado a una categoria. Porfavor dirijace al modulo de configuración de planilla y asocie el servicio a un categoria";
                                        }
                                    }
                                    if ($data_p['pro_tipo'] != 3) {
                                        if ($data_p['pro_nostock'] == 0) {
                                            if ($detalles_producto) {
                                                if ($cantidad) {
                                                    if ($detalles_producto['nart_procantidad'] < $row['cantidad'] && $cantidad['ps_cantidad'] < ($row['cantidad'] - $detalles_producto['nart_descontar_inventario'])) {
                                                        $this->array_errors[] = "Lo siento la cantidad a descontar del producto {$row['nombre']} supera la cantidad existente en Stock";
                                                    }
                                                } else {
                                                    $this->array_errors[] = "Lo siento el producto {$row['nombre']} no tiene existencia en el almacen seleccionado";
                                                }
                                            } else {
                                                if ($cantidad) {
                                                    if ($cantidad['ps_cantidad'] < $row['cantidad']) {
                                                        $this->array_errors[] = "Lo siento la cantidad a descontar del producto {$row['nombre']} supera la cantidad existente en Stock";
                                                    }
                                                } else {
                                                    $this->array_errors[] = "Lo siento el producto {$row['nombre']} no tiene existencia en el almacen seleccionado";
                                                }
                                            }
                                        }
                                    }
                                }
                            }

                            if (empty($this->array_errors)) {

                                if ($this->divisa_master['div_id'] != $_SESSION["oreditar$id_factura"]['divisa']) {
                                    $factor_div = $this->notas_entrega_model->obtenerDivisaAlCambio($_SESSION["oreditar$id_factura"]['divisa'], $this->divisa_master['div_id']);
                                    $factor = $factor_div['df_factor'];
                                }

                                if ($this->notas_entrega_model->editar($id_factura, [
                                    'n_subtotal'           => $_SESSION["oreditar$id_factura"]['subtotal'],
                                    'n_descuento'          => $_SESSION["oreditar$id_factura"]['descuento'],
                                    'n_neto'               => $_SESSION["oreditar$id_factura"]['neto'],
                                    'n_iva'                => $_SESSION["oreditar$id_factura"]['iva'],
                                    'n_total'              => $_SESSION["oreditar$id_factura"]['total'],
                                    'n_articulos_total'    => $_SESSION["oreditar$id_factura"]['articulos_cantidad'],
                                    'n_divid'              => $_SESSION["oreditar$id_factura"]['divisa'],
                                    'n_serid'              => $serie['ser_id'],
                                    'n_serie'              => $serie['ser_descripcion'],
                                    'n_empresaid'          => 1,
                                    //'n_empleadoid'         => $_SESSION['user_data']['einfo_id'],
                                    'n_fecha'              => $fecha,
                                    'n_cliid'              => $cliente['cli_id'],
                                    'n_env_nombres'        => $cliente['cli_razon_social'],
                                    'n_env_direccion'      => $cliente['cli_direccion'],
                                    'n_env_pais'           => $cliente['cli_paisid'],
                                    'n_env_estado'         => $cliente['cli_estado'],
                                    'n_env_ciudad'         => $cliente['cli_ciudad'],
                                    'n_env_codigo_postal'  => $cliente['cli_codpostal'],
                                    'n_estatus'            => 2,
                                    'n_observaciones'      => $observaciones,
                                    'n_descontado'         => $ne_decontado,
                                    'factor'                => $factor
                                ])) {

                                    foreach ($articulos as $row) {

                                        $detalles_producto = $notas_entrega_articulos_model->obtenerDetalleProductoFacturado($id_factura, $row['id'], $row['id_almacen']);
                                        $almacen  = $this->carritoVentas->obtenerAlmacen($row['id_almacen']);
                                        $producto = $this->carritoVentas->obtenerProducto($row['id']);
                                        $cantidad_stock = $this->carritoVentas->chuequearStock($row['id'], $row['id_almacen']);

                                        if ($detalles_producto) {

                                            $cantidad_descontada = $detalles_producto['nart_descontar_inventario'];

                                            if ($producto['pro_tipo'] != 3) {
                                                if ($detalles_producto['nart_procantidad'] > $row['cantidad'] && $ne_decontado == 1) {
                                                    $cantidad = $detalles_producto['nart_procantidad'] - $row['cantidad'];
                                                    if ($this->notas_entrega_model->restablecerStock($row['id'], $row['id_almacen'], $cantidad)) {
                                                        Notifica::stock($row['id'], $almacen['alm_nombre'], 'ventas', $cantidad_stock['ps_cantidad'] ?? 0, $cantidad, 0, ($cantidad_stock['ps_cantidad'] ?? 0) + $cantidad, $factura['n_correlativo'], 12);
                                                        $cantidad_descontada = $detalles_producto['nart_descontar_inventario'] - $cantidad;
                                                    }
                                                } else {
                                                    if (($desci == true || $ne_decontado == 1) && $detalles_producto['nart_descontar_inventario'] < $row['cantidad']) {
                                                        $cantidad_a_descontar = $row['cantidad'] - $detalles_producto['nart_descontar_inventario'];
                                                        if ($cantidad_a_descontar > 0 && $this->notas_entrega_model->desontardeStock($row['id'], $row['id_almacen'], $cantidad_a_descontar)) {
                                                            Notifica::stock($row['id'], $almacen['alm_nombre'], 'ventas', $cantidad_stock['ps_cantidad'] ?? 0, 0, $cantidad_a_descontar, ($cantidad_stock['ps_cantidad'] ?? 0) - $cantidad_a_descontar, $factura['n_correlativo'], 12);
                                                            $cantidad_descontada = $detalles_producto['nart_descontar_inventario'] + $cantidad_a_descontar;
                                                        }
                                                    }
                                                }
                                            }

                                            if ($notas_entrega_articulos_model->editar($detalles_producto['nart_id'], [
                                                'nart_procodigo'               => $row['codigo'],
                                                'nart_propnombre'              => $row['nombre'],
                                                'nart_procosto'                => $row['costo'],
                                                'nart_costo_servicio'          => $row['costo_servicio'],
                                                'nart_proprecio'               => $row['precio'],
                                                'nart_procantidad'             => $row['cantidad'],
                                                'nart_prodescuento'            => $row['descuento'],
                                                'nart_proneto'                 => $row['neto'],
                                                'nart_idiva'                   => $row['id_iva'],
                                                'nart_proiva'                  => $row['iva'],
                                                'nart_ivatotal'                => $row['iva_total'],
                                                'nart_prototal'                => $row['total'],
                                                'nart_descontar_inventario'    => $cantidad_descontada,
                                            ])) {

                                                if ($producto['pro_tipo'] == 3) {

                                                    if ($planilla) {

                                                        $data_servicio = $GLOBALS['newDBIni']->consultar("SELECT preserv_id
                                                        FROM app_preorden_master m
                                                        JOIN app_preorden_master_servicios ms ON ms.preserv_preid = m.pre_id
                                                        JOIN app_planillas_servicios s ON ms.preserv_servid = s.serv_id
                                                        WHERE pre_id = {$planilla['po_preid']} AND serv_proid = {$producto['pro_id']}")->row();

                                                        $GLOBALS['newDBIni']->consultar("UPDATE app_preorden_master_servicios SET preserv_cantidad = {$row['cantidad']} WHERE preserv_id = {$data_servicio['preserv_id']}")->run();
                                                    }

                                                    $total_costo_servicio += $row['costo_servicio'] * $row['cantidad'];
                                                } else {
                                                    $total_procosto += $row['costo'] * $row['cantidad'];
                                                }
                                            }
                                        } else {

                                            $cantidad_descontada = 0;

                                            if ($producto['pro_tipo'] != 3 && ($desci == true || $ne_decontado == 1) && $this->notas_entrega_model->desontardeStock($row['id'], $row['id_almacen'], $row['cantidad'])) {
                                                $cantidad_descontada = $row['cantidad'];
                                                Notifica::stock($row['id'], $almacen['alm_nombre'], 'ventas', $cantidad_stock['ps_cantidad'] ?? 0, 0, $row['cantidad'], ($cantidad_stock['ps_cantidad'] ?? 0) - $row['cantidad'], $factura['n_correlativo'], 12);
                                            }

                                            if ($notas_entrega_articulos_model->guardar([
                                                'nart_nid'                    => $id_factura,
                                                'nart_proid'                   => $row['id'],
                                                'nart_procodigo'               => $row['codigo'],
                                                'nart_propnombre'              => $row['nombre'],
                                                'nart_procosto'                => $row['costo'],
                                                'nart_costo_servicio'          => $row['costo_servicio'],
                                                'nart_proprecio'               => $row['precio'],
                                                'nart_procantidad'             => $row['cantidad'],
                                                'nart_prodescuento'            => $row['descuento'],
                                                'nart_proneto'                 => $row['neto'],
                                                'nart_idiva'                   => $row['id_iva'],
                                                'nart_almid'                   => $row['id_almacen'],
                                                'nart_proiva'                  => $row['iva'],
                                                'nart_ivatotal'                => $row['iva_total'],
                                                'nart_prototal'                => $row['total'],
                                                'nart_descontar_inventario'    => $cantidad_descontada,
                                            ], true)) {

                                                if ($producto['pro_tipo'] == 3) {
                                                    if ($planilla) {
                                                        $data_servicio = $GLOBALS['newDBIni']->consultar("SELECT serv_id FROM app_planillas_servicios WHERE serv_proid = {$producto['pro_id']}")->row();
                                                        $GLOBALS['newDBIni']->consultar("INSERT INTO app_preorden_master_servicios(preserv_preid, preserv_servid, preserv_cantidad) VALUES({$planilla['po_preid']}, {$data_servicio['serv_id']}, {$row['cantidad']})")->run();
                                                    }
                                                }

                                                if ($producto['pro_tipo'] == 3) {
                                                    $total_costo_servicio += $row['costo_servicio'] * $row['cantidad'];
                                                } else {
                                                    $total_procosto += $row['costo'] * $row['cantidad'];
                                                }
                                            }
                                        }
                                    }

                                    $this->notas_entrega_model->editar($id_factura, [
                                        'total_procosto' => $total_procosto,
                                        'total_costo_servicio' => $total_costo_servicio,
                                    ]);

                                    $this->carritoVentas->recalcularComisiones($id_factura, 12);

                                    Http::json_response(ruta_base() . 'ordendeentregaeditar/verFactura/' . $id_factura);
                                } else {
                                    $this->array_errors[] = 'Los siento ocurrio un error al guardar la venta';
                                }
                            }
                        } else {
                            $this->array_errors[] = 'La nota de etrega a sido pagada en su totalidad por lo tanto no puede ser modificada.';
                        }
                    }
                }

                Http::json_response(['errors' => $this->array_errors]);
            }
        }
    }

    public function guardarEnvioCliente()
    {
        if ('POST' === $_SERVER['REQUEST_METHOD'] && isAjax()) {

            $id_factura             = filter_input(INPUT_POST, 'id_factura', FILTER_SANITIZE_NUMBER_INT);
            $env_nombre_opcional    = filter_input(INPUT_POST, 'env_nombre_opcional', FILTER_SANITIZE_STRING);
            $env_agencia_transporte = filter_input(INPUT_POST, 'env_agencia_transporte', FILTER_SANITIZE_STRING);
            $env_codigo_seguimiento = filter_input(INPUT_POST, 'env_codigo_seguimiento', FILTER_SANITIZE_STRING);
            $env_direccion          = filter_input(INPUT_POST, 'env_direccion', FILTER_SANITIZE_STRING);
            $env_pais               = filter_input(INPUT_POST, 'env_pais', FILTER_SANITIZE_NUMBER_INT);
            $env_estado             = filter_input(INPUT_POST, 'env_estado', FILTER_SANITIZE_STRING);
            $env_ciudad             = filter_input(INPUT_POST, 'env_ciudad', FILTER_SANITIZE_STRING);
            $env_codigopostal       = filter_input(INPUT_POST, 'env_codigopostal', FILTER_SANITIZE_STRING);
            $env_asegurado          = ('true' == filter_input(INPUT_POST, 'env_asegurado')) ? 1 : 0;

            if (!empty($id_factura)) {

                if (empty($env_agencia_transporte))
                    $this->array_errors[] = 'El campo Agencia de tranporte es obligatorio.';
                if (empty($env_codigo_seguimiento))
                    $this->array_errors[] = 'El campo Codigo de seguimiento es obligatorio.';
                if (empty($env_direccion))
                    $this->array_errors[] = 'El campo Dirección obligatorio.';
                if (empty($env_pais))
                    $this->array_errors[] = 'El campo País es obligatorio.';
                if (empty($env_estado))
                    $this->array_errors[] = 'El campo Estado es obligatorio.';
                if (empty($env_ciudad))
                    $this->array_errors[] = 'El campo Ciudad es obligatorio.';
                if (empty($env_codigopostal))
                    $this->array_errors[] = 'El campo Codigo postal es obligatorio.';

                if (empty($this->array_errors)) {

                    $data_factura = $this->notas_entrega_model->obtenerFactura($id_factura);

                    if ($data_factura['n_estatus'] != 1) {
                        Http::json_response($this->notas_entrega_model->editar($id_factura, [
                            'n_env_nombres'            => $env_nombre_opcional ?? $data_factura['n_env_nombres'],
                            'n_env_direccion'          => $env_direccion,
                            'n_env_pais'               => $env_pais,
                            'n_env_estado'             => $env_estado,
                            'n_env_ciudad'             => $env_ciudad,
                            'n_env_codigo_postal'      => $env_codigopostal,
                            'n_env_agencia_transporte' => $env_agencia_transporte,
                            'n_env_codigo_seguimiento' => $env_codigo_seguimiento,
                            'n_env_asegurado'          => $env_asegurado
                        ]));
                    } else {
                        $this->array_errors[] = 'La factura no se puede editar ya que ha sigo pagada en su totalidad.';
                    }
                }
            }

            Http::json_response(['errors' => $this->array_errors]);
        }
    }

    public function comprobarFactura(int $id_factura)
    {
        if ('GET' === $_SERVER['REQUEST_METHOD'] && isAjax()) {
            $id_factura = filter_var($id_factura, FILTER_SANITIZE_NUMBER_INT);
            $factura = $this->notas_entrega_model->obtenerFactura($id_factura);
            if ($factura['n_estatus'] == 1) {
                $this->array_errors[] = 'Ya la factura a sido pagada en su totalidad';
            } else {
                Http::json_response(true);
            }
            Http::json_response(['errors' => $this->array_errors]);
        }
    }

    private function esEditable(int $id_factura)
    {
        $factura = $this->notas_entrega_model->obtenerFactura($id_factura);
        return ($factura['n_estatus'] == 1) ? false : true;
    }

    private function facturaFinalizada($id_factura)
    {
        $movimiento_model = new MovimientoModel();
        $factura = $this->notas_entrega_model->obtenerFactura($id_factura);
        $total_pagos = $movimiento_model->totalPagos($id_factura, 12,1);
        return (round($total_pagos['total'], 2) >= round($factura['n_total'], 2)) ? true : false;
    }

    public function obtenerMetodosSegunDivisa()
    {
        if ('POST' == $_SERVER['REQUEST_METHOD'] && isAjax()) {

            $id_divisa = filter_input(INPUT_POST, 'id_divisa', FILTER_SANITIZE_NUMBER_INT);
            $id_factura = filter_input(INPUT_POST, 'id_factura', FILTER_SANITIZE_NUMBER_INT);
            $factor = 1;

            if (empty($id_divisa))
                $this->array_errors[] = 'Debe seleccionar una divisa';

            if (!empty($id_factura) && empty($this->array_errors)) {

                $factura = $this->notas_entrega_model->obtenerFactura($id_factura);
                $divisa = Moneda::obtenerDivisa($id_divisa);

                if ($divisa && $factura) {

                    $movimiento_model = new MovimientoModel();
                    $data_metodos = $this->notas_entrega_model->obtenerMetodosSegunDivisa($id_divisa);

                    if ($data_metodos) {

                        if ($factura['n_divid'] != $divisa['id']) {
                            $divisa_factor = $this->notas_entrega_model->obtenerDivisaAlCambio($factura['n_divid'], $divisa['id']);
                            if ($divisa_factor) {
                                $factor = $divisa_factor['df_factor'];
                            } else {
                                $this->array_errors[] = 'Lo siento no se encuentra ningun valor de conversión para la moneda que intenta escoger y la moneda en que se realizo la factura';
                            }
                        }

                        if (empty($this->array_errors)) {
                            $total_pagos = $movimiento_model->totalPagos($factura['n_id'], 12,1);
                            $total = round(($factura['n_total'] - ($total_pagos['total'] ?? 0)), 2);
                            Http::json_response([
                                'factor'        => $factor,
                                'divisa'        => $divisa,
                                'data_metodos'  => $data_metodos,
                                'restante'      => $total
                            ]);
                        }
                    }
                }
            }

            Http::json_response(['errors' => $this->array_errors]);
        }
    }

    public function obtenerCuentasSegunMetodo($id_metodo_divisa)
    {
        if ('GET' == $_SERVER['REQUEST_METHOD'] && isAjax()) {

            $id_metodo_divisa = filter_var($id_metodo_divisa, FILTER_SANITIZE_NUMBER_INT);

            if (empty($id_metodo_divisa))
                $this->array_errors[] = 'Debe seleccionar un metodo';

            if (empty($this->array_errors)) {
                $data = $this->notas_entrega_model->obtenerCuentasSegunMetodo($id_metodo_divisa);
                if ($data) {
                    Http::json_response($data);
                } else {
                    $this->array_errors[] = 'Lo siento no hay cuentas registradas para este metoto de pago';
                }
            }

            Http::json_response(['errors' => $this->array_errors]);
        }
    }

    public function pagar()
    {
        if ($_SERVER['REQUEST_METHOD'] == 'POST' && isAjax()) {

            $per_pagar = $this->module->has_module_action_permission('facturacion', 'pagar', $_SESSION['user_data']['emp_id']);

            if ($per_pagar) {

                $id_factura         = filter_input(INPUT_POST, 'id_factura', FILTER_SANITIZE_NUMBER_INT);
                $id_divisa          = filter_input(INPUT_POST, 'id_divisa', FILTER_SANITIZE_NUMBER_INT);
                $id_metodo_divisa   = filter_input(INPUT_POST, 'id_metodo_divisa', FILTER_SANITIZE_NUMBER_INT);
                $id_cuenta_metodo   = filter_input(INPUT_POST, 'id_cuenta_metodo', FILTER_SANITIZE_NUMBER_INT);
                $monto              = filter_input(INPUT_POST, 'monto', FILTER_SANITIZE_STRING);
                $generar_credito    = ('true' == $_POST['credito']) ? true : false;
                $cambiar_estatus    = ('true' == $_POST['cambiar_estatus']) ? true : false;
                $factor = filter_input(INPUT_POST, 'factor', FILTER_SANITIZE_STRING);

                if (empty($id_divisa))
                    $this->array_errors[] = 'El campo Divisa el obligatorio.';
                if (empty($id_metodo_divisa))
                    $this->array_errors[] = 'El campo Metodo el obligatorio.';
                if (empty($id_cuenta_metodo))
                    $this->array_errors[] = 'El campo Cuenta el obligatorio.';
                if (empty($monto))
                    $this->array_errors[] = 'El campo Monto el obligatorio.';

                if (!empty($id_factura) && empty($this->array_errors)) {

                    $factura    = $this->notas_entrega_model->obtenerFactura($id_factura);

                    if ($factura && !$this->facturaFinalizada($factura['n_id'])) {
                        $result = $this->carritoVentas->pagar('app_orden_de_entrega', $monto, $id_divisa, $id_factura, $generar_credito, $id_cuenta_metodo, $id_metodo_divisa,false,[],'',$cambiar_estatus,$factor);
                        if (isset($result['errors'])) {
                            return Http::json_response(['errors' => $result['errors']]);
                        } else {
                            return Http::json_response($result);
                        }
                    }
                }

                Http::json_response(['errors' => $this->array_errors]);
            }
        }
    }

    public function eliminarPago()
    {
        if ($_SERVER['REQUEST_METHOD'] == 'POST' && isAjax()) {

            if ($this->module->has_module_action_permission('facturacion', 'eliminar_pagos', $_SESSION['user_data']['emp_id'])) {

                $id         = filter_input(INPUT_POST, 'id', FILTER_SANITIZE_NUMBER_INT);
                $id_factura = filter_input(INPUT_POST, 'id_factura', FILTER_SANITIZE_NUMBER_INT);

                if (!empty($id) && !empty($id_factura)) {

                    $d_ = $this->carritoVentas->obtenerDocumento(12);

                    $factura = $this->notas_entrega_model->obtenerFactura($id_factura);

                    if ($factura['n_estatus'] == 1) {
                        $this->array_errors[] = 'Lo siento no se puede eliminar el pago ya que la factura a sido cancelada en su totalidad';
                    } else {

                        $movimiento_model = new MovimientoModel();

                        $movimiento = $movimiento_model->abtenerMovimiento($id);

                        if ($movimiento && $factura['n_id'] == $movimiento['fab_idgenerico']) {

                            if ($movimiento_model->abtenerMovimientoNegativo($id)) {
                                $this->array_errors[] = 'EL pago no se puede eliminar ya que se encuentra en reverso';
                            } else {

                                $cuenta = $this->notas_entrega_model->consultar("SELECT cmp_cueid, cmp_saldo FROM app_cuentas_metodopago WHERE cmp_id = {$movimiento['fab_cmpid']}")->row();
                                $total_saldo_cuenta = $this->notas_entrega_model->consultar("SELECT bc_saldo FROM app_bancos_cuentas WHERE bc_id = {$cuenta['cmp_cueid']}")->row();
                                $divisa_fac_mov = $this->carritoVentas->obtenerDivisa($movimiento['fab_divisa']);
                                $cliente = $this->carritoVentas->obtenerCliente($factura['n_cliid']);

                                $movimiento_model->editar($movimiento['fab_id'], [
                                    'fab_retiro' => 1,
                                ]);

                                if ($movimiento_model->guardar([
                                    'fab_idgenerico'        => $movimiento['fab_idgenerico'],
                                    'fab_doc'               => 12,
                                    'fab_divisa'            => $movimiento['fab_divisa'],
                                    'fab_metodo'            => $movimiento['fab_metodo'],
                                    'fab_cmpid'             => $movimiento['fab_cmpid'],
                                    'fab_monto'             => $movimiento['fab_monto'] * -1,
                                    'fab_factor'            => $movimiento['fab_factor'],
                                    'fab_conversion'        => $movimiento['fab_conversion'] * -1,
                                    'fab_divid_conversion'  => $movimiento['fab_divid_conversion'],
                                    'fab_factor_master'     => $movimiento['fab_factor_master'],
                                    'fab_idretiro'          => $movimiento['fab_id'],
                                    'fab_retiro'            => 1,
                                    'fab_empid'             => $movimiento['fab_empid'],
                                    'fab_modulo'            => $movimiento['fab_modulo'],
                                    'fab_descripcion'       => '',
                                    'fab_observacion'       => "Devolución {$d_['doc_prefijo']} # {$factura['n_correlativo']} {$cliente['cli_razon_social']} Monto: " . Moneda::moneda($movimiento['fab_monto'], $divisa_fac_mov['div_locale'], $divisa_fac_mov['div_simbolo']),
                                    'fab_categoria'         => 1,
                                    'fab_saldo_anterior'    => $total_saldo_cuenta['bc_saldo']
                                ])) {

                                    $this->notas_entrega_model->pagoPositivo($cuenta['cmp_cueid'], ($total_saldo_cuenta['bc_saldo'] - $movimiento['fab_monto']));
                                    $tcm = $cuenta['cmp_saldo'] - $movimiento['fab_monto'];
                                    $this->notas_entrega_model->consultar("UPDATE app_cuentas_metodopago SET cmp_saldo = $tcm WHERE cmp_id = {$movimiento['fab_cmpid']}")->run();

                                    $total_pagos = $movimiento_model->totalPagos($factura['n_id'], 12,1);

                                    $array_abonos = [];
                                    $abonos = $this->notas_entrega_model->abonos($factura['n_id']);

                                    if (is_countable($abonos) && count($abonos)) {
                                        foreach ($abonos as $row) {
                                            $divisa_mov = $this->carritoVentas->obtenerDivisa($row['fab_divisa']);
                                            $divisa_conv_mov = $this->carritoVentas->obtenerDivisa($row['fab_divid_conversion']);
                                            $array_abonos[] = [
                                                'fab_id'            => $row['fab_id'],
                                                'fab_fecha'         => $row['fecha'],
                                                'bc_alias'          => $row['bc_alias'],
                                                'bc_tipo'           => $row['bc_tipo'],
                                                'fab_retiro'        => $row['fab_retiro'],
                                                'mp_nombre'         => $row['mp_nombre'],
                                                'fab_monto'         => Moneda::moneda($row['fab_monto'], $divisa_mov['div_locale'], $divisa_mov['div_simbolo']),
                                                'fab_factor'        => Moneda::decimal($row['fab_factor'], $this->divisa_master['div_locale']),
                                                'fab_conversion'    => Moneda::moneda($row['fab_conversion'], $divisa_conv_mov['div_locale'], $divisa_conv_mov['div_simbolo'])
                                            ];
                                        }
                                    }

                                    Http::json_response([
                                        'abonos'        => $array_abonos,
                                        'total_factura' => round($factura['n_total'], 2),
                                        'restante'      => round(($factura['n_total'] - $total_pagos['total']), 2),
                                        'total_pagado'  => round($total_pagos['total'], 2)
                                    ]);
                                }
                            }
                        }
                    }
                }
            } else {
                $this->array_errors[] = 'Acceso prohibido no posee permisos para eliminar los pagos.';
            }

            Http::json_response(['errors' => $this->array_errors]);
        }
    }

    public function eniviarFactura()
    {
        if ('POST' === $_SERVER['REQUEST_METHOD'] && isAjax()) {

            $id     = filter_input(INPUT_POST, 'id_factura', FILTER_SANITIZE_NUMBER_INT);
            $de     = filter_input(INPUT_POST, 'de', FILTER_SANITIZE_EMAIL);
            $para   = filter_input(INPUT_POST, 'para', FILTER_SANITIZE_EMAIL);
            $copia  = filter_input(INPUT_POST, 'copia', FILTER_SANITIZE_EMAIL);
            $firma  = filter_input(INPUT_POST, 'firma', FILTER_SANITIZE_EMAIL);
            $tipo   = filter_input(INPUT_POST, 'tipo', FILTER_SANITIZE_NUMBER_INT) ?? 1;

            $d_ = $this->carritoVentas->obtenerDocumento(12);

            if (empty($de))
                $this->array_errors[] = 'El campo De es obligatorio.';
            if (empty($para))
                $this->array_errors[] = 'El campo Para es obligatorio.';

            if (empty($this->array_errors)) {

                $newVentasHistoricoEmail = new VentasHistoricoEmail();
                $data_factura = $this->notas_entrega_model->obtener($id);

                if (!empty($id)) {

                    switch ($tipo) {
                        case 1:
                            $pdf_nombre = 'Factura completa';
                            $mpdf = $this->pdfCompleto($id);
                            break;
                        case 2:
                            $pdf_nombre = 'Factura media pagina';
                            $mpdf = $this->pdfMediaPagina($id);
                            break;
                        case 3:
                            $pdf_nombre = 'Factura mas pagos';
                            $mpdf = $this->pdfPagos($id);
                            break;
                    }

                    $content = $mpdf['mpdf']->Output('', 'S');

                    $mail = new PHPMailer(true);

                    try {

                        $mail->isSMTP();
                        $mail->Host       = "{$mpdf['empresa']['emp_host_correo']}";
                        $mail->SMTPAuth   = true;
                        $mail->Username   = "{$mpdf['empresa']['emp_email']}";
                        $mail->Password   = "{$mpdf['empresa']['emp_email_password']}";
                        $mail->SMTPSecure = PHPMailer::ENCRYPTION_STARTTLS;
                        $mail->Port       = $mpdf['empresa']['emp_port_correo'];

                        $mail->setFrom($de);
                        $mail->addAddress($para);
                        $mail->addReplyTo($de, 'Empresa');

                        if (!empty($copia)) {
                            $mail->addAddress($copia);
                        }

                        $mail->addStringAttachment($content, "{$mpdf['mascara']}");

                        $mail->isHTML(true);
                        $mail->Subject = 'NOTA DE ENTREGA';
                        $mail->Body    = "{$mpdf['mascara']}";

                        $mail->send();

                        $newVentasHistoricoEmail->guardar([
                            'venhisemail_idfac' => $id,
                            'venhisemail_cliid' => $data_factura['n_cliid'],
                            'venhisemail_descripcion' => "Envio de factura de: $de para: $para tipo: $pdf_nombre",
                            'venhisemail_modulo' => $d_['doc_prefijo'],
                            'venhisemail_empid' => $_SESSION['user_data']['einfo_id']
                        ]);

                        Http::json_response("Envio de factura exitosa");
                    } catch (Exception $e) {
                        $this->array_errors[] = "Message could not be sent. Mailer Error: {$mail->ErrorInfo}.";
                    }
                }
            }

            Http::json_response(['errors' => $this->array_errors]);
        }
    }

    private function pdfCompleto($id_factura)
    {
        $factura_data       = $this->notas_entrega_model->obtenerFacturaCompleta($id_factura);
        $articulos_model    = new OrdendeentregaArticulos();
        $articulos_data     = $articulos_model->articulos($factura_data['n_id']);
        $cliente_data       = $this->carritoVentas->obtenerCliente($factura_data['n_cliid']);
        $empresa_data       = $this->carritoVentas->obtenerDatosEmpresa();
        $documento_data     = $this->carritoVentas->obtenerDocumento(12);

        $mascara = mascara_correlativo($documento_data['doc_prefijo'], $factura_data['ser_impuesto'], $factura_data['n_correlativo']);

        $defaultConfig = (new \Mpdf\Config\ConfigVariables())->getDefaults();
        $fontDirs = $defaultConfig['fontDir'];
        $defaultFontConfig = (new \Mpdf\Config\FontVariables())->getDefaults();
        $fontData = $defaultFontConfig['fontdata'];

        $mpdf = new \Mpdf\Mpdf([
            'mode'              => 'utf-8',
            'margin_left'       => 15,
            'margin_right'      => 15,
            'margin_top'        => 35,
            'margin_bottom'     => 30,
            'margin_header'     => 15,
            'margin_footer'     => 30,
            'format'            => 'A4',
            'orientation'       => 'P',
            'default_font_size' => 8,
            'default_font'      => 'helvetica'
        ]);

        $mpdf->SetTitle($mascara);
        $mpdf->SetAuthor($empresa_data['emp_nombre']);
        $mpdf->SetCreator($empresa_data['emp_nombre']);
        $mpdf->SetSubject($mascara);

        $html_header = Vista::viewPDF('pdffacturas/ordendeentrega/header', [
            'emp_nombre'    => $empresa_data['emp_nombre'] ?? '',
            'emp_rif'       => $empresa_data['emp_rif'] ?? '',
            'emp_direccion' => $empresa_data['emp_direccion'] ?? '',
            'emp_direccion' => $empresa_data['emp_direccion'] ?? '',
            'emp_codpostal' => $empresa_data['emp_codpostal'] ?? '',
            'emp_estado'    => $empresa_data['emp_estado'] ?? '',
            'emp_ciudad'    => $empresa_data['emp_ciudad'] ?? ''
        ]);

        $mpdf->SetHTMLHeader($html_header);

        $html_body = Vista::viewPDF('pdffacturas/ordendeentrega/body_completo', [
            'documento'     => $documento_data['doc_descripcion'],
            'factura'       => $mascara,
            'cliente'       => $cliente_data['cli_razon_social'],
            'direccion'     => $cliente_data['cli_direccion'],
            'fecha'         => date('Y-m-d', strtotime($factura_data['n_fecha'])),
            'cedularif'     => $cliente_data['cli_dni'],
            'telefono'      => $cliente_data['cli_telefono'],
            'div_locale'    => $factura_data['div_locale'],
            'div_simbolo'  => $factura_data['div_simbolo'],
            'articulos'     => $articulos_data,
            'observaciones' => $factura_data['n_observaciones']
        ]);

        $mpdf->WriteHTML($html_body);

        $html_footer = Vista::viewPDF('pdffacturas/ordendeentrega/footer', [
            'div_locale'    => $factura_data['div_locale'],
            'div_simbolo'  => $factura_data['div_simbolo'],
            'total'         => $factura_data['n_total'],
            'iva'           => $factura_data['n_iva'],
            'neto'          => $factura_data['n_neto'],
            'descuento'     => $factura_data['n_descuento']
        ]);

        $mpdf->SetHTMLFooter($html_footer);

        return [
            'mpdf'      => $mpdf,
            'mascara'   => $mascara . '.pdf',
            'empresa'   => $empresa_data,
        ];
    }

    private function pdfMediaPagina($id_factura)
    {
        $factura_data = $this->notas_entrega_model->obtenerFacturaCompleta($id_factura);

        $articulos_model    = new OrdendeentregaArticulos();
        $articulos_data     = $articulos_model->articulos($factura_data['n_id']);
        $cliente_data       = $this->carritoVentas->obtenerCliente($factura_data['n_cliid']);
        $empresa_data       = $this->carritoVentas->obtenerDatosEmpresa();
        $documento_data     = $this->carritoVentas->obtenerDocumento(12);

        $mascara = mascara_correlativo($documento_data['doc_prefijo'], $factura_data['ser_impuesto'], $factura_data['n_correlativo']);

        $mpdf = new \Mpdf\Mpdf([
            'mode'              => 'utf-8',
            'margin_left'       => 15,
            'margin_right'      => 15,
            'margin_top'        => 35,
            'margin_bottom'     => 30,
            'margin_header'     => 15,
            'margin_footer'     => 30,
            'format'            => [210, 148.5],
            'orientation'       => 'P',
            'default_font_size' => 8,
            'default_font'      => 'helvetica'
        ]);

        $mpdf->SetTitle($mascara);
        $mpdf->SetAuthor($empresa_data['emp_nombre']);
        $mpdf->SetCreator($empresa_data['emp_nombre']);
        $mpdf->SetSubject($mascara);

        $html_header = Vista::viewPDF('pdffacturas/ordendeentrega/header', [
            'emp_nombre'    => $empresa_data['emp_nombre'] ?? '',
            'emp_rif'       => $empresa_data['emp_rif'] ?? '',
            'emp_direccion' => $empresa_data['emp_direccion'] ?? '',
            'emp_direccion' => $empresa_data['emp_direccion'] ?? '',
            'emp_codpostal' => $empresa_data['emp_codpostal'] ?? '',
            'emp_estado'    => $empresa_data['emp_estado'] ?? '',
            'emp_ciudad'    => $empresa_data['emp_ciudad'] ?? '',
        ]);

        $mpdf->SetHTMLHeader($html_header);

        $html_body = Vista::viewPDF('pdffacturas/ordendeentrega/body_completo', [
            'documento'     => $documento_data['doc_descripcion'],
            'factura'       => $mascara,
            'cliente'       => $cliente_data['cli_razon_social'],
            'direccion'     => $cliente_data['cli_direccion'],
            'fecha'         => date('Y-m-d', strtotime($factura_data['n_fecha'])),
            'cedularif'     => $cliente_data['cli_dni'],
            'telefono'      => $cliente_data['cli_telefono'],
            'div_locale'    => $factura_data['div_locale'],
            'div_simbolo'  => $factura_data['div_simbolo'],
            'articulos'     => $articulos_data,
            'observaciones' => $factura_data['n_observaciones']
        ]);

        $mpdf->WriteHTML($html_body);

        $html_footer = Vista::viewPDF('pdffacturas/ordendeentrega/footer', [
            'div_locale'    => $factura_data['div_locale'],
            'div_simbolo'  => $factura_data['div_simbolo'],
            'total'         => $factura_data['n_total'],
            'iva'           => $factura_data['n_iva'],
            'neto'          => $factura_data['n_neto'],
            'descuento'     => $factura_data['n_descuento']
        ]);

        $mpdf->SetHTMLFooter($html_footer);

        return [
            'mpdf'      => $mpdf,
            'mascara'   => $mascara . '.pdf',
            'empresa'   => $empresa_data,
        ];
    }

    public function pdfPagos($id_factura)
    {
        $factura_data = $this->notas_entrega_model->obtenerFacturaCompleta($id_factura);

        $articulos_model    = new OrdendeentregaArticulos();
        $articulos_data     = $articulos_model->articulos($factura_data['n_id']);
        $cliente_data       = $this->carritoVentas->obtenerCliente($factura_data['n_cliid']);
        $empresa_data       = $this->carritoVentas->obtenerDatosEmpresa();
        $documento_data     = $this->carritoVentas->obtenerDocumento(12);

        $mascara = mascara_correlativo($documento_data['doc_prefijo'], $factura_data['ser_impuesto'], $factura_data['n_correlativo']);

        $mpdf = new \Mpdf\Mpdf([
            'mode'              => 'utf-8',
            'margin_left'       => 15,
            'margin_right'      => 15,
            'margin_top'        => 35,
            'margin_bottom'     => 30,
            'margin_header'     => 15,
            'margin_footer'     => 20,
            'format'            => [210, 148.5],
            'orientation'       => 'P',
            'default_font_size' => 8,
            'default_font'      => 'helvetica'
        ]);

        $mpdf->SetTitle($mascara);
        $mpdf->SetAuthor($empresa_data['emp_nombre']);
        $mpdf->SetCreator($empresa_data['emp_nombre']);
        $mpdf->SetSubject($mascara);

        $html_header = Vista::viewPDF('pdffacturas/ordendeentrega/header', [
            'emp_nombre'    => $empresa_data['emp_nombre'] ?? '',
            'emp_rif'       => $empresa_data['emp_rif'] ?? '',
            'emp_direccion' => $empresa_data['emp_direccion'] ?? '',
            'emp_direccion' => $empresa_data['emp_direccion'] ?? '',
            'emp_codpostal' => $empresa_data['emp_codpostal'] ?? '',
            'emp_estado'    => $empresa_data['emp_estado'] ?? '',
            'emp_ciudad'    => $empresa_data['emp_ciudad'] ?? '',
        ]);

        $mpdf->SetHTMLHeader($html_header);

        $html_body = Vista::viewPDF('pdffacturas/ordendeentrega/body_completo', [
            'documento'     => $documento_data['doc_descripcion'],
            'factura'       => $mascara,
            'cliente'       => $cliente_data['cli_razon_social'],
            'direccion'     => $cliente_data['cli_direccion'],
            'fecha'         => date('Y-m-d', strtotime($factura_data['n_fecha'])),
            'cedularif'     => $cliente_data['cli_dni'],
            'telefono'      => $cliente_data['cli_telefono'],
            'div_locale'    => $factura_data['div_locale'],
            'div_simbolo'  => $factura_data['div_simbolo'],
            'articulos'     => $articulos_data,
            'observaciones' => $factura_data['n_observaciones']
        ]);

        $mpdf->WriteHTML($html_body);

        $html_footer = Vista::viewPDF('pdffacturas/ordendeentrega/footer', [
            'div_locale'    => $factura_data['div_locale'],
            'div_simbolo'  => $factura_data['div_simbolo'],
            'total'         => $factura_data['n_total'],
            'iva'           => $factura_data['n_iva'],
            'neto'          => $factura_data['n_neto'],
            'descuento'     => $factura_data['n_descuento']
        ]);

        $mpdf->SetHTMLFooter($html_footer);

        $mpdf->AddPage();

        $array_abonos = [];
        $total_abonos = 0;
        $abonos = $this->notas_entrega_model->abonos($id_factura);

        if (is_countable($abonos) && count($abonos)) {
            foreach ($abonos as $row) {
                $divisa_mov = $this->carritoVentas->obtenerDivisa($row['fab_divisa']);
                $divisa_conv_mov = $this->carritoVentas->obtenerDivisa($row['fab_divid_conversion']);
                $array_abonos[] = [
                    'fab_id'            => $row['fab_id'],
                    'fab_fecha'         => $row['fecha'],
                    'bc_alias'          => $row['bc_alias'],
                    'bc_tipo'           => $row['bc_tipo'],
                    'fab_retiro'        => $row['fab_retiro'],
                    'mp_nombre'         => $row['mp_nombre'],
                    'fab_monto'         => Moneda::moneda($row['fab_monto'], $divisa_mov['div_locale'], $divisa_mov['div_simbolo']),
                    'fab_factor'        => Moneda::decimal($row['fab_factor'], $this->divisa_master['div_locale']),
                    'fab_conversion'    => Moneda::moneda($row['fab_conversion'], $divisa_conv_mov['div_locale'], $divisa_conv_mov['div_simbolo'])
                ];

                $total_abonos += $row['fab_conversion'];
            }
        }

        $pendiente = abs($factura_data['n_total'] - $total_abonos);

        if (is_countable($abonos) && count($abonos)) {
            $html_abonos = Vista::viewPDF('pdffacturas/ordendeentrega/abonos', [
                'total' => Moneda::moneda($factura_data['n_total'], $divisa_conv_mov['div_locale'], $divisa_conv_mov['div_simbolo']),
                'pendiente' => Moneda::moneda($pendiente, $divisa_conv_mov['div_locale'], $divisa_conv_mov['div_simbolo']),
                'abonos' => $array_abonos,
                'abonado' => Moneda::moneda($total_abonos, $divisa_conv_mov['div_locale'], $divisa_conv_mov['div_simbolo'])
            ]);
        } else {
            $html_abonos = Vista::viewPDF('pdffacturas/ordendeentrega/abonos', [
                'total' => Moneda::moneda($factura_data['n_total'], $factura_data['div_locale'], $factura_data['div_simbolo']),
                'pendiente' => Moneda::moneda($factura_data['n_total'], $factura_data['div_locale'], $factura_data['div_simbolo']),
                'abonos' => $array_abonos,
                'abonado' => 0
            ]);
        }

        $mpdf->WriteHTML($html_abonos);

        $footer = Vista::viewPDF('pdffacturas/ordendeentrega/footerFMP');

        $mpdf->SetHTMLFooter($footer);

        return [
            'mpdf'      => $mpdf,
            'mascara'   => $mascara . '.pdf',
            'empresa'   => $empresa_data,
        ];
    }

    public function pdf($id)
    {
        if ('GET' === $_SERVER['REQUEST_METHOD']) {

            $id = filter_var($id, FILTER_SANITIZE_NUMBER_INT);

            $factura_data = $this->notas_entrega_model->obtenerFacturaCompleta($id);

            if (!$factura_data) {
                Http::notFound();
            }

            $mpdf = $this->pdfCompleto($id);

            $mpdf['mpdf']->Output("{$mpdf['mascara']}", \Mpdf\Output\Destination::INLINE);
            exit;
        }
    }

    public function pdfMP($id)
    {
        if ('GET' === $_SERVER['REQUEST_METHOD']) {

            $id = filter_var($id, FILTER_SANITIZE_NUMBER_INT);

            $factura_data = $this->notas_entrega_model->obtenerFacturaCompleta($id);

            if (!$factura_data) {
                Http::notFound();
            }

            $mpdf = $this->pdfMediaPagina($id);

            $mpdf['mpdf']->Output("{$mpdf['mascara']}", \Mpdf\Output\Destination::INLINE);
            exit;
        }
    }

    public function pdfFMP($id)
    {
        if ('GET' === $_SERVER['REQUEST_METHOD']) {

            $id = filter_var($id, FILTER_SANITIZE_NUMBER_INT);

            $factura_data = $this->notas_entrega_model->obtenerFacturaCompleta($id);

            if (!$factura_data) {
                Http::notFound();
            }

            $mpdf = $this->pdfPagos($id);

            $mpdf['mpdf']->Output("{$mpdf['mascara']}", \Mpdf\Output\Destination::INLINE);
            exit;
        }
    }

    public function obtnerDocumentos(int $id_factura)
    {
        if ('GET' === $_SERVER['REQUEST_METHOD'] && isAjax()) {
            $facturadocumentos_model = new OrdendeentregaDocumentos();
            $id_factura = filter_var($id_factura, FILTER_SANITIZE_NUMBER_INT);
            Http::json_response($facturadocumentos_model->obtenerDocumentos($id_factura));
        }
    }


    public function anularFactura()
    {
        if ($_SERVER['REQUEST_METHOD'] == 'GET' && isAjax()) {

            if ($this->module->has_module_action_permission('facturacion', 'anular_doc', $_SESSION['user_data']['emp_id'])) {

                $id_factura     = filter_input(INPUT_GET, 'id_factura', FILTER_SANITIZE_NUMBER_INT);
                $descripcion    = filter_input(INPUT_GET, 'descripcion', FILTER_SANITIZE_STRING);

                $factura = $this->notas_entrega_model->obtenerFactura($id_factura);
                $d_ = $this->carritoVentas->obtenerDocumento(12);

                if (!$factura) {
                    $this->array_errors[] = 'ACCESO DENEGADO';
                    return Http::json_response(['errors' => $this->array_errors]);
                } else {
                    if ($factura['n_estatus'] == 3) {
                        $this->array_errors[] = 'La orden ya se encuentra anulada.';
                    }
                }

                if (empty($this->array_errors)) {

                    $correlativo = $this->carritoVentas->chuequearCorrelativo($factura['n_serid'], 7);
                    $serie = $this->carritoVentas->obtenerSerie($factura['n_serid']);

                    if ($correlativo == false) {
                        $this->array_errors[] = "No existe correlativo entre la se serie $serie[ser_descripcion] y el documento orden de entrega por favor dirijase a Modulo Configuración -> correlativos";
                    }

                    if (empty($this->array_errors)) {

                        $new_articulos  = new OrdendeentregaArticulos();
                        $new_movimiento = new MovimientoModel();
                        $new_credito = new Notadecredito();
                        $articulos = $new_articulos->articulos($factura['n_id']);
                        $movimientos = $new_movimiento->obtenerMovimientosDocumento($factura['n_id'], 12);
                        $total_pagos = 0;

                        if ($this->notas_entrega_model->editar($factura['n_id'], [
                            'n_estatus' => 3,
                            'n_observaciones' => $factura['n_observaciones'] . ' (ANULADO ' . $descripcion . ')'
                        ])) {

                            foreach ($articulos as $row) {
                                $almacen  = $this->carritoVentas->obtenerAlmacen($row['nart_almid']);
                                $cantidad_stock = $this->carritoVentas->chuequearStock($row['nart_proid'], $row['nart_almid']);
                                if ($row['nart_descontar_inventario'] > 0 && $this->notas_entrega_model->restablecerStock($row['nart_proid'], $row['nart_almid'], $row['nart_descontar_inventario'])) {
                                    $new_articulos->editar($row['nart_id'], ['nart_descontar_inventario' => 0]);
                                    Notifica::stock($row['nart_proid'], "{$almacen['alm_nombre']}", 'ventas', $cantidad_stock['ps_cantidad'] ?? 0, $row['nart_descontar_inventario'], 0, ($cantidad_stock['ps_cantidad'] ?? 0) + $row['nart_descontar_inventario'], $factura['n_correlativo'], 12);
                                }
                            }

                            if (is_countable($movimientos) && count($movimientos)) {

                                foreach ($movimientos as $row) {
                                    if ($row['fab_divisa'] == $this->divisa_master['div_id']) {
                                        $total_pagos += $row['fab_monto'];
                                    } else {
                                        $total_pagos += $row['fab_monto'] / $row['fab_factor_master'];
                                    }
                                }

                                if ($new_credito->guardar([
                                    'cre_cliid'         => $factura['n_cliid'],
                                    'cre_facid'         => $factura['n_id'],
                                    'cre_docid'         => 12,
                                    'cre_empleado'      => $_SESSION['user_data']['emp_id'],
                                    'cre_modulo'        => $d_['doc_prefijo'],
                                    'cre_descripcion'   => $descripcion,
                                    'cre_correlativo'   => $correlativo['cor_correlativo'] + 1,
                                    'cre_monto'         => $total_pagos
                                ], true)) {
                                    $this->carritoVentas->actualizarCorrelativo($serie['ser_id'], 7, ($correlativo['cor_correlativo'] + 1));
                                }
                            }

                            $new_comisiones = new EmpleadosComisionesEmplAgente();
                            $new_comisiones->eliminarNotaFactId($id_factura, 12);

                            return Http::json_response(ruta_base() . 'ordendeentregaeditar/verFactura/' . $id_factura);
                        } else {
                            Http::json_response(false);
                        }
                    }
                }
            } else {
                $this->array_errors[] = 'Acceso prohibido no posee permisos para anular el documento.';
            }

            Http::json_response(['errors' => $this->array_errors]);
        }
    }

    public function imprimirPuntoTicket()
    {
        if ('GET' === $_SERVER['REQUEST_METHOD'] && isAjax()) {

            if (!empty($_GET['id_factura']) && !empty($_GET['impresora'])) {

                $id_factura     = $this->solicitud->sanitize($_GET['id_factura'], FILTER_VALIDATE_INT);
                $id_impresora   = $this->solicitud->sanitize($_GET['impresora'], FILTER_VALIDATE_INT);

                if ($id_factura && $id_impresora) {
                    if ($this->notas_entrega_model->existe('n_id', $id_factura)) {
                        Http::json_response($this->carritoVentas->imprimirPuntoTicket('app_orden_de_entrega', $id_factura, $id_impresora));
                    } else {
                        $this->array_errors[] = 'Acción prohibida';
                    }
                } else {
                    $this->array_errors[] = 'Acción prohibida';
                }
            }

            Http::json_response(['errors' => $this->array_errors]);
        }
    }

    public function imprimir()
    {
        if ('GET' === $_SERVER['REQUEST_METHOD'] && isAjax()) {

            if (!empty($_GET['id_factura']) && !empty($_GET['impresora'])) {

                $id_factura     = $this->solicitud->sanitize($_GET['id_factura'], FILTER_VALIDATE_INT);
                $id_impresora   = $this->solicitud->sanitize($_GET['impresora'], FILTER_VALIDATE_INT);

                if ($id_factura && $id_impresora) {
                    if ($this->notas_entrega_model->existe('n_id', $id_factura)) {
                        Http::json_response($this->carritoVentas->imprimir('app_orden_de_entrega', $id_factura, $id_impresora));
                    } else {
                        $this->array_errors[] = 'Acción prohibida';
                    }
                } else {
                    $this->array_errors[] = 'Acción prohibida';
                }
            }

            Http::json_response(['errors' => $this->array_errors]);
        }
    }

    public function imprimirTicketCredito()
    {
        if ('GET' === $_SERVER['REQUEST_METHOD'] && isAjax()) {
            if (!empty($_GET['id_factura']) && !empty($_GET['id_impresora'])) {
                $id_factura     = $this->solicitud->sanitize($_GET['id_factura'], FILTER_VALIDATE_INT);
                $id_impresora   = $this->solicitud->sanitize($_GET['id_impresora'], FILTER_VALIDATE_INT);

                if ($id_factura && $id_impresora) {
                    if ($this->notas_entrega_model->existe('n_id', $id_factura)) {
                        Http::json_response($this->carritoVentas->imprimirTicketCredito('app_orden_de_entrega', $id_factura, $id_impresora));
                    } else {
                        $this->array_errors[] = 'Acción prohibida';
                    }
                } else {
                    $this->array_errors[] = 'Acción prohibida';
                }
            }

            Http::json_response(['errors' => $this->array_errors]);
        }
    }

    public function imprimirTicketIndividual()
    {
        if ('GET' === $_SERVER['REQUEST_METHOD'] && isAjax()) {
            if (!empty($_GET['id_factura']) && !empty($_GET['id_impresora'])) {
                $id_factura     = $this->solicitud->sanitize($_GET['id_factura'], FILTER_VALIDATE_INT);
                $id_impresora   = $this->solicitud->sanitize($_GET['id_impresora'], FILTER_VALIDATE_INT);
                $id_movimiento   = $this->solicitud->sanitize($_GET['id_movimiento'], FILTER_VALIDATE_INT);
                if ($id_factura && $id_impresora) {
                    if ($this->notas_entrega_model->existe('n_id', $id_factura)) {
                        Http::json_response($this->carritoVentas->imprimirTicketIndividual('app_orden_de_entrega', $id_factura, $id_impresora, $id_movimiento));
                    } else {
                        $this->array_errors[] = 'Acción prohibida';
                    }
                } else {
                    $this->array_errors[] = 'Acción prohibida';
                }
            }

            Http::json_response(['errors' => $this->array_errors]);
        }
    }

    public function obtenerCreditos(int $id_cliente)
    {
        if ('GET' == $_SERVER['REQUEST_METHOD'] && isAjax()) {

            $id_cliente = $this->solicitud->sanitize($id_cliente, FILTER_SANITIZE_NUMBER_INT);

            $newNotaDeCredito = new Notadecredito();
            $newNotadeCreditoDetalles = new NotadeCreditoDetalles();

            $lista_creditos = [];

            $creditos = $newNotaDeCredito->obtenerCreditosClientes($id_cliente);

            if (is_countable($creditos) && count($creditos)) {
                foreach ($creditos as $row) {
                    $total_credito = $newNotadeCreditoDetalles->obtenerTotalPagosCreditos($row['cre_id']);
                    $lista_creditos[] = [
                        'id' => $row['cre_id'],
                        'monto' => $row['cre_monto'] - ($total_credito['total']) ?? 0
                    ];
                }
            }

            Http::json_response($lista_creditos);
        }
    }

    public function pagarConCredito()
    {
        if ('GET' == $_SERVER['REQUEST_METHOD'] && isAjax() && (!empty($_GET['id_fac']) && !empty($_GET['id_credito']))) {
            $newCreditoaPagos = new Notadecredito();
            $newNotadeCreditoDetalles = new NotadeCreditoDetalles();
            $movimiento_model = new MovimientoModel();
            $id_factura = $this->solicitud->sanitize($_GET['id_fac'], FILTER_SANITIZE_NUMBER_INT);
            $id_credito = $this->solicitud->sanitize($_GET['id_credito'], FILTER_SANITIZE_NUMBER_INT);
            $factura    = $this->notas_entrega_model->obtenerFactura($id_factura);
            $d_ = $this->carritoVentas->obtenerDocumento(12);
            if ($this->facturaFinalizada($factura['n_id'])) {
                Http::json_response('pagado');
            } else {

                $factor_master = 1;
                $factor_factura = 1;

                $data_credito = $newCreditoaPagos->obtener($id_credito);
                $total_credito = $newNotadeCreditoDetalles->obtenerTotalPagosCreditos($data_credito['cre_id']);
                $total_disponible = $data_credito['cre_monto'] - ($total_credito['total']) ?? 0;
                $cliente = $this->carritoVentas->obtenerCliente($factura['n_cliid']);
                $total_pagos = $movimiento_model->totalPagos($id_factura, 12,1);
                $restante = $factura['n_total'] - $total_pagos['total'] ?? 0;

                if ($factura['n_divid'] != $this->divisa_master['div_id']) {
                    $factor = $this->notas_entrega_model->obtenerDivisaAlCambio($factura['n_divid'], $this->divisa_master['div_id']);
                    if (!$factor) {
                        $this->array_errors[] = 'No se encuentra el factor de conversion entre la divisa de la factura y la divisa predeterminada.';
                    } else {
                        $total_disponible = round(($total_disponible / $factor['df_factor']), 2);
                    }
                    $data_factor_factura = $this->notas_entrega_model->obtenerDivisaAlCambio($this->divisa_master['div_id'], $factura['n_divid']);
                    if (!$data_factor_factura) {
                        $this->array_errors[] = 'No se encuentra el factor de conversion entre la divisa predeterminada y la divisa en que se registró la factura.';
                    } else {
                        $factor_factura = $data_factor_factura['df_factor'];
                        $factor_master = $data_factor_factura['df_factor'];
                    }
                }

                if (empty($this->array_errors)) {

                    if ($total_disponible > round($restante, 2)) {
                        $monto = $restante;
                    } else {
                        $monto = $total_disponible;
                    }

                    $conversion = $monto / $factor_factura;

                    $id_movimiento = $movimiento_model->guardar([
                        'fab_idgenerico'        => $factura['n_id'],
                        'fab_doc'               => 12,
                        'fab_divisa'            => 2,
                        'fab_monto'             => $conversion,
                        'fab_factor'            => $factor_factura,
                        'fab_conversion'        => $monto,
                        'fab_divid_conversion'  => 2,
                        'fab_retiro'            => 0,
                        'fab_factor_master'     => $factor_master,
                        'fab_empid'             => $_SESSION['user_data']['emp_id'],
                        'fab_modulo'            => 'orden de entrega',
                        'fab_descripcion'       => '',
                        'fab_observacion'       => "Pago con saldo Credito en {$d_['doc_prefijo']} # {$factura['n_correlativo']} {$cliente['cli_razon_social']} Monto: " . Moneda::moneda($monto, $this->divisa_master['div_locale'], $this->divisa_master['div_simbolo']),
                        'fab_credito'           => 1,
                        'fab_categoria'         => 1
                    ]);

                    if ($id_movimiento) {

                        $newNotadeCreditoDetalles->guardar([
                            'credet_movid' => $id_movimiento,
                            'credet_creid' => $data_credito['cre_id'],
                            'credet_idfac' => $factura['n_id'],
                            'credet_docid' => 12,
                            'credet_monto' => $conversion,
                            'credet_descripcion' => "Pago con nota de credito #{$data_credito['cre_correlativo']} por el monto de $monto",
                            'credet_empid' => $_SESSION['user_data']['einfo_id'],
                            'credet_modulo' => $d_['doc_prefijo']
                        ]);

                        $total_credito = $newNotadeCreditoDetalles->obtenerTotalPagosCreditos($data_credito['cre_id']);

                        if (round($data_credito['cre_monto'], 2) == round($total_credito['total'], 2)) {
                            $newCreditoaPagos->editar($data_credito['cre_id'], [
                                'cre_estatus' => 1
                            ]);
                        }

                        $pagado = false;

                        if ($this->facturaFinalizada($factura['n_id'])) {
                            $this->notas_entrega_model->culminarFactura($id_factura);
                            $pagado = true;
                        }

                        $factura = $this->notas_entrega_model->obtenerFactura($id_factura);

                        $array_abonos = [];

                        $total_pagos = $movimiento_model->totalPagos($factura['n_id'], 12,1);
                        $abonos = $this->notas_entrega_model->abonos($factura['n_id']);

                        if (is_countable($abonos) && count($abonos)) {

                            foreach ($abonos as $row) {

                                if (is_null($row['fab_divisa'])) {
                                    $divisa_mov = $this->divisa_master;
                                } else {
                                    $divisa_mov = $this->carritoVentas->obtenerDivisa($row['fab_divisa']);
                                }

                                if (is_null($row['fab_divid_conversion'])) {
                                    $divisa_conv_mov = $this->divisa_master;
                                } else {
                                    $divisa_conv_mov = $this->carritoVentas->obtenerDivisa($row['fab_divid_conversion']);
                                }

                                if (is_null($row['fab_factor'])) {
                                    $row['fab_factor'] = 1;
                                }

                                $array_abonos[] = [
                                    'fab_id'            => $row['fab_id'],
                                    'fab_fecha'         => $row['fecha'],
                                    'bc_alias'          => $row['bc_alias'],
                                    'bc_tipo'           => $row['bc_tipo'],
                                    'fab_retiro'        => $row['fab_retiro'],
                                    'mp_nombre'         => $row['mp_nombre'],
                                    'fab_monto'         => Moneda::moneda($row['fab_monto'], $divisa_mov['div_locale'], $divisa_mov['div_simbolo']),
                                    'fab_factor'        => Moneda::decimal($row['fab_factor'], $this->divisa_master['div_locale']),
                                    'fab_conversion'    => Moneda::moneda($row['fab_conversion'], $divisa_conv_mov['div_locale'], $divisa_conv_mov['div_simbolo']),
                                    'credito'           => $row['fab_credito']
                                ];
                            }
                        }

                        Http::json_response([
                            'abonos'        => $array_abonos,
                            'total_factura' => round($factura['n_total'], 2),
                            'pagado'        => $pagado,
                            'restante'      => round(($factura['n_total'] - $total_pagos['total']), 2),
                            'total_pagado'  => round($total_pagos['total'])
                        ]);
                    }
                } else {
                    Http::json_response(['errors' => $this->array_errors]);
                }
            }
        }
    }

    public function obtenerFactor()
    {
        if ('GET' === $_SERVER['REQUEST_METHOD'] && isAjax() && (!empty($_GET['id_factura']) && !empty($_GET['id_credito']))) {
            $id_factura = $this->solicitud->sanitize($_GET['id_factura'], FILTER_SANITIZE_NUMBER_INT);
            $id_credito = $this->solicitud->sanitize($_GET['id_credito'], FILTER_SANITIZE_NUMBER_INT);
            if ($this->notas_entrega_model->existe('n_id', $id_factura)) {

                $data_factura = $this->notas_entrega_model->obtener($id_factura);
                $newCreditoa = new Notadecredito();
                $newNotadeCreditoDetalles = new NotadeCreditoDetalles();

                $data_credito = $newCreditoa->obtener($id_credito);
                $total_credito = $newNotadeCreditoDetalles->obtenerTotalPagosCreditos($data_credito['cre_id']);
                $total_disponible = $data_credito['cre_monto'] - ($total_credito['total']) ?? 0;

                if ($data_factura['n_divid'] != $this->divisa_master['div_id']) {
                    $factor = $this->notas_entrega_model->obtenerDivisaAlCambio($data_factura['n_divid'], $this->divisa_master['div_id']);
                    if (!$factor) {
                        $this->array_errors[] = 'No se ecuentra el factor de conversion entre la divisa predeterminada y la divisa en que se registró la factura.';
                    } else {
                        $total_disponible = round(($total_disponible / $factor['df_factor']), 2);
                    }
                }

                if (empty($this->array_errors)) {
                    Http::json_response($total_disponible);
                } else {
                    Http::json_response(0);
                }
            }
        }
    }

    public function obtenerubicacionProductos(int $id_factura)
    {
        if ('GET' === $_SERVER['REQUEST_METHOD'] && isAjax()) {
            $id_factura = filter_var($id_factura, FILTER_SANITIZE_NUMBER_INT);
            Http::json_response($this->carritoVentas->obtenerUbicacionesProducto('oreditar', $id_factura));
        }
    }

    public function guardarCredito()
    {
        if ('POST' == $_SERVER['REQUEST_METHOD'] && isAjax()) {

            if (empty($_POST['id_factura']))
                $this->array_errors[] =  'El campo Factura es obligatorio.';
            if (empty($_POST['monto']))
                $this->array_errors[] =  'El campo Monto es obligatorio.';
            if (empty($_POST['id_divisa']))
                $this->array_errors[] =  'El campo Divisa es obligatorio';
            if (empty($_POST['id_metodo_divisa']))
                $this->array_errors[] =  'El campo Metodo es obligatorio';
            if (empty($_POST['id_cuenta_metodo']))
                $this->array_errors[] =  'El campo Cuenta es obligatorio';
            if (empty($_POST['id_serie']))
                $this->array_errors[] =  'El campo Serie es obligatorio';

            if (empty($this->array_errors)) {

                $id_factura = $_POST['id_factura'];
                $id_cuenta_metodo = $_POST['id_cuenta_metodo'];
                $observacion = $_POST['observacion'];
                $id_serie = $_POST['id_serie'];

                $monto = $this->solicitud->sanitize($_POST['monto'], FILTER_SANITIZE_STRING);

                $result = $this->carritoVentas->guardarCredito('app_orden_de_entrega', $id_factura, $monto, $id_cuenta_metodo, $id_serie, $observacion);

                if (isset($result['errors'])) {
                    return Http::json_response(['errors' => $result['errors']]);
                } else {
                    return Http::json_response($result);
                }
            }

            Http::json_response(['errors' => $this->array_errors]);
        }
    }

    public function actualizarPrecios()
    {
        if ('POST' === $_SERVER['REQUEST_METHOD'] && isAjax()) {

            $id_factura = filter_input(INPUT_POST, 'id_factura', FILTER_SANITIZE_NUMBER_INT);
            $descuento_global = filter_input(INPUT_POST, 'descuento_global', FILTER_SANITIZE_STRING) ?? 0;
            $factura = $this->notas_entrega_model->obtenerFactura($id_factura);

            $result = $this->carritoVentas->actualizarPrecios($id_factura, $factura['n_cliid'], 'oreditar', $descuento_global);

            if (isset($result['errors'])) {
                return Http::json_response(['errors' => $result['errors']]);
            } else {
                return Http::json_response($result);
            }
        }
    }

    public function autorizarTrabajoPlanilla(int $id_factura)
    {
        if ('GET' === $_SERVER['REQUEST_METHOD'] && isAjax()) {

            $id_factura = filter_var($id_factura, FILTER_SANITIZE_NUMBER_INT);

            $newPlanillaOrden = new PlanillaOrdenDeEntrega();

            $data_planilla_orden = $newPlanillaOrden->obtenerOrden($id_factura);

            if ($data_planilla_orden) {
                if ($newPlanillaOrden->obtenerOrden($id_factura)) {
                    Http::json_response($newPlanillaOrden->editar($data_planilla_orden['po_id'], [
                        'po_estatus' => $data_planilla_orden['po_estatus'] == 1 ? 0 : 1,
                    ]));
                }
            } else {
                Http::json_response(['errors' => ['Acción prohibida']]);
            }
        }
    }

    public function obtenerComisionesPendiente(int $id_factura)
    {
        if ('GET' === $_SERVER['REQUEST_METHOD'] && isAjax()) {

            $id_factura = filter_var($id_factura, FILTER_SANITIZE_NUMBER_INT);

            $result = $this->carritoVentas->obtenerComisionesPendiente($id_factura, 12);

            if (isset($result['errors'])) {
                return Http::json_response(['errors' => $result['errors']]);
            } else {
                return Http::json_response($result);
            }
        }
    }

    public function recalcularComisiones(int $id_factura)
    {
        if ('GET' === $_SERVER['REQUEST_METHOD'] && isAjax()) {

            $id_factura = filter_var($id_factura, FILTER_SANITIZE_NUMBER_INT);
            $factura = $this->notas_entrega_model->obtenerFactura($id_factura);

            if ($factura) {

                $result = $this->carritoVentas->recalcularComisiones($id_factura, 12);

                if (isset($result['errors'])) {
                    return Http::json_response(['errors' => $result['errors']]);
                } else {
                    return Http::json_response($result);
                }
            }

            $this->array_errors[] = 'Acción prohibida';
            Http::json_response(['errors' => $this->array_errors]);
        }
    }

    public function editarpendiente()
    {
        if ('POST' === $_SERVER['REQUEST_METHOD'] && isAjax()) {

            $id             = filter_input(INPUT_POST, 'id', FILTER_SANITIZE_NUMBER_INT);
            $porcentaje     = filter_input(INPUT_POST, 'porcentaje', FILTER_SANITIZE_STRING ?? 0);
            $monto          = filter_input(INPUT_POST, 'monto', FILTER_SANITIZE_STRING ?? 0);

            $result = $this->carritoVentas->editarComisionPendiente($id, $porcentaje, $monto);

            if (isset($result['errors'])) {
                return Http::json_response(['errors' => $result['errors']]);
            } else {
                return Http::json_response($result);
            }
        }
    }

    public function obtenerRepuestos(int $id_factura)
    {
        if ('GET' === $_SERVER['REQUEST_METHOD'] && isAjax()) {
            $newArt = new OrdendeentregaArticulos();
            $id_factura = filter_var($id_factura, FILTER_SANITIZE_NUMBER_INT);
            Http::json_response($newArt->repuestos($id_factura));
        }
    }

    public function asignarRepuestoAEmpleadoGlobal()
    {
        if ('POST' === $_SERVER['REQUEST_METHOD'] && isAjax()) {

            $newArt = new OrdendeentregaArticulos();

            if (empty($_POST['id_factura']) && empty($_POST['id_empleado']))
                Http::json_response(['errors' => ['Acción prohibida']]);

            $id_factura = filter_input(INPUT_POST, 'id_factura', FILTER_SANITIZE_NUMBER_INT);
            $id_empleado = filter_input(INPUT_POST, 'id_empleado', FILTER_SANITIZE_NUMBER_INT);

            $factura = $this->notas_entrega_model->obtenerFactura($id_factura);

            if (!$factura || $factura['n_estatus'] == 1)
                Http::json_response(['errors' => ['Acción prohibida']]);

            if (!$this->notas_entrega_model->consultar("SELECT * FROM app_empleados_info WHERE einfo_id = $id_empleado")->row())
                Http::json_response(['errors' => ['Acción prohibida']]);

            $articulos =  $newArt->articulos($id_factura);

            try {
                $newArt->transactionBegin();
                foreach ($articulos as $row) {
                    $newArt->editar($row['nart_id'], [
                        'nart_empleado_repuesto' => $id_empleado
                    ]);
                }
                $newArt->transactionCommit();
            } catch (\Throwable $th) {
                $newArt->transactionRollBack();
                $this->array_errors[] = 'Error en transacción';
            }

            if (empty($this->array_errors)) {
                Http::json_response(true);
            }

            Http::json_response(['errors' => $this->array_errors]);
        }
    }

    public function asignarRepuestoAEmpleadoIndividual()
    {
        if ('POST' === $_SERVER['REQUEST_METHOD'] && isAjax()) {

            $newArt = new OrdendeentregaArticulos();

            if (empty($_POST['id_factura']) || empty($_POST['id_empleado']) || empty($_POST['id_producto']))
                Http::json_response(['errors' => ['Acción prohibida']]);

            $id_factura = filter_input(INPUT_POST, 'id_factura', FILTER_SANITIZE_NUMBER_INT);
            $id_empleado = filter_input(INPUT_POST, 'id_empleado', FILTER_SANITIZE_NUMBER_INT);
            $nart_id = filter_input(INPUT_POST, 'id_producto', FILTER_SANITIZE_NUMBER_INT);

            $factura = $this->notas_entrega_model->obtenerFactura($id_factura);

            if (!$factura || $factura['n_estatus'] == 1)
                Http::json_response(['errors' => ['Acción prohibida']]);

            if (!$this->notas_entrega_model->consultar("SELECT * FROM app_empleados_info WHERE einfo_id = $id_empleado")->row())
                Http::json_response(['errors' => ['Acción prohibida']]);

            if (!$newArt->existe('nart_id', $nart_id))
                Http::json_response(['errors' => ['Acción prohibidadd']]);

            try {
                $newArt->transactionBegin();
                $newArt->editar($nart_id, [
                    'nart_empleado_repuesto' => $id_empleado
                ]);
                $newArt->transactionCommit();
            } catch (\Throwable $th) {
                $newArt->transactionRollBack();
                $this->array_errors[] = 'Error al actualizar empleado';
            }

            if (empty($this->array_errors)) {
                Http::json_response(true);
            }

            Http::json_response(['errors' => $this->array_errors]);
        }
    }

    public function obtenerOrden(int $id_orden)
    {
        if ('GET' === $_SERVER['REQUEST_METHOD'] && isAjax()) {

            $id_orden = filter_var($id_orden, FILTER_SANITIZE_NUMBER_INT);

            $lista_part = [];
            $lista_serv = [];
            $serv_categorias = [];
            $newMotor = new Motor();
            $newPreOrden = new PlanillaPreOrden();
            $newPreOrdenPartes = new PlanillaPreOrdenPartes();
            $newPreOrdenServicios = new PlanillaPreOrdenServicios();
            $newPlanillaOrden = new PlanillaOrdenDeEntrega();
            $newCatEmp = new PlanillaCategoriaEmpleado();
            $orden = $newPreOrden->obtenerPreOrden($id_orden);
            $motor = $orden['pre_motid'] ? $newMotor->obtenerMotor($orden['pre_motid']) : null;
            $servicios = $newPreOrdenServicios->obtenerServicios($id_orden);
            $partes = $newPreOrdenPartes->obtenerPartes($id_orden);

            $data_presupuesto = $newPlanillaOrden->where(['po_preid' => $id_orden], true);

            if ($data_presupuesto) {
                $estatus_autorizado = $data_presupuesto['po_estatus'] == 1 ? true : false;
            } else {
                $estatus_autorizado = false;
            }

            if (is_countable($servicios) && count($servicios)) {
                foreach ($servicios as $row) {
                    $empleados = $newPreOrdenServicios->obtenerEmpleadosServicios($row['preserv_id']);
                    $data_serv = [
                        'id' => $row['preserv_id'],
                        'cantidad' => $row['preserv_cantidad'],
                        'servicio' => $row['pro_descripcion'],
                        'estatus' => $row['preserv_estatus'],
                        'categoria' => $row['cat_categorias'],
                        'empleados' => $empleados ?? [],
                        'checked' => false,
                    ];
                    if (!in_array($row['cat_id'], $serv_categorias)) {
                        $serv_categorias[] = $row['cat_id'];
                        $lista_serv[$row['cat_id']] = [
                            'cat_id' => $row['cat_id'],
                            'categoria' => $row['cat_categorias'],
                            'servicios' => [$data_serv]
                        ];
                    } else {
                        $lista_serv[$row['cat_id']]['servicios'][] = $data_serv;
                    }
                }
            }

            if (is_countable($partes) && count($partes)) {
                foreach ($partes as $row) {
                    $lista_part[] = [
                        'id' => $row['prepar_id'],
                        'cantidad' => $row['prepar_cantidad'],
                        'categoria' => $row['cat_categorias'],
                        'ubicacion' => $row['prepar_ubicacion'],
                        'observacion' => $row['prepar_observacion'],
                        'parte' => $row['par_parte']
                    ];
                }
            }
            if (!$newPreOrdenServicios->where(['preserv_preid' => $id_orden])) {
                $servicios_check = 1;
            } else {
                $servicios = $newPreOrden->consultar("SELECT count(preserv_id) as total FROM app_preorden_master_servicios WHERE preserv_preid = $id_orden AND preserv_estatus = 0")->row();
                $servicios_check = $servicios['total'];
            }

            $existe_presupuesto = $newPreOrden->consultar("SELECT * FROM app_planilla_orden_de_entrega WHERE po_preid = $id_orden")->row();
            $deuda = 0;
            $estatus_norden = 0;
            if ($existe_presupuesto) {
                $newCarritoVenta = new CarritoVentasModel();

                $factura = $newCarritoVenta->obtenerOrdenE($existe_presupuesto['po_nid']);

                $estatus_norden = $factura['estatus'];
                $total_pagos = $newCarritoVenta->totalPagos($existe_presupuesto['po_nid'], 12,1);

                $deuda = $factura['total'] - $total_pagos['total'];
            }

            Http::json_response([
                'orden' => $id_orden,
                'estatus' => $orden['pre_estatus'],
                'n_orden' => $orden['pre_correlativo'],
                'observacion_repuestos' => $orden['pre_observacion_repuestos'],
                'fecha' => date('d-m-Y', strtotime($orden['pre_creado'])),
                'taller' => $orden['pre_taller'],
                'ubicacion_culminado' => $orden['pre_ubicacion_final'],
                'motor_id' => ($motor) ? $motor['mot_id'] : '',
                'motor' => ($motor) ? $motor['mot_motor'] . ' - Marca: ' . $motor['m_marca'] . ' - Modelo: ' . $motor['mot_modelo'] : '',
                'cliente' => [
                    'id' => $orden['cli_id'],
                    'dni' => $orden['cli_dni'],
                    'cliente' => $orden['cli_razon_social'],
                    'telefono' => $orden['cli_telefono']
                ],
                'emp_bajo_motor' => $orden['pre_empbajo_motor'],
                'emp_desarmo_motor' => $orden['pre_empdesarmo_motor'],
                'medidas1' => $orden['pre_medidas'],
                'medidas2' => $orden['pre_medidas_d'],
                'medidas3' => $orden['pre_medidas_t'],
                'empleados_todos' => $newCatEmp->obtenerEmpleadosSegunCategoria(7),
                'estatus_autorizado' => $estatus_autorizado,
                'partes' => $lista_part,
                'servicios' => $lista_serv,
                'tot_servicios_asignados' => $servicios_check,
                'restante' => $deuda,
                'n_estatus' => $estatus_norden
            ]);
        }
    }

    public function anularPrecio()
    {
        if ('POST' == $_SERVER['REQUEST_METHOD'] && isAjax()) {

            if (empty($_POST['producto']))
                $this->array_errors[] = 'Debe seleccionar un producto';
            if (empty($_POST['motivo']))
                $this->array_errors[] = 'Cual es el motivo de anular el precio?';

            if (empty($this->array_errors)) {

                $producto = filter_input(INPUT_POST, 'producto', FILTER_VALIDATE_INT);
                $motivo   = filter_input(INPUT_POST, 'motivo', FILTER_SANITIZE_STRING);
                $id_orden = filter_input(INPUT_POST, 'orden', FILTER_VALIDATE_INT);

                $permiso = $this->module->has_module_action_permission('planilla', 'anular_precio', $_SESSION['user_data']['emp_id']);

                if ($permiso) {
                    if ($producto && $motivo) {

                        if ($this->esEditable($id_orden)) {
                            $notas_entrega_articulos_model = new OrdendeentregaArticulos();
                            $articulo = $notas_entrega_articulos_model->consultar("SELECT * FROM app_orden_de_entrega_articulos WHERE nart_nid=$id_orden AND nart_proid=$producto")->row();
                            $neto_art = $articulo['nart_proneto'];
                            $iva_art = $articulo['nart_ivatotal'];
                            $total_art = $articulo['nart_prototal'];

                            $factura = $this->notas_entrega_model->obtenerFactura($id_orden);
                            $neto = $factura['n_neto'];
                            $iva = $factura['n_iva'];
                            $total = $factura['n_total'];
                            $subtotal = $factura['n_subtotal'];
                            $observacion = $factura['n_observaciones'];

                            $notas_entrega_articulos_model->editar($articulo['nart_id'], [
                                'nart_prodescuento'            => 100,
                                'nart_proneto'                 => 0,
                                'nart_ivatotal'                => 0,
                                'nart_prototal'                => 0,
                            ]);

                            $result = $this->notas_entrega_model->editar($id_orden, [
                                'n_subtotal'           => $neto - $neto_art,
                                'n_neto'               => $subtotal - $neto_art,
                                'n_iva'                => $iva - $iva_art,
                                'n_total'              => $total - $total_art,
                                'n_observaciones'      => $observacion . '.  ' . $motivo
                            ]);


                            if ($result) {
                                Http::json_response(ruta_base() . 'ordendeentregaeditar/verFactura/' . $id_orden);
                            } else {
                                $this->array_errors[] = 'Error';
                            }
                        } else {
                            $this->array_errors[] = 'Acci\A8\AEn prohibida';
                        }
                    } else {
                        $this->array_errors[] = 'Acci\A8\AEn prohibida';
                    }
                } else {
                    $this->array_errors[] = 'No tiene el permiso para realizar este ajuste';
                }
            }

            Http::json_response(['errors' => $this->array_errors]);
        }
    }

    public function finalizarOrden()
    {
        if ('GET' === $_SERVER['REQUEST_METHOD'] && isAjax()) {

            if ($this->module->has_module_action_permission('facturacion', 'status', $_SESSION['user_data']['emp_id'])) {

                $id = $this->solicitud->sanitize($_GET['id'], FILTER_SANITIZE_NUMBER_INT);
                $estatus = $this->solicitud->sanitize($_GET['estatus'], FILTER_SANITIZE_NUMBER_INT);

                if ($this->notas_entrega_model->editar($id, [
                    'n_estatus' => $estatus
                ])) {
                    Http::json_response(true);
                } else {
                    Http::json_response(false);
                }
            } else {
                Http::json_response('Usted no posee permisos para cambiar el estatus de los documentos');
            }
        }
    }
}
