<?php

namespace Core\Librerias;

use App\Controladores\TarifasControlador;
use App\Modelos\AlmacenUbicacion;
use App\Modelos\CarritoVentasModel;
use App\Modelos\Cliente;
use App\Modelos\Clientedireccionenvios;
use App\Modelos\Comisiones;
use App\Modelos\EmpleadoAgente;
use App\Modelos\EmpleadosComisionesEmplAgente;
use App\Modelos\PlanillaOrdenDeEntrega;
use App\Modelos\PlanillaPreOrden;
use App\Modelos\ProductosCompuestos;
use App\Modelos\ProductoUbicacion;
use ArrayObject;
use Core\Helpers\Moneda;
use Core\Helpers\Notifica;
use DateTime;
use DateTimeZone;
use Core\Librerias\SMS;

final class CarritoVentasEditar
{
    private $carrito = [];
    private $array_errors = [];
    private $divisa_master;
    private $carritoModel;

    public function __construct()
    {
        $this->carritoModel = new CarritoVentasModel();
        $this->divisa_master = Moneda::Predeterminada();
    }

    public function obtenerDivisasParaFacturar(): array
    {
        $data_divisa = $this->carritoModel->obtenerDivisaEmpleado($_SESSION['user_data']['emp_id']);
        return $data_divisa ?? $this->carritoModel->obtenerDivisas();
    }

    public function totalDocumentosPendientes(int $id_cliente)
    {
        return $this->carritoModel->totalDocumentosPendientes($id_cliente);
    }

    public function obtenerProducto(int $id_producto)
    {
        return $this->carritoModel->obtenerProducto($id_producto);
    }

    public function obtenerDivisa(int $id_divisa)
    {
        return $this->carritoModel->obtenerDivisa($id_divisa);
    }

    public function obtenerSerie(int $id_serie)
    {
        return $this->carritoModel->obtenerSerie($id_serie);
    }

    public function obtenerBalanceComprarDolares($doc, $tipo)
    {
        return $this->carritoModel->obtenerBalanceComprarDolares($doc, $tipo);
    }

    public function obtenerCliente(int $id_cliente)
    {
        return $this->carritoModel->obtenerCliente($id_cliente);
    }

    public function obtenerDatosEmpresa()
    {
        return $this->carritoModel->obtenerDatosEmpresa();
    }

    public function obtenerEmpleados()
    {
        return $this->carritoModel->obtenerEmpleados();
    }

    public function obternerTiposDeDocumentos()
    {
        return $this->carritoModel->obternerTiposDeDocumentos();
    }

    public function obtenerImpuestos()
    {
        return $this->carritoModel->obtenerImpuestos();
    }

    public function obtenerPaises()
    {
        return $this->carritoModel->obtenerPaises();
    }

    public function obtenerDocumento(int $id_documento)
    {
        return $this->carritoModel->obtenerDocumento($id_documento);
    }

    public function obtenerEmpleado(int $id_empleado)
    {
        return $this->carritoModel->obtenerEmpleado($id_empleado);
    }

    public function obtenerAlmacenesEmpleado()
    {
        return $this->carritoModel->obtenerAlmacenesEmpleado();
    }

    public function obtenerSeriesEmpleado()
    {
        return $this->carritoModel->obtenerSeriesEmpleado();
    }

    public function obtenerAgentesdeVenta()
    {
        return $this->carritoModel->obtenerAgentesdeVenta();
    }

    public function obtenerAlmacen(int $id_almacen)
    {
        return $this->carritoModel->obtenerAlmacen($id_almacen);
    }

    public function chuequearStock(int $id_producto, int $id_almacen)
    {
        return $this->carritoModel->chuequearStock($id_producto, $id_almacen);
    }

    public function chuequearCorrelativo(int $id_serie, int $id_documento)
    {
        return $this->carritoModel->chuequearCorrelativo($id_serie, $id_documento);
    }

    public function actualizarCorrelativo(int $id_serie, int $id_documento, int $correlativo)
    {
        return $this->carritoModel->actualizarCorrelativo($id_serie, $id_documento, $correlativo);
    }

    public function obtenerFactura(string $tabla_db, string $_nombre_carrito_, int $id_factura)
    {
        $this->carrito  = null;
        $array_abonos   = [];
        $list_creditos  = [];
        $pago_movil = [];
        $_SESSION["$_nombre_carrito_$id_factura"] = [];

        if ($tabla_db == 'app_factura_master') {
            $factura        = $this->carritoModel->obtenerFac($id_factura);
            $articulos      = $this->carritoModel->obtenerFacArticulos($id_factura);
            $abonos         = $this->carritoModel->abonosFac($id_factura);
            $total_pagos    = $this->carritoModel->totalPagos($id_factura, 2, 1);
            $creditos       = $this->carritoModel->obtenerCreditos($id_factura, 2);
            $total_pagos    = $total_pagos['total'] ? $total_pagos['total'] : 0.00;
            $pago_movil = $this->carritoModel->obtenerBalanceComprarDolares($id_factura, 2);
        } else if ($tabla_db == 'app_notas_de_entrega') {
            $factura        = $this->carritoModel->obtenerNe($id_factura);
            $articulos      = $this->carritoModel->obtenerNeArticulos($id_factura);
            $abonos         = $this->carritoModel->abonosNe($id_factura);
            $total_pagos    = $this->carritoModel->totalPagos($id_factura, 1, 1);
            $creditos       = $this->carritoModel->obtenerCreditos($id_factura, 1);
            $total_pagos    = $total_pagos['total'] ? $total_pagos['total'] : 0.00;
            $pago_movil = $this->carritoModel->obtenerBalanceComprarDolares($id_factura, 1);
        } else if ($tabla_db == 'app_pedidos') {
            $factura        = $this->carritoModel->obtenerPe($id_factura);
            $articulos      = $this->carritoModel->obtenerPeArticulos($id_factura);
            $abonos         = [];
            $creditos       = [];
            $total_pagos    = 0.00;
        } else if ($tabla_db == 'app_presupuesto') {
            $factura        = $this->carritoModel->obtenerPre($id_factura);
            $articulos      = $this->carritoModel->obtenerPreArticulos($id_factura);
            $abonos         = [];
            $creditos       = [];
            $total_pagos    = 0.00;
        } else if ($tabla_db == 'app_orden_de_entrega') {
            $factura        = $this->carritoModel->obtenerOrdenE($id_factura);
            $articulos      = $this->carritoModel->obtenerOrdenArticulos($id_factura);
            $abonos         = $this->carritoModel->abonosOrden($id_factura);
            $total_pagos    = $this->carritoModel->totalPagos($id_factura, 12, 1);
            $creditos       = $this->carritoModel->obtenerCreditos($id_factura, 12);
            $total_pagos    = $total_pagos['total'] ? $total_pagos['total'] : 0.00;
        }

        $documento_credito = $this->carritoModel->obtenerDocumento(7);

        if (is_countable($creditos) && count($creditos)) {
            foreach ($creditos as $row) {
                $list_creditos[] = [
                    'id' => $row['cre_id'],
                    'fecha' => date('d-m-Y h:i A', strtotime($row['cre_fecha'])),
                    'estatus' => $row['cre_estatus'] ? true : false,
                    'correlativo' => $documento_credito['doc_prefijo'] . '' . $row['cre_correlativo'],
                    'monto' => Moneda::moneda($row['cre_monto'], $this->divisa_master['locale'], $this->divisa_master['symbol']),
                    'observaciones' => $row['cre_descripcion'] . ' ' . $row['cre_observacion']
                ];
            }
        }

        $divisa = $this->carritoModel->obtenerDivisa($factura['id_divisa']);

        $list_licencia = [];
        if ($tabla_db == 'app_notas_de_entrega' || $tabla_db == 'app_factura_master') {
            if (is_countable($articulos) && count($articulos)) {
                foreach ($articulos as $row) {
                    $producto = $this->carritoModel->obtenerProductoCategoria($row['id_producto']);
                    if ($producto) {
                        $list_licencia[] = [
                            'pro'                => $row['id_producto'],
                            'serial'            => $row['seriall'],
                            'fecha'            => $row['ser_fecha'],
                            'comentario'        => $row['comentario'],
                            'id'        => $row['id'],
                            'codigo' => $row['codigo'],
                            'producto' => $row['nombre']
                        ];
                    }
                }
            }
        }

        if (is_countable($articulos) && count($articulos)) {
            foreach ($articulos as $row) {
                if ($tabla_db == 'app_factura_master' || $tabla_db == 'app_notas_de_entrega') {
                    $tarif = ($row['tarifa'] == NULL) ? '' : $row['tarifa'];
                } else {
                    $tarif = '';
                }
                $producto = $this->carritoModel->obtenerProducto($row['id_producto']);
                $articulo = [
                    'id'                => $row['id_producto'],
                    'codigo'            => $row['codigo'],
                    'nombre'            => $row['nombre'],
                    'costo'             => $row['costo'],
                    'costo_servicio'    => $row['costo_servicio'] ?? 0,
                    'precio'            => $row['precio'],
                    'id_iva'            => $row['id_iva'],
                    'iva'               => $row['iva'],
                    'iva_total'         => $row['iva_total'],
                    'descuento'         => $row['descuento'],
                    'cantidad'          => $row['cantidad'],
                    'neto'              => $row['neto'],
                    'total'             => $row['total'],
                    'id_almacen'        => $row['alm_id'],
                    'tipo'              => $producto['pro_tipo'],
                    'tarifa'            => $tarif
                ];
                $articulo['unique'] = md5($articulo['id']);
                $_SESSION["$_nombre_carrito_$id_factura"][$articulo['unique']] = $articulo;
            }
        }

        $this->carrito_c = $_SESSION["$_nombre_carrito_$id_factura"];

        $_SESSION["$_nombre_carrito_$id_factura"]['divisa'] = $factura['id_divisa'];
        $_SESSION["$_nombre_carrito_$id_factura"]['id_almacen'] = $factura['id_almacen'];

        $div_format = Moneda::obtenerDivisa($_SESSION["$_nombre_carrito_$id_factura"]['divisa']);

        if ($this->carrito_c !== []) {
            foreach ($this->carrito_c as $row) {
                $this->carrito_c[$row['unique']]['precio'] = number_format($row['precio'], $div_format['precision'], $div_format['decimal'], $div_format['thousands']);
                $this->carrito_c[$row['unique']]['iva'] = number_format($row['iva'], $div_format['precision'], $div_format['decimal'], $div_format['thousands']);
                $this->carrito_c[$row['unique']]['iva_total'] = number_format($row['iva_total'], $div_format['precision'], $div_format['decimal'], $div_format['thousands']);
                $this->carrito_c[$row['unique']]['neto'] = number_format($row['neto'], $div_format['precision'], $div_format['decimal'], $div_format['thousands']);
                $this->carrito_c[$row['unique']]['total'] = number_format($row['total'], $div_format['precision'], $div_format['decimal'], $div_format['thousands']);
            }
        }

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

            foreach ($abonos as $row) {

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

                if (is_null($row['fab_divid_conversion'])) {
                    $divisa_conv_mov = $this->divisa_master;
                } else {
                    $divisa_conv_mov = Moneda::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'],
                    'credito'           => $row['fab_credito'],
                    'mp_nombre'         => $row['mp_nombre'],
                    'referencia'        => $row['fab_descripcion'],
                    'fab_monto'         => Moneda::moneda($row['fab_monto'], $divisa_mov['locale'], $divisa_mov['symbol']),
                    'fab_factor'        => ($row['fab_factor'] < 1) ? $row['fab_factor'] : Moneda::decimal($row['fab_factor'], $div_format['locale']),
                    'fab_conversion'    => Moneda::moneda($row['fab_conversion'], $div_format['locale'], $div_format['symbol'])
                ];
            }
        }

        $data = [
            'creditos'              => $list_creditos,
            'divisa'                => $div_format,
            'id_divisa'             => $factura['id_divisa'],
            'factura'               => $factura,
            'licencia'              => $list_licencia,
            'pago_movil'            => $pago_movil,
            'observaciones'         => $factura['observaciones'] ?? '',
            'articulos_cantidad'    => $factura['art_total'],
            'subtotal'              => round($factura['subtotal'], 2),
            'descuento'             => round($factura['descuento'], 2),
            'neto'                  => round($factura['neto'], 2),
            'iva'                   => round($factura['iva'], 2),
            'total'                 => round($factura['total'], 2),
            'total_pagado'          => round($total_pagos, 2),
            'restante'              => round($factura['total'] -  $total_pagos, 2),
            'data_carrito'          => $this->carrito_c,
            'abonos'                => $array_abonos,
            'factor'                => 1,
            'div_nombre'            => $divisa['div_nombre'],
            'div_locale'            => $divisa['div_locale'],
            'div_simbolo'           => $divisa['div_simbolo'],
            'div_decimal'           => $divisa['div_decimal'],
        ];

        $_SESSION["$_nombre_carrito_$id_factura"]['divisa']             = $factura['id_divisa'];
        $_SESSION["$_nombre_carrito_$id_factura"]['subtotal']           = $factura['subtotal'];
        $_SESSION["$_nombre_carrito_$id_factura"]['descuento']          = $factura['descuento'];
        $_SESSION["$_nombre_carrito_$id_factura"]['neto']               = $factura['neto'];
        $_SESSION["$_nombre_carrito_$id_factura"]['iva']                = $factura['iva'];
        $_SESSION["$_nombre_carrito_$id_factura"]['total']              = $factura['total'];
        $_SESSION["$_nombre_carrito_$id_factura"]['articulos_cantidad'] = $factura['art_total'];

        return $data;
    }

    public function obtenerCreditosFactura(int $id_factura, int $id_documento)
    {
        $documento_credito = $this->carritoModel->obtenerDocumento(7);
        $creditos = $this->carritoModel->obtenerCreditos($id_factura, $id_documento);
        $list_creditos = [];
        if (is_countable($creditos) && count($creditos)) {
            foreach ($creditos as $row) {
                $list_creditos[] = [
                    'id' => $row['cre_id'],
                    'fecha' => date('d-m-Y h:i A', strtotime($row['cre_fecha'])),
                    'estatus' => $row['cre_estatus'] ? true : false,
                    'correlativo' => $documento_credito['doc_prefijo'] . '' . $row['cre_correlativo'],
                    'monto' => Moneda::moneda($row['cre_monto'], $this->divisa_master['locale'], $this->divisa_master['symbol']),
                    'observaciones' => $row['cre_descripcion'] . ' ' . $row['cre_observacion']
                ];
            }
        }
        return $list_creditos;
    }

    public function imprimirCredito(int $id_credito, int $id_impresora)
    {
        $factura        = $this->carritoModel->obtenerCredito($id_credito);
        $impresora      = $this->carritoModel->impresora($id_impresora);

        if ($factura && $impresora) {

            $divisa     = Moneda::Predeterminada();

            return [
                'ip_puerto' => protocolo() . $impresora['ip_puerto'],
                'data' => [
                    'command' => 'generate_ticket_credito',
                    'args' => [[
                        'fecha_impresion'   => date('d-m-Y H:i:s'),
                        'fecha_creacion'    => date('d-m-Y H:i:s', strtotime($factura['cre_fecha'])),
                        'observacion'       => empty($factura['cre_descripcion']) ? '' : $factura['cre_descripcion'],
                        'num_ticket'        => $factura['cre_correlativo'],
                        'rif'               => $factura['cli_dni'],
                        'clients'           => $factura['cli_razon_social'],
                        'direccion'         => $factura['cli_direccion'],
                        'telefono'          => $factura['cli_telefono'],
                        'cajero'            => $factura['einfo_nombres'] . ' ' . $factura['einfo_apellidos'],
                        'monto_total'       => Moneda::moneda($factura['cre_monto'], $divisa['locale'], $divisa['symbol']),
                    ]]
                ]
            ];
        } else {
            $this->array_errors[] = 'Acción prohibida';
        }

        return ['errors' => $this->array_errors];
    }

    public function contenidoCarrito(string $_nombre_carrito_, int $id_factura)
    {
        $this->carrito = [];
        $this->carrito = $_SESSION["$_nombre_carrito_$id_factura"];
        unset($this->carrito['articulos_cantidad']);
        unset($this->carrito['subtotal']);
        unset($this->carrito['descuento']);
        unset($this->carrito['neto']);
        unset($this->carrito['iva']);
        unset($this->carrito['total']);
        unset($this->carrito['divisa']);
        unset($this->carrito['id_almacen']);
        return $this->carrito;
    }

    public function predeterminarDivisa(string $_nombre_carrito_, int $id_factura, $id_cliente, int $id_divisa, string $descuento_global)
    {
        $divisa = Moneda::obtenerDivisa($id_divisa);

        if ($divisa) {
            if ($divisa['id'] !== $this->divisa_master['id']) {
                $div_master = $_SESSION["$_nombre_carrito_$id_factura"]['divisa'] ?? $this->divisa_master['id'];
                if (!$this->carritoModel->obtenerDivisaAlCambio($div_master, $divisa['id'])) {
                    $this->array_errors[] = 'Lo siento no se encuentra algun valor establecido para la conversión con la moneda predetermminada';
                }
            }
        } else {
            $this->array_errors[] = 'Divisa predeterminada no establecisa o divisa no enontrada';
        }

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

            if (!is_null($_SESSION["$_nombre_carrito_$id_factura"])) {

                $descuento_global = convertir_a_float($descuento_global);
                $contenido_carrito = $this->contenidoCarrito($_nombre_carrito_, $id_factura);

                foreach ($contenido_carrito as $row) {

                    $divisa_factor = $this->carritoModel->obtenerProductoFactor($row['id']);

                    if ($divisa_factor) {
                        $precio = $this->obtenerPrecioSegunDivisaFactorProducto($divisa_factor['profac_bifac_serial'], $_SESSION["$_nombre_carrito_$id_factura"][$row['unique']]['precio'], $_SESSION["$_nombre_carrito_$id_factura"]['divisa'], $id_divisa);
                        $costo = $this->obtenerPrecioSegunDivisaFactorProducto($divisa_factor['profac_bifac_serial'], $_SESSION["$_nombre_carrito_$id_factura"][$row['unique']]['costo'], $_SESSION["$_nombre_carrito_$id_factura"]['divisa'], $id_divisa);
                        $costo_servicio = $this->obtenerPrecioSegunDivisaFactorProducto($divisa_factor['profac_bifac_serial'], $_SESSION["$_nombre_carrito_$id_factura"][$row['unique']]['costo_servicio'], $_SESSION["$_nombre_carrito_$id_factura"]['divisa'], $id_divisa);
                    } else {
                        $precio = $this->obtenerPrecioSegunDivisa($_SESSION["$_nombre_carrito_$id_factura"][$row['unique']]['precio'], $_SESSION["$_nombre_carrito_$id_factura"]['divisa'], $id_divisa);
                        $costo = $this->obtenerPrecioSegunDivisa($_SESSION["$_nombre_carrito_$id_factura"][$row['unique']]['costo'], $_SESSION["$_nombre_carrito_$id_factura"]['divisa'], $id_divisa);
                        $costo_servicio = $this->obtenerPrecioSegunDivisa($_SESSION["$_nombre_carrito_$id_factura"][$row['unique']]['costo_servicio'], $_SESSION["$_nombre_carrito_$id_factura"]['divisa'], $id_divisa);
                    }

                    $_SESSION["$_nombre_carrito_$id_factura"][$row['unique']]['precio'] = $precio['precio'];
                    $pc = $_SESSION["$_nombre_carrito_$id_factura"][$row['unique']]['cantidad'] * $_SESSION["$_nombre_carrito_$id_factura"][$row['unique']]['precio'];
                    $precio = $this->obtenerDescuentoMasIvaProducto($pc, $row['iva'], 'pvp', $_SESSION["$_nombre_carrito_$id_factura"][$row['unique']]['descuento']);
                    $_SESSION["$_nombre_carrito_$id_factura"][$row['unique']]['iva_total']      = $precio['iva'];
                    $_SESSION["$_nombre_carrito_$id_factura"][$row['unique']]['neto']           = $precio['neto'];
                    $_SESSION["$_nombre_carrito_$id_factura"][$row['unique']]['total']          = $precio['total'];
                    $_SESSION["$_nombre_carrito_$id_factura"][$row['unique']]['costo']          = $costo['precio'];
                    $_SESSION["$_nombre_carrito_$id_factura"][$row['unique']]['costo_servicio'] = $costo_servicio['precio'];
                }

                $_SESSION["$_nombre_carrito_$id_factura"]['divisa'] = $id_divisa;

                return [
                    'divisa' => $divisa,
                    'data_carrito' => $this->obtenerCarritoCliente($_nombre_carrito_, $id_factura, $id_cliente, $descuento_global)
                ];
            } else {
                return true;
            }
        }

        return ['errors' => $this->array_errors];
    }

    public function buscarProducto(string $producto, int $id_divisa, int $id_almacen, bool $stock = true)
    {
        $divisa = Moneda::obtenerDivisa($id_divisa);

        if ($divisa) {
            if ($divisa['id'] !== $this->divisa_master['id']) {
                $divisa_factor = $this->carritoModel->obtenerDivisaAlCambio($this->divisa_master['id'], $divisa['id']);
                if (!$divisa_factor) {
                    $this->array_errors[] = 'Lo siento no se encuentra algun valor establecido para la conversión con la moneda predetermminada.';
                } else {
                    $factor = $divisa_factor['df_factor'];
                }
            } else {
                $factor = 1;
            }
        } else {
            $this->array_errors[] = 'Divisa predeterminada no establecisa o divisa no encontrada';
        }

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

            $array_productos = [];

            if (strlen($producto) > 0) {

                if ($stock) {
                    $productos = $this->carritoModel->buscarProductos($id_almacen, $producto);
                } else {
                    $productos = $this->carritoModel->buscarProductosSinStock($producto);
                }

                if (is_countable($productos) && count($productos)) {
                    foreach ($productos as $row) {
                        $imagen = null;
                        if (($row['pi_imagen'] != null || $row['pi_imagen'] != '') && file_exists(constant('UPLOADS_URI') . 'productos/' . $row['pi_imagen'])) {
                            $imagen = constant('IMG_URI') . 'productos/' . $row['pi_imagen'];
                        }
                        $array_productos[] = [
                            'pro_id'            => $row['pro_id'],
                            'pro_descripcion'   => "({$row['pro_codigo']}) {$row['pro_descripcion']}",
                            'pro_precio'        => Moneda::moneda(($row['pro_precio'] * $factor), $divisa['locale'], $divisa['symbol']),
                            'ps_cantidad'       => $row['ps_cantidad'] ?? 0,
                            'id_almacen'        => $id_almacen,
                            'fabricante'        => $row['fa_nombre'],
                            'imagen'            => $imagen
                        ];
                    }
                }
            }

            return $array_productos;
        }

        return ['errors' => $this->array_errors];
    }

    public function actualizarPrecioTotalYCantidad(string $_nombre_carrito_, int $id_factura, int $id_cliente, $descuento = null)
    {
        $this->carrito = $_SESSION["$_nombre_carrito_$id_factura"];
        unset($this->carrito['articulos_cantidad']);
        unset($this->carrito['subtotal']);
        unset($this->carrito['descuento']);
        unset($this->carrito['neto']);
        unset($this->carrito['iva']);
        unset($this->carrito['total']);
        unset($this->carrito['divisa']);
        unset($this->carrito['id_almacen']);

        $subtotal = $total_iva = $neto = $total = $articulos_cantidad = 0;

        if (is_null($descuento)) {
            $descuento = $this->carritoModel->obtenerDescuento($id_cliente);
            $descuento = $descuento['cli_descuento'];
        }

        if ($descuento > 0) {
            foreach ($this->carrito as $row) {
                $articulos_cantidad += 1;
                $subtotal += $row['neto'];
                $precio = $this->obtenerDescuentoMasIvaProducto($row['neto'], $row['iva'], 'pvp', $descuento, 0);
                $neto += $precio['neto'];
                $total_iva += $precio['iva'];
                $total += $precio['total'];
            }
        } else {
            foreach ($this->carrito as $row) {
                $articulos_cantidad += 1;
                $neto += $row['neto'];
                $total_iva += $row['iva_total'];
                $total += $row['total'];
            }
            $subtotal = $neto;
        }

        $_SESSION["$_nombre_carrito_$id_factura"]['articulos_cantidad']   = $articulos_cantidad;
        $_SESSION["$_nombre_carrito_$id_factura"]['subtotal']             = $subtotal;
        $_SESSION["$_nombre_carrito_$id_factura"]['descuento']            = $descuento;
        $_SESSION["$_nombre_carrito_$id_factura"]['neto']                 = $neto;
        $_SESSION["$_nombre_carrito_$id_factura"]['iva']                  = $total_iva;
        $_SESSION["$_nombre_carrito_$id_factura"]['total']                = $neto + $total_iva;
    }

    public function obtenerCarritoCliente(string $_nombre_carrito_, int $id_factura, int $id_cliente, $descuento = null)
    {
        $this->actualizarPrecioTotalYCantidad($_nombre_carrito_, $id_factura, $id_cliente, $descuento);

        $div_format = Moneda::obtenerDivisa($_SESSION["$_nombre_carrito_$id_factura"]['divisa']);

        $carrito_c = [];
        $carrito_c = $_SESSION["$_nombre_carrito_$id_factura"];
        unset($carrito_c['articulos_cantidad']);
        unset($carrito_c['subtotal']);
        unset($carrito_c['descuento']);
        unset($carrito_c['neto']);
        unset($carrito_c['iva']);
        unset($carrito_c['total']);
        unset($carrito_c['divisa']);
        unset($carrito_c['id_almacen']);

        foreach ($carrito_c as $row) {
            $carrito_c[$row['unique']]['precio'] = number_format($row['precio'], $div_format['precision'], $div_format['decimal'], $div_format['thousands']);
            $carrito_c[$row['unique']]['iva'] = number_format($row['iva'], $div_format['precision'], $div_format['decimal'], $div_format['thousands']);
            $carrito_c[$row['unique']]['iva_total'] = number_format($row['iva_total'], $div_format['precision'], $div_format['decimal'], $div_format['thousands']);
            $carrito_c[$row['unique']]['neto'] = number_format($row['neto'], $div_format['precision'], $div_format['decimal'], $div_format['thousands']);
            $carrito_c[$row['unique']]['total'] = number_format($row['total'], $div_format['precision'], $div_format['decimal'], $div_format['thousands']);
        }

        return [
            'articulos_cantidad'    => round($_SESSION["$_nombre_carrito_$id_factura"]['articulos_cantidad'] ?? 0, 2),
            'subtotal'              => number_format($_SESSION["$_nombre_carrito_$id_factura"]['subtotal'] ?? 0, $div_format['precision'], $div_format['decimal'], $div_format['thousands']),
            'descuento'             => round($_SESSION["$_nombre_carrito_$id_factura"]['descuento'] ?? 0, 2),
            'neto'                  => number_format($_SESSION["$_nombre_carrito_$id_factura"]['neto'] ?? 0, $div_format['precision'], $div_format['decimal'], $div_format['thousands']),
            'iva'                   => number_format($_SESSION["$_nombre_carrito_$id_factura"]['iva'] ?? 0, $div_format['precision'], $div_format['decimal'], $div_format['thousands']),
            'total'                 => number_format($_SESSION["$_nombre_carrito_$id_factura"]['total'] ?? 0, $div_format['precision'], $div_format['decimal'], $div_format['thousands']),
            'carrito'               => array_reverse($carrito_c)
        ];
    }

    private function obtenerDescuentoMasIvaProducto(float $precio, float $iva, string $tipo_tarifa, float $tarifa)
    {
        $ivam = $precio * ($iva / 100);

        if ($tarifa > 0) {
            $precio = TarifasControlador::aplicar(null, $precio, $tipo_tarifa, $tarifa, 0, $ivam); //DESCUENTO PRODUCTO
        }

        $ivam = $precio * ($iva / 100);

        return [
            'iva' => $ivam,
            'neto' => $precio,
            'total' => $precio + $ivam,
        ];
    }

    public function obtenerPrecioSegunDivisa(float $precio, int $id_divisa_master, int $id_divisa_buscada)
    {
        $divisa_factor = $this->carritoModel->obtenerDivisaAlCambio($id_divisa_master, $id_divisa_buscada);

        if ($divisa_factor) {
            $precio *= $divisa_factor['df_factor'];
            $factor = $divisa_factor['df_factor'];
        } else {
            $factor = 1;
        }

        return [
            'precio' => $precio,
            'factor' => $factor
        ];
    }

    public function obtenerPrecioSegunDivisaFactorProducto(string $serial,  float $precio, int $id_divisa_master, int $id_divisa_buscada)
    {
        $divisa_factor = $this->carritoModel->obtenerDivisaAlCambioProducto($serial, $id_divisa_master, $id_divisa_buscada);

        if ($divisa_factor) {
            $precio *= $divisa_factor['bifac_factor'];
            $factor = $divisa_factor['bifac_factor'];
        } else {
            $factor = 1;
        }

        return [
            'precio' => $precio,
            'factor' => $factor
        ];
    }

    public function agregarProductoBarcode(string $tabla_db, string $_nombre_carrito_, int $id_factura, int $id_cliente, string $producto, int $id_almacen, int $id_divisa, string $descuento_global, bool $chequear_stock = true, bool $caja = false)
    {
        if ($caja) {
            $producto = $this->carritoModel->buscarProductoBarcodeVentasCaja($id_almacen, $producto);
        } else {
            $producto = $this->carritoModel->buscarProductoBarcode($id_almacen, $producto);
        }

        $preciot = 0;
        $descuento_producto = 0.00;
        $stockno = [];

        $divisa   = Moneda::obtenerDivisa($id_divisa);

        if (!$producto || !$divisa)
            $this->array_errors[] = 'Producto o Divisa no disponibles';

        $modulo = new Module();

        $tarifas_clientes =  $this->carritoModel->consultar("SELECT * FROM app_clientes WHERE cli_id={$id_cliente}")->row();
        $permiso_tarifa = $modulo->has_module_action_permission('facturacion', 'agregar_tarifa', $_SESSION['user_data']['emp_id']);

        if ($producto) {
            if ($tarifas_clientes && $permiso_tarifa && $producto) {
                $tarifas =  $this->carritoModel->consultar("SELECT * FROM app_tarifas WHERE tar_id={$tarifas_clientes['cli_gruptarid']}")->row();
                $tarifa_producto =  $this->carritoModel->consultar("SELECT * FROM app_productos_tarifas WHERE pt_proid={$producto['pro_id']} AND pt_tarid={$tarifas_clientes['cli_gruptarid']}")->row();

                if ($tarifa_producto) {
                    if ($tarifa_producto['pt_tarprecio'] > 0) {
                        $preciot = $tarifa_producto['pt_tarprecio'];
                    } else {
                        $preciot = $producto['pro_precio'];
                        $descuento_producto = $tarifas['tar_valorx'];
                    }
                } else {
                    $preciot = $producto['pro_precio'];
                }
            } else {
                $preciot = $producto['pro_precio'];
            }

            $factor_producto = $this->carritoModel->obtenerProductoFactor($producto['pro_id']);

            if ($tabla_db == 'app_factura_master' || $tabla_db == 'app_notas_de_entrega' || $tabla_db == 'app_pedidos' || $tabla_db == 'app_presupuesto') {
                $imp_data = $this->carritoModel->obtenerImpuesto($producto['pro_impid']);
            } else {
                $imp_data = $this->carritoModel->obtenerImpuesto(2);

                if ($tabla_db == 'app_orden_de_entrega') {
                    $planilla   = $this->carritoModel->obtenerPlanilla($id_factura);
                    if ($planilla && $producto['pro_tipo'] == 3) {
                        if (!$GLOBALS['newDBIni']->consultar("SELECT serv_id FROM app_planillas_servicios WHERE serv_proid = {$producto['pro_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 ($producto['pro_tipo'] == 2) {
                $productoCompuesto = new ProductosCompuestos();

                $productoscomp = $productoCompuesto->obtenerProductosCompuesto($producto['pro_id']);
                if (!$productoscomp) {
                    $this->array_errors[] = 'Error el producto compuesto ' . $producto['pro_descripcion'] . ' no tiene ningun producto';
                }
            }
        }


        if ($_SESSION["$_nombre_carrito_$id_factura"] != null) {
            if ($_SESSION["$_nombre_carrito_$id_factura"]['id_almacen'] != $id_almacen)
                $this->array_errors[] = 'No puede seleccionar otro almacén diferente';
            if ($_SESSION["$_nombre_carrito_$id_factura"]['divisa'] != $id_divisa)
                $this->array_errors[] = 'No puede seleccionar otra divisa diferente';
        }


        if ($divisa['id'] !== $this->divisa_master['id']) {
            $divisa_factor = $this->carritoModel->obtenerDivisaAlCambio($this->divisa_master['id'], $divisa['id']);
            if (!$divisa_factor)
                $this->array_errors[] = 'Lo siento no se encuentra el valor establecido para la conversión con la moneda predeterminada.';
        }

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

            $descuento_global = convertir_a_float($descuento_global);
            $unique = md5($producto['pro_id']);
            $seguir = true;

            if (isset($_SESSION["$_nombre_carrito_$id_factura"][$unique])) {

                $id_divisa_master   = $_SESSION["$_nombre_carrito_$id_factura"]['divisa'];
                $precio             = $_SESSION["$_nombre_carrito_$id_factura"][$unique]['precio'];
                $id_iva             = $_SESSION["$_nombre_carrito_$id_factura"][$unique]['id_iva'];
                $iva                = $_SESSION["$_nombre_carrito_$id_factura"][$unique]['iva'];
                $nombre             = $_SESSION["$_nombre_carrito_$id_factura"][$unique]['nombre'];

                if ($producto['pro_tipo'] == 2) {
                    $productoCompuesto = new ProductosCompuestos();
                    $segui = [];
                    $productos = $productoCompuesto->obtenerProductosCompuesto($producto['pro_id']);

                    if (is_countable($productos) && count($productos)) {
                        foreach ($productos as $row) {
                            $producto_stock = $this->carritoModel->verificarProductoEnStock($row['pro_ccproid'], $id_almacen);
                            if ($producto_stock  && $row['pro_cccant'] > 0) {
                                $cantidad = convertir_a_float($_SESSION["$_nombre_carrito_$id_factura"][$unique]['cantidad'] + 1);
                                $cant = convertir_a_float($cantidad * $row['pro_cccant']);
                                if ($cant > $producto_stock['ps_cantidad']) {
                                    $segui[] = false;
                                    $stockno[] = ['producto' => $row['pro_descripcion']];
                                }
                            } else {
                                $segui[] = false;
                                $stockno[] = ['producto' => $row['pro_descripcion']];
                            }
                        }
                    }
                    if (in_array(false, $segui)) {
                        $seguir = false;
                    }
                }

                /*
                if ($producto['pro_tipo'] != 3 && $producto['pro_nostock'] == 0) {

                    if ($chequear_stock) {

                        $producto_stock = $this->carritoModel->verificarProductoEnStock($producto['pro_id'], $id_almacen);

                        if ($tabla_db == 'app_notas_de_entrega') {
                            $det_pro = $this->carritoModel->obtenerProductoNe($id_factura, $producto['pro_id']);
                        } else {
                            $det_pro = false;
                        }

                        if ($producto_stock) {
                            if ($det_pro) {
                                $cantidad = $_SESSION["$_nombre_carrito_$id_factura"][$unique]['cantidad'] + 1;
                                $solicitado = $cantidad - $det_pro['descontado'];
                                if ($solicitado > $producto_stock['ps_cantidad'])
                                    $seguir = false;
                            } else {
                                $cantidad = $_SESSION["$_nombre_carrito_$id_factura"][$unique]['cantidad'] + 1;
                                if ($cantidad > $producto_stock['ps_cantidad']) {
                                    $seguir = false;
                                }
                            }
                        } else {
                            $seguir = false;
                        }
                    }
                }*/
            } else {

                /*
                if ($producto['pro_tipo'] != 3 && $producto['pro_nostock'] == 0) {
                    if ($chequear_stock) {
                        $producto_stock = $this->carritoModel->verificarProductoEnStock($producto['pro_id'], $id_almacen);
                        if ($producto_stock) {
                            if (1 > $producto_stock['ps_cantidad'])
                                $seguir = false;
                        } else {
                            $seguir = false;
                        }
                    }
                }*/

                if ($producto['pro_tipo'] == 2) {
                    $productoCompuesto = new ProductosCompuestos();
                    $segui = [];
                    $productos = $productoCompuesto->obtenerProductosCompuesto($producto['pro_id']);

                    if (is_countable($productos) && count($productos)) {
                        foreach ($productos as $row) {
                            $producto_stock = $this->carritoModel->verificarProductoEnStock($row['pro_ccproid'], $id_almacen);
                            if ($producto_stock  && $row['pro_cccant'] > 0) {
                                $cant = convertir_a_float($row['pro_cccant']);
                                if ($cant > $producto_stock['ps_cantidad']) {
                                    $segui[] = false;
                                    $stockno[] = ['producto' => $row['pro_descripcion']];
                                }
                            } else {
                                $segui[] = false;
                                $stockno[] = ['producto' => $row['pro_descripcion']];
                            }
                        }
                    }
                    if (in_array(false, $segui)) {
                        $seguir = false;
                    }
                }

                $id_divisa_master   = $this->divisa_master['id'];
                $precio             = $preciot;
                $id_iva             = $imp_data['imp_id'];
                $iva                = $imp_data['imp_valor'];
                $nombre             = $producto['pro_descripcion'];
            }

            if ($seguir == false) {
                if ($producto['pro_tipo'] == 2 && is_countable($stockno) && count($stockno)) {
                    foreach ($stockno as $row) {
                        $this->array_errors[] = 'El producto ' . $row['producto'] . ' del producto compuesto ha superado el limite de stock';
                    }
                } else {
                    $this->array_errors[] = 'Ha superado el limite de stock';
                }
            } else {

                if ($factor_producto) {
                    $precio = $this->obtenerPrecioSegunDivisaFactorProducto($factor_producto['profac_bifac_serial'], $precio, $id_divisa_master, $divisa['id']);
                    $costo  = $this->obtenerPrecioSegunDivisaFactorProducto($factor_producto['profac_bifac_serial'], $producto['pro_costo'], $id_divisa_master, $divisa['id']);
                    $costo_servicio = $this->obtenerPrecioSegunDivisaFactorProducto($factor_producto['profac_bifac_serial'], $producto['pro_precio'], $id_divisa_master, $divisa['id']);
                } else {
                    $precio = $this->obtenerPrecioSegunDivisa($precio, $id_divisa_master, $divisa['id']);
                    $costo  = $this->obtenerPrecioSegunDivisa($producto['pro_costo'], $id_divisa_master, $divisa['id']);
                    $costo_servicio = $this->obtenerPrecioSegunDivisa($producto['pro_precio'], $id_divisa_master, $divisa['id']);
                }

                $articulo = [
                    'id'                => $producto['pro_id'],
                    'codigo'            => $producto['pro_codigo'],
                    'nombre'            => $nombre,
                    'costo'             => ($producto['pro_tipo'] == 3) ? 0 : $costo['precio'],
                    'costo_servicio'    => ($producto['pro_tipo'] == 3) ? $costo_servicio['precio'] : 0,
                    'precio'            => $precio['precio'],
                    'id_iva'            => $id_iva,
                    'iva'               => $iva,
                    'id_almacen'        => $id_almacen,
                    'descuento'         => $descuento_producto,
                    'cantidad'          => 1.00,
                    'tipo'              => $producto['pro_tipo'],
                    'tarifa'            => ""
                ];

                $articulo['unique'] = $unique;

                $contenido_carrito = $this->contenidoCarrito($_nombre_carrito_, $id_factura);

                if (!empty($contenido_carrito)) {
                    foreach ($contenido_carrito as $row) {
                        if ($row['id'] === $articulo['id']) {
                            $articulo['cantidad'] += convertir_a_float($row['cantidad']);
                        }
                    }
                }

                $precio = $this->obtenerDescuentoMasIvaProducto(($articulo['cantidad'] * $articulo['precio']), $articulo['iva'], 'pvp', $descuento_producto);

                $articulo['iva_total']  = $precio['iva'];
                $articulo['neto']       = $precio['neto'];
                $articulo['total']      = $precio['total'];

                $_SESSION["$_nombre_carrito_$id_factura"][$unique] = $articulo;
                $_SESSION["$_nombre_carrito_$id_factura"]['divisa'] = $id_divisa;
                $_SESSION["$_nombre_carrito_$id_factura"]['id_almacen'] = $id_almacen;

                return $this->obtenerCarritoCliente($_nombre_carrito_, $id_factura, $id_cliente, $descuento_global);
            }
        }

        return ['errors' => $this->array_errors];
    }

    public function agregarProducto(string $tabla_db, string $_nombre_carrito_, int $id_factura, int $id_cliente, int $id_producto, int $id_almacen, int $id_divisa, string $descuento_global, bool $chequear_stock = true)
    {
        $producto = $this->carritoModel->obtenerProducto($id_producto);
        $factor_producto = $this->carritoModel->obtenerProductoFactor($id_producto);
        $divisa   = Moneda::obtenerDivisa($id_divisa);

        $preciot = 0;
        $descuento_producto = 0.00;
        $stockno = [];

        $modulo = new Module();

        $tarifas_clientes =  $this->carritoModel->consultar("SELECT * FROM app_clientes WHERE cli_id={$id_cliente}")->row();
        $permiso_tarifa = $modulo->has_module_action_permission('facturacion', 'agregar_tarifa', $_SESSION['user_data']['emp_id']);

        if ($tarifas_clientes && $permiso_tarifa) {
            $tarifas =  $this->carritoModel->consultar("SELECT * FROM app_tarifas WHERE tar_id={$tarifas_clientes['cli_gruptarid']}")->row();
            $tarifa_producto =  $this->carritoModel->consultar("SELECT * FROM app_productos_tarifas WHERE pt_proid={$id_producto} AND pt_tarid={$tarifas_clientes['cli_gruptarid']}")->row();

            if ($tarifa_producto) {
                if ($tarifa_producto['pt_tarprecio'] > 0) {
                    $preciot = $tarifa_producto['pt_tarprecio'];
                } else {
                    $preciot = $producto['pro_precio'];
                    $descuento_producto = $tarifas['tar_valorx'];
                }
            } else {
                $preciot = $producto['pro_precio'];
            }
        } else {
            $preciot = $producto['pro_precio'];
        }

        if ($tabla_db == 'app_factura_master' || $tabla_db == 'app_notas_de_entrega' || $tabla_db == 'app_pedidos' || $tabla_db == 'app_presupuesto') {
            if ($producto['pro_impid'] != null) {
                $imp_data = $this->carritoModel->obtenerImpuesto($producto['pro_impid']);
            } else {
                $imp_data = $this->carritoModel->obtenerImpuesto(2);
            }
        } else {
            $imp_data = $this->carritoModel->obtenerImpuesto(2);

            if ($tabla_db == 'app_orden_de_entrega') {
                $planilla   = $this->carritoModel->obtenerPlanilla($id_factura);
                if ($planilla && $producto['pro_tipo'] == 3) {
                    if (!$GLOBALS['newDBIni']->consultar("SELECT serv_id FROM app_planillas_servicios WHERE serv_proid = $id_producto")->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 (!$producto || !$divisa)
            $this->array_errors[] = 'Producto o Divisa no disponibles';

        if ($_SESSION["$_nombre_carrito_$id_factura"] != null) {
            if ($_SESSION["$_nombre_carrito_$id_factura"]['id_almacen'] != $id_almacen)
                $this->array_errors[] = 'No puede seleccionar otro almacen diferente';
            if ($_SESSION["$_nombre_carrito_$id_factura"]['divisa'] != $id_divisa)
                $this->array_errors[] = 'No puede seleccionar otra divisa diferente';
        }


        if ($producto['pro_tipo'] == 2) {
            $productoCompuesto = new ProductosCompuestos();

            $productoscomp = $productoCompuesto->obtenerProductosCompuesto($producto['pro_id']);
            if (!$productoscomp) {
                $this->array_errors[] = 'Error el producto compuesto ' . $producto['pro_descripcion'] . ' no tiene ningun producto';
            }
        }

        if ($divisa['id'] !== $this->divisa_master['id']) {
            $divisa_factor = $this->carritoModel->obtenerDivisaAlCambio($this->divisa_master['id'], $divisa['id']);
            if (!$divisa_factor)
                $this->array_errors[] = 'Lo siento no se encuentra el valor establecido para la conversión con la moneda predeterminada.';
        }

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

            $descuento_global = convertir_a_float($descuento_global);
            $unique = md5($producto['pro_id']);
            $seguir = true;

            if (isset($_SESSION["$_nombre_carrito_$id_factura"][$unique])) {

                $id_divisa_master   = $_SESSION["$_nombre_carrito_$id_factura"]['divisa'];
                $precio             = $_SESSION["$_nombre_carrito_$id_factura"][$unique]['precio'];
                $id_iva             = $_SESSION["$_nombre_carrito_$id_factura"][$unique]['id_iva'];
                $iva                = $_SESSION["$_nombre_carrito_$id_factura"][$unique]['iva'];
                $nombre             = $_SESSION["$_nombre_carrito_$id_factura"][$unique]['nombre'];

                if ($producto['pro_tipo'] == 2) {
                    $productoCompuesto = new ProductosCompuestos();

                    $productos = $productoCompuesto->obtenerProductosCompuesto($id_producto);
                    $segui = [];

                    if (is_countable($productos) && count($productos)) {
                        foreach ($productos as $row) {
                            $producto_stock = $this->carritoModel->verificarProductoEnStock($row['pro_ccproid'], $id_almacen);
                            if ($producto_stock && $row['pro_cccant'] > 0) {
                                $cantidad = $_SESSION["$_nombre_carrito_$id_factura"][$unique]['cantidad'] + 1;
                                $cant = convertir_a_float($cantidad * $row['pro_cccant']);
                                if ($cant > $producto_stock['ps_cantidad']) {
                                    $segui[] = false;
                                    $stockno[] = ['producto' => $row['pro_descripcion']];
                                }
                            } else {
                                $segui[] = false;
                                $stockno[] = ['producto' => $row['pro_descripcion']];
                            }
                        }
                    }
                    if (in_array(false, $segui)) {
                        $seguir = false;
                    }
                }

                /*
                if ($producto['pro_tipo'] != 3 && $producto['pro_nostock'] == 0) {

                    if ($chequear_stock) {

                        $producto_stock = $this->carritoModel->verificarProductoEnStock($producto['pro_id'], $id_almacen);

                        if ($tabla_db == 'app_notas_de_entrega') {
                            $det_pro = $this->carritoModel->obtenerProductoNe($id_factura, $producto['pro_id']);
                        } else {
                            $det_pro = false;
                        }

                        if ($producto_stock) {
                            if ($det_pro) {
                                $cantidad = $_SESSION["$_nombre_carrito_$id_factura"][$unique]['cantidad'] + 1;
                                $solicitado = $cantidad - $det_pro['descontado'];
                                if ($solicitado > $producto_stock['ps_cantidad'])
                                    $seguir = false;
                            } else {
                                $cantidad = $_SESSION["$_nombre_carrito_$id_factura"][$unique]['cantidad'] + 1;
                                if ($cantidad > $producto_stock['ps_cantidad']) {
                                    $seguir = false;
                                }
                            }
                        } else {
                            $seguir = false;
                        }
                    }
                }*/
            } else {

                /*
                if ($chequear_stock) {
                    if ($producto['pro_tipo'] != 3 && $producto['pro_nostock'] == 0) {
                        $producto_stock = $this->carritoModel->verificarProductoEnStock($producto['pro_id'], $id_almacen);
                        if ($producto_stock) {
                            if (1 > $producto_stock['ps_cantidad'])
                                $seguir = false;
                        } else {
                            $seguir = false;
                        }
                    }
                }*/

                if ($producto['pro_tipo'] == 2) {
                    $productoCompuesto = new ProductosCompuestos();
                    $segui = [];
                    $productos = $productoCompuesto->obtenerProductosCompuesto($id_producto);

                    if (is_countable($productos) && count($productos)) {
                        foreach ($productos as $row) {
                            $producto_stock = $this->carritoModel->verificarProductoEnStock($row['pro_ccproid'], $id_almacen);
                            if ($producto_stock && $row['pro_cccant'] > 0) {
                                $cant = convertir_a_float($row['pro_cccant']);
                                if ($cant > $producto_stock['ps_cantidad']) {
                                    $stockno[] = ['producto' => $row['pro_descripcion']];
                                    $segui[] = false;
                                }
                            } else {
                                $segui[] = false;
                                $stockno[] = ['producto' => $row['pro_descripcion']];
                            }
                        }
                    }
                    if (in_array(false, $segui)) {
                        $seguir = false;
                    }
                }

                $id_divisa_master   = $this->divisa_master['id'];
                $precio             = $preciot;
                $id_iva             = $imp_data['imp_id'];
                $iva                = $imp_data['imp_valor'];
                $nombre             = $producto['pro_descripcion'];
            }

            if ($seguir == false) {
                if ($producto['pro_tipo'] == 2 && is_countable($stockno) && count($stockno)) {
                    foreach ($stockno as $row) {
                        $this->array_errors[] = 'El producto ' . $row['producto'] . ' del producto compuesto ha superado el limite de stock';
                    }
                } else {
                    $this->array_errors[] = 'Ha superado el limite de stock';
                }
            } else {

                if ($factor_producto) {
                    $precio = $this->obtenerPrecioSegunDivisaFactorProducto($factor_producto['profac_bifac_serial'], $precio, $id_divisa_master, $divisa['id']);
                    $costo  = $this->obtenerPrecioSegunDivisaFactorProducto($factor_producto['profac_bifac_serial'], $producto['pro_costo'], $id_divisa_master, $divisa['id']);
                    $costo_servicio = $this->obtenerPrecioSegunDivisaFactorProducto($factor_producto['profac_bifac_serial'], $producto['pro_precio'], $id_divisa_master, $divisa['id']);
                } else {
                    $precio = $this->obtenerPrecioSegunDivisa($precio, $id_divisa_master, $divisa['id']);
                    $costo  = $this->obtenerPrecioSegunDivisa($producto['pro_costo'], $id_divisa_master, $divisa['id']);
                    $costo_servicio = $this->obtenerPrecioSegunDivisa($producto['pro_precio'], $id_divisa_master, $divisa['id']);
                }

                $articulo = [
                    'id'                => $producto['pro_id'],
                    'codigo'            => $producto['pro_codigo'],
                    'nombre'            => $nombre,
                    'costo'             => ($producto['pro_tipo'] == 3) ? 0 : $costo['precio'],
                    'costo_servicio'    => ($producto['pro_tipo'] == 3) ? $costo_servicio['precio'] : 0,
                    'precio'            => $precio['precio'],
                    'id_iva'            => $id_iva,
                    'iva'               => $iva,
                    'id_almacen'        => $id_almacen,
                    'descuento'         => $descuento_producto,
                    'cantidad'          => 1.00,
                    'tipo'              => $producto['pro_tipo'],
                    'tarifa'            => '',
                ];

                $articulo['unique'] = $unique;

                $contenido_carrito = $this->contenidoCarrito($_nombre_carrito_, $id_factura);

                if (!empty($contenido_carrito)) {
                    foreach ($contenido_carrito as $row) {
                        if ($row['id'] === $articulo['id']) {
                            $articulo['cantidad'] += convertir_a_float($row['cantidad']);
                        }
                    }
                }

                $precio = $this->obtenerDescuentoMasIvaProducto(($articulo['cantidad'] * $articulo['precio']), $articulo['iva'], 'pvp', $descuento_producto);

                $articulo['iva_total']  = $precio['iva'];
                $articulo['neto']       = $precio['neto'];
                $articulo['total']      = $precio['total'];

                $_SESSION["$_nombre_carrito_$id_factura"][$unique] = $articulo;
                $_SESSION["$_nombre_carrito_$id_factura"]['divisa'] = $id_divisa;
                $_SESSION["$_nombre_carrito_$id_factura"]['id_almacen'] = $id_almacen;

                return $this->obtenerCarritoCliente($_nombre_carrito_, $id_factura, $id_cliente, $descuento_global);
            }
        }

        return ['errors' => $this->array_errors];
    }

    public function actualizarPrecio(string $_nombre_carrito_, int $id_factura, int $id_cliente, string $unique, string $precio, string $descuento_global)
    {
        if (!isset($_SESSION["$_nombre_carrito_$id_factura"][$unique])) {
            $this->array_errors[] = 'Acción prohibida';
        } else {
            $precio = convertir_a_float($precio);
            $descuento_global = convertir_a_float($descuento_global);
            $_SESSION["$_nombre_carrito_$id_factura"][$unique]['precio'] = $precio;
            $pc = $_SESSION["$_nombre_carrito_$id_factura"][$unique]['cantidad'] * $precio;
            $precio = $this->obtenerDescuentoMasIvaProducto($pc, $_SESSION["$_nombre_carrito_$id_factura"][$unique]['iva'], 'pvp', $_SESSION["$_nombre_carrito_$id_factura"][$unique]['descuento']);
            $_SESSION["$_nombre_carrito_$id_factura"][$unique]['iva_total']   = $precio['iva'];
            $_SESSION["$_nombre_carrito_$id_factura"][$unique]['neto']        = $precio['neto'];
            $_SESSION["$_nombre_carrito_$id_factura"][$unique]['total']       = $precio['total'];
            return $this->obtenerCarritoCliente($_nombre_carrito_, $id_factura, $id_cliente, $descuento_global);
        }

        return ['errors' => $this->array_errors];
    }

    public function actualizarPrecioTarifa(string $_nombre_carrito_, int $id_factura, int $id_cliente, string $unique, int $id_producto, int $id_tarifa, string $descuento_global)
    {
        if (!isset($_SESSION["$_nombre_carrito_$id_factura"][$unique])) {
            $this->array_errors[] = 'Acción prohibida';
        } else {

            $pro = $this->carritoModel->consultar("SELECT * FROM app_productos WHERE pro_id={$id_producto}")->row();
            $tarifas_productos = $this->carritoModel->consultar("SELECT * FROM app_productos_tarifas WHERE pt_proid={$id_producto} AND pt_tarid={$id_tarifa}")->row();
            $tarifa_data = $this->carritoModel->consultar("SELECT * FROM app_tarifas WHERE tar_id={$id_tarifa}")->row();
            $imp = $this->carritoModel->obtenerImpuesto($pro['pro_impid']);
            if ($tarifas_productos) {
                $monto_tarifa = $tarifas_productos['pt_tarprecio'];
                if ($monto_tarifa > 0) {
                    $precio_total = $monto_tarifa;
                } else {
                    $iv = ($pro['pro_precio'] * ($imp['imp_valor'] / 100));
                    $precio_total = TarifasControlador::aplicar($pro['pro_costo'], $pro['pro_precio'], $tarifa_data['tar_aplicar'], $tarifa_data['tar_valorx'], $tarifa_data['tar_valory'], $iv);
                }

                $precio = convertir_a_float($precio_total);
                $divisa_factor = $this->carritoModel->obtenerDivisaAlCambio($this->divisa_master['id'], $_SESSION["$_nombre_carrito_$id_factura"]['divisa']);

                if ($divisa_factor) {
                    $precio *= $divisa_factor['df_factor'];
                    $factor = $divisa_factor['df_factor'];
                } else {
                    $factor = 1;
                }

                $_SESSION["$_nombre_carrito_$id_factura"][$unique]['precio'] = $precio;
                $pc = $_SESSION["$_nombre_carrito_$id_factura"][$unique]['cantidad'] * $precio;
                $precio = $this->obtenerDescuentoMasIvaProducto($pc, $_SESSION["$_nombre_carrito_$id_factura"][$unique]['iva'], 'pvp', $_SESSION["$_nombre_carrito_$id_factura"][$unique]['descuento']);
                $_SESSION["$_nombre_carrito_$id_factura"][$unique]['iva_total']   = $precio['iva'];
                $_SESSION["$_nombre_carrito_$id_factura"][$unique]['neto']        = $precio['neto'];
                $_SESSION["$_nombre_carrito_$id_factura"][$unique]['total']       = $precio['total'];
                $_SESSION["$_nombre_carrito_$id_factura"][$unique]['tarifa']      = $tarifa_data['tar_nombre'];
                return $this->obtenerCarritoCliente($_nombre_carrito_, $id_factura, $id_cliente, $descuento_global);
            }
        }
    }

    public function actualizarCantidad(string $_nombre_carrito_, string $tabla_db, int $id_factura, int $id_cliente, int $id_producto, float $cantidad, string $descuento_global, bool $chequear_stock = true)
    {
        $producto = $this->carritoModel->obtenerProducto($id_producto);
        $newPlanillaOrden = new PlanillaOrdenDeEntrega();

        if ($tabla_db == 'app_orden_de_entrega') {
            $data_planilla = $newPlanillaOrden->obtenerOrden($id_factura);
            if ($data_planilla && $producto['pro_tipo'] == 3) {
                return ['errors' => ['La cantidad no puede ser modificada']];
            }
        }

        if (!$producto)
            $this->array_errors[] = 'Producto no disponible';

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

            $unique = md5($id_producto);
            $seguir = false;

            $cantidad = $cantidad;
            $stockno = [];


            if (!isset($_SESSION["$_nombre_carrito_$id_factura"][$unique])) {
                $this->array_errors[] = 'Producto no disponible';
            } else {

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

                    if ($producto['pro_nostock'] == 0) {

                        if ($chequear_stock) {

                            if ($tabla_db == 'app_notas_de_entrega') {
                                $det_pro = $this->carritoModel->obtenerProductoNe($id_factura, $id_producto);
                            } else if ($tabla_db == 'app_orden_de_entrega') {
                                $det_pro = $this->carritoModel->obtenerProductoOr($id_factura, $id_producto);
                            } else {
                                $det_pro = false;
                            }
                            $segui = [];
                            if ($producto['pro_tipo'] == 2) {
                                $productoCompuesto = new ProductosCompuestos();
                                $producto_stockCompuesto = $this->carritoModel->verificarProductoEnStock($id_producto, $_SESSION["$_nombre_carrito_$id_factura"][$unique]['id_almacen']);
                                $productos = $productoCompuesto->obtenerProductosCompuesto($id_producto);

                                if ($producto_stockCompuesto) {
                                    if ($det_pro) {
                                        $solicitad = convertir_a_float($cantidad - $det_pro['descontado']);
                                        if ($solicitad <= $producto_stockCompuesto['ps_cantidad']) {
                                            if (is_countable($productos) && count($productos)) {
                                                foreach ($productos as $row) {
                                                    $producto_stock = $this->carritoModel->verificarProductoEnStock($row['pro_id'], $det_pro['alm_id']);
                                                    if ($producto_stock) {
                                                        $cant = convertir_a_float($cantidad * $row['pro_cccant']);
                                                        $de = convertir_a_float($det_pro['descontado'] * $row['pro_cccant']);
                                                        $solicitado = $cant - $de;
                                                        if ($solicitado <= $producto_stock['ps_cantidad']) {
                                                            $segui[] = true;
                                                        } else {
                                                            $segui[] = false;
                                                            $stockno[] = ['producto' => $row['pro_descripcion']];
                                                        }
                                                    }
                                                }
                                            }
                                            if (in_array(false, $segui)) {
                                                $seguir = false;
                                            } else {
                                                $seguir = true;
                                            }
                                        } else {
                                            $seguir = false;
                                        }
                                    } else {
                                        if ($cantidad <= $producto_stockCompuesto['ps_cantidad']) {
                                            if (is_countable($productos) && count($productos)) {
                                                foreach ($productos as $row) {
                                                    $producto_stock = $this->carritoModel->verificarProductoEnStock($row['pro_id'], $det_pro['alm_id']);
                                                    if ($producto_stock) {
                                                        if ($cantidad <= $producto_stockCompuesto['ps_cantidad']) {
                                                            $cant = convertir_a_float($cantidad * $row['pro_cccant']);

                                                            if ($cant <= $producto_stock['ps_cantidad']) {
                                                                $segui[] = true;
                                                            } else {
                                                                $segui[] = false;
                                                                $stockno[] = ['producto' => $row['pro_descripcion']];
                                                            }
                                                        }
                                                    }
                                                }
                                            }
                                            if (in_array(false, $segui)) {
                                                $seguir = false;
                                            } else {
                                                $seguir = true;
                                            }
                                        } else {
                                            $seguir = false;
                                        }
                                    }
                                }
                            } else {
                                $producto_stock = $this->carritoModel->verificarProductoEnStock($id_producto, $_SESSION["$_nombre_carrito_$id_factura"][$unique]['id_almacen']);

                                if ($producto_stock) {
                                    if ($det_pro) {
                                        $solicitado = convertir_a_float($cantidad - $det_pro['descontado']);
                                        if ($solicitado <= $producto_stock['ps_cantidad'])
                                            $seguir = true;
                                    } else {
                                        if ($cantidad <= $producto_stock['ps_cantidad']) {
                                            $seguir = true;
                                        }
                                    }
                                }
                            }
                        } else {
                            $seguir = true;
                        }
                    } else {
                        $seguir = true;
                    }
                } else {
                    $seguir = true;
                }

                if ($seguir == false) {
                    if ($producto['pro_tipo'] == 2 && is_countable($stockno) && count($stockno)) {
                        foreach ($stockno as $row) {
                            $this->array_errors[] = 'El producto ' . $row['producto'] . ' del producto compuesto ha superado el limite de stock';
                        }
                    } else {
                        $this->array_errors[] = 'Ha superado el limite de stock';
                    }
                } else {
                    $descuento_global = convertir_a_float($descuento_global);
                    $pc = $cantidad * $_SESSION["$_nombre_carrito_$id_factura"][$unique]['precio'];
                    $precio = $this->obtenerDescuentoMasIvaProducto($pc, $_SESSION["$_nombre_carrito_$id_factura"][$unique]['iva'], 'pvp', $_SESSION["$_nombre_carrito_$id_factura"][$unique]['descuento']);
                    $_SESSION["$_nombre_carrito_$id_factura"][$unique]['cantidad']    = $cantidad;
                    $_SESSION["$_nombre_carrito_$id_factura"][$unique]['iva_total']   = $precio['iva'];
                    $_SESSION["$_nombre_carrito_$id_factura"][$unique]['neto']        = $precio['neto'];
                    $_SESSION["$_nombre_carrito_$id_factura"][$unique]['total']       = $precio['total'];
                    //$this->carritoModel->actualizarCantidadServicioDePlanilla($id_factura, $id_producto, $cantidad);
                    return $this->obtenerCarritoCliente($_nombre_carrito_, $id_factura, $id_cliente, $descuento_global);
                }
            }
        }

        return ['errors' => $this->array_errors];
    }

    public function actualizarDescripcion(string $_nombre_carrito_, int $id_factura, string $unique, string $descripcion)
    {
        if (!isset($_SESSION["$_nombre_carrito_$id_factura"][$unique])) {
            $this->array_errors[] = 'Producto no disponible';
        } else {
            $_SESSION["$_nombre_carrito_$id_factura"][$unique]['nombre'] = $descripcion;
            return true;
        }

        return ['errors' => $this->array_errors];
    }

    public function aplicarNuevoIva(string $_nombre_carrito_, int $id_factura, $id_cliente, string $unique, int $id_iva, string $descuento_global)
    {
        $iva = $this->carritoModel->obtenerImpuesto($id_iva);

        if (!$iva) {
            $this->array_errors[] = 'IVA no disponible';
        } else {
            if (!isset($_SESSION["$_nombre_carrito_$id_factura"][$unique])) {
                $this->array_errors[] = 'Producto no disponible';
            } else {

                $descuento_global = convertir_a_float($descuento_global);

                $_SESSION["$_nombre_carrito_$id_factura"][$unique]['id_iva'] = $iva['imp_id'];
                $iva_total = $_SESSION["$_nombre_carrito_$id_factura"][$unique]['neto'] * ($iva['imp_valor'] / 100);

                if ($iva['imp_valor'] > 0) {
                    $_SESSION["$_nombre_carrito_$id_factura"][$unique]['iva']         = $iva['imp_valor'];
                    $_SESSION["$_nombre_carrito_$id_factura"][$unique]['iva_total']   = $iva_total;
                    $_SESSION["$_nombre_carrito_$id_factura"][$unique]['total']       = $_SESSION["$_nombre_carrito_$id_factura"][$unique]['neto'] + $iva_total;
                } else {
                    $_SESSION["$_nombre_carrito_$id_factura"][$unique]['iva']         = 0.00;
                    $_SESSION["$_nombre_carrito_$id_factura"][$unique]['iva_total']   = 0.00;
                    $_SESSION["$_nombre_carrito_$id_factura"][$unique]['total']       = $_SESSION["$_nombre_carrito_$id_factura"][$unique]['neto'];
                }

                return $this->obtenerCarritoCliente($_nombre_carrito_, $id_factura, $id_cliente, $descuento_global);
            }
        }

        return ['errors' => $this->array_errors];
    }

    public function aplicarDescuentoProducto(string $_nombre_carrito_, int $id_factura, int $id_cliente, string $unique, string $descuento, string $descuento_global)
    {
        if (!isset($_SESSION["$_nombre_carrito_$id_factura"][$unique])) {
            $this->array_errors[] = 'Producto no disponible';
        } else {
            $descuento = convertir_a_float($descuento);
            $descuento_global = convertir_a_float($descuento_global);
            $_SESSION["$_nombre_carrito_$id_factura"][$unique]['descuento'] = $descuento;
            $precio_total = $_SESSION["$_nombre_carrito_$id_factura"][$unique]['cantidad'] * $_SESSION["$_nombre_carrito_$id_factura"][$unique]['precio'];
            $precio = $this->obtenerDescuentoMasIvaProducto($precio_total, $_SESSION["$_nombre_carrito_$id_factura"][$unique]['iva'], 'pvp', $descuento);
            $_SESSION["$_nombre_carrito_$id_factura"][$unique]['iva_total']   = $precio['iva'];
            $_SESSION["$_nombre_carrito_$id_factura"][$unique]['neto']        = $precio['neto'];
            $_SESSION["$_nombre_carrito_$id_factura"][$unique]['total']       = $precio['total'];
            return $this->obtenerCarritoCliente($_nombre_carrito_, $id_factura, $id_cliente, $descuento_global);
        }

        return ['errors' => $this->array_errors];
    }

    public function aplicarDescuentoAdicional(string $_nombre_carrito_, int $id_factura, int $id_cliente, string $descuento_global)
    {
        $descuento = convertir_a_float($descuento_global);
        return $this->obtenerCarritoCliente($_nombre_carrito_, $id_factura, $id_cliente, $descuento);
    }

    public function eliminarProducto(string $_nombre_carrito_, string $tabla_db, int $id_factura, int $id_cliente, string $unique, string $descuento_global)
    {
        if (!isset($_SESSION["$_nombre_carrito_$id_factura"][$unique]))
            return ['errors' => ['Producto no disponible']];

        $descuento_global = convertir_a_float($descuento_global);
        $almacen = $this->carritoModel->obtenerAlmacen($_SESSION["$_nombre_carrito_$id_factura"][$unique]['id_almacen']);
        $cantidad_en_stock = $this->carritoModel->verificarProductoEnStock($_SESSION["$_nombre_carrito_$id_factura"][$unique]['id'], $almacen['alm_id']);
        $habia = $cantidad_en_stock['ps_cantidad'] ?? 0;
        $data_pro = $this->carritoModel->obtenerProducto($_SESSION["$_nombre_carrito_$id_factura"][$unique]['id']);

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

            if ($tabla_db == 'app_notas_de_entrega') {
                $det_prod = $this->carritoModel->obtenerProductoNe($id_factura, $_SESSION["$_nombre_carrito_$id_factura"][$unique]['id']);
                if ($det_prod) {
                    try {
                        $this->carritoModel->transactionBegin();
                        $this->carritoModel->eliminarProductoNe($id_factura, $det_prod['pro_id'], $_SESSION["$_nombre_carrito_$id_factura"][$unique]['cantidad']);
                        $this->carritoModel->transactionCommit();
                    } catch (\Throwable $th) {
                        $this->carritoModel->transactionRollBack();
                        $this->array_errors[] = 'Error al eliminar el producto';
                    }
                }
            } else if ($tabla_db == 'app_orden_de_entrega') {
                $det_prod = $this->carritoModel->obtenerProductoOr($id_factura, $_SESSION["$_nombre_carrito_$id_factura"][$unique]['id']);
                if ($det_prod) {
                    try {
                        $this->carritoModel->transactionBegin();
                        $planilla = $this->carritoModel->consultar("SELECT * FROM app_planilla_orden_de_entrega WHERE po_nid = $id_factura")->row();
                        if ($planilla) {

                            $data_servicio = $this->carritoModel->consultar("SELECT preserv_id, preserv_estatus
                            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 = {$det_prod['pro_id']}")->row();

                            if ($data_servicio['preserv_estatus'] == 0) {
                                $this->carritoModel->consultar("UPDATE app_preorden_master_servicios SET preserv_estatus = 2 WHERE preserv_id = {$data_servicio['preserv_id']}")->run();
                                $this->carritoModel->eliminarProductoOr($id_factura, $det_prod['pro_id'], $_SESSION["$_nombre_carrito_$id_factura"][$unique]['cantidad']);
                            } else {
                                $this->array_errors[] = 'El servicio no pude ser eliminado ya que se encuentra con estatus terminado en planilla';
                            }
                        } else {
                            $this->carritoModel->eliminarProductoOr($id_factura, $det_prod['pro_id'], $_SESSION["$_nombre_carrito_$id_factura"][$unique]['cantidad']);
                        }
                        $this->carritoModel->transactionCommit();
                    } catch (\Throwable $th) {
                        $this->carritoModel->transactionRollBack();
                        $this->array_errors[] = 'Error al eliminar el producto';
                    }
                }
            } else if ($tabla_db == 'app_factura_master') {
                $det_prod = $this->carritoModel->obtenerProductoFac($id_factura, $_SESSION["$_nombre_carrito_$id_factura"][$unique]['id']);
                if ($det_prod) {
                    try {
                        $this->carritoModel->transactionBegin();
                        $this->carritoModel->eliminarProductoFac($id_factura, $det_prod['pro_id'], $_SESSION["$_nombre_carrito_$id_factura"][$unique]['cantidad']);
                        $this->carritoModel->transactionCommit();
                    } catch (\Throwable $th) {
                        $this->carritoModel->transactionRollBack();
                        $this->array_errors[] = 'Error al eliminar el producto';
                    }
                }
            } else if ($tabla_db == 'app_pedidos') {
                $det_prod = $this->carritoModel->obtenerProductoPe($id_factura, $_SESSION["$_nombre_carrito_$id_factura"][$unique]['id']);
                if ($det_prod) {
                    try {
                        $this->carritoModel->transactionBegin();
                        $this->carritoModel->eliminarProductoPe($id_factura, $det_prod['pro_id'], $_SESSION["$_nombre_carrito_$id_factura"][$unique]['cantidad']);
                        $this->carritoModel->transactionCommit();
                    } catch (\Throwable $th) {
                        $this->carritoModel->transactionRollBack();
                        $this->array_errors[] = 'Error al eliminar el producto';
                    }
                }
            } else if ($tabla_db == 'app_presupuesto') {
                $det_prod = $this->carritoModel->obtenerProductoPre($id_factura, $_SESSION["$_nombre_carrito_$id_factura"][$unique]['id']);
                if ($det_prod) {
                    try {
                        $this->carritoModel->transactionBegin();
                        $this->carritoModel->eliminarProductoPre($id_factura, $det_prod['pro_id'], $_SESSION["$_nombre_carrito_$id_factura"][$unique]['cantidad']);
                        $this->carritoModel->transactionCommit();
                    } catch (\Throwable $th) {
                        $this->carritoModel->transactionRollBack();
                        $this->array_errors[] = 'Error al eliminar el producto';
                    }
                }
            }

            if (empty($this->array_errors)) {
                unset($_SESSION["$_nombre_carrito_$id_factura"][$unique]);
                return $this->obtenerCarritoCliente($_nombre_carrito_, $id_factura, $id_cliente, $descuento_global);
            }
        }
        if ($data_pro['pro_tipo'] == 2) {
            if ($tabla_db == 'app_notas_de_entrega') {
                $correlativo_fac = $this->carritoModel->obtenerCorrelativoNe($id_factura);
                $det_prod = $this->carritoModel->obtenerProductoNe($id_factura, $_SESSION["$_nombre_carrito_$id_factura"][$unique]['id']);
                if ($det_prod) {
                    if ($det_prod['descontado'] > 0) {
                        try {
                            $this->carritoModel->transactionBegin();

                            $productoCompuesto = new ProductosCompuestos();
                            $productos = $productoCompuesto->obtenerProductosCompuesto($det_prod['pro_id']);

                            if (is_countable($productos) && count($productos)) {
                                foreach ($productos as $row1) {
                                    $cant = convertir_a_float($det_prod['descontado'] * $row1['pro_cccant']);
                                    $this->carritoModel->restablecerStock($row1['pro_id'], $almacen['alm_id'], $cant);
                                }
                            }

                            $this->carritoModel->eliminarProductoNe($id_factura, $det_prod['pro_id'], $det_prod['descontado']);
                            $this->carritoModel->transactionCommit();
                        } catch (\Throwable $th) {
                            $this->carritoModel->transactionRollBack();
                            $this->array_errors[] = 'Error al eliminar el producto';
                        }
                        if (empty($this->array_errors)) {
                            $productoCompuesto = new ProductosCompuestos();
                            $productos = $productoCompuesto->obtenerProductosCompuesto($det_prod['pro_id']);

                            if (is_countable($productos) && count($productos)) {
                                foreach ($productos as $row1) {
                                    $cantidad_en_stock = $this->carritoModel->verificarProductoEnStock($row1['pro_id'], $almacen['alm_id']);
                                    $disp = convertir_a_float($cantidad_en_stock['ps_cantidad'] ?? 0);
                                    $cant = convertir_a_float($det_prod['descontado'] * $row1['pro_cccant']);
                                    Notifica::stock($row1['pro_id'], $almacen['alm_nombre'], 'ventas', $disp, $cant, 0, convertir_a_float($disp + $cant), $correlativo_fac['correlativo'], 1);
                                }
                            }
                        }
                    } else {
                        try {
                            $this->carritoModel->transactionBegin();
                            $this->carritoModel->eliminarProductoNe($id_factura, $det_prod['pro_id'], $_SESSION["$_nombre_carrito_$id_factura"][$unique]['cantidad']);
                            $this->carritoModel->transactionCommit();
                        } catch (\Throwable $th) {
                            $this->carritoModel->transactionRollBack();
                            $this->array_errors[] = 'Error al eliminar el producto';
                        }
                    }
                }
            } else if ($tabla_db == 'app_orden_de_entrega') {
                $correlativo_fac = $this->carritoModel->obtenerCorrelativoOrden($id_factura);
                $det_prod = $this->carritoModel->obtenerProductoOr($id_factura, $_SESSION["$_nombre_carrito_$id_factura"][$unique]['id']);
                if ($det_prod) {
                    if ($det_prod['descontado'] > 0) {
                        try {
                            $this->carritoModel->transactionBegin();

                            $productoCompuesto = new ProductosCompuestos();
                            $productos = $productoCompuesto->obtenerProductosCompuesto($det_prod['pro_id']);

                            if (is_countable($productos) && count($productos)) {
                                foreach ($productos as $row1) {
                                    $cant = convertir_a_float($det_prod['descontado'] * $row1['pro_cccant']);
                                    $this->carritoModel->restablecerStock($row1['pro_id'], $almacen['alm_id'], $cant);
                                }
                            }

                            $this->carritoModel->eliminarProductoOr($id_factura, $det_prod['pro_id'], $det_prod['descontado']);
                            $this->carritoModel->transactionCommit();
                        } catch (\Throwable $th) {
                            $this->carritoModel->transactionRollBack();
                            $this->array_errors[] = 'Error al eliminar el producto';
                        }
                        if (empty($this->array_errors)) {
                            $productoCompuesto = new ProductosCompuestos();
                            $productos = $productoCompuesto->obtenerProductosCompuesto($det_prod['pro_id']);

                            if (is_countable($productos) && count($productos)) {
                                foreach ($productos as $row1) {
                                    $cantidad_en_stock = $this->carritoModel->verificarProductoEnStock($row1['pro_id'], $almacen['alm_id']);
                                    $disp = convertir_a_float($cantidad_en_stock['ps_cantidad'] ?? 0);
                                    $cant = convertir_a_float($det_prod['descontado'] * $row1['pro_cccant']);
                                    Notifica::stock($row1['pro_id'], $almacen['alm_nombre'], 'ventas', $disp, $cant, 0, convertir_a_float($disp + $cant), $correlativo_fac['correlativo'], 12);
                                }
                            }
                        }
                    } else {
                        try {
                            $this->carritoModel->transactionBegin();
                            $this->carritoModel->eliminarProductoOr($id_factura, $det_prod['pro_id'], $_SESSION["$_nombre_carrito_$id_factura"][$unique]['cantidad']);
                            $this->carritoModel->transactionCommit();
                        } catch (\Throwable $th) {
                            $this->carritoModel->transactionRollBack();
                            $this->array_errors[] = 'Error al eliminar el producto';
                        }
                    }
                }
            } else if ($tabla_db == 'app_factura_master') {
                $correlativo_fac = $this->carritoModel->obtenerCorrelativoFac($id_factura);
                $det_prod = $this->carritoModel->obtenerProductoFac($id_factura, $_SESSION["$_nombre_carrito_$id_factura"][$unique]['id']);
                if ($det_prod) {
                    if ($det_prod['descontado'] > 0) {
                        try {
                            $this->carritoModel->transactionBegin();

                            $productoCompuesto = new ProductosCompuestos();
                            $productos = $productoCompuesto->obtenerProductosCompuesto($det_prod['pro_id']);

                            if (is_countable($productos) && count($productos)) {
                                foreach ($productos as $row1) {
                                    $cant = convertir_a_float($det_prod['descontado'] * $row1['pro_cccant']);
                                    $this->carritoModel->restablecerStock($row1['pro_id'], $almacen['alm_id'], $cant);
                                }
                            }

                            $this->carritoModel->eliminarProductoFac($id_factura, $det_prod['pro_id'], $det_prod['descontado']);
                            $this->carritoModel->transactionCommit();
                        } catch (\Throwable $th) {
                            $this->carritoModel->transactionRollBack();
                            $this->array_errors[] = 'Error al eliminar el producto';
                        }
                        if (empty($this->array_errors)) {
                            $productoCompuesto = new ProductosCompuestos();
                            $productos = $productoCompuesto->obtenerProductosCompuesto($det_prod['pro_id']);

                            if (is_countable($productos) && count($productos)) {
                                foreach ($productos as $row1) {
                                    $cantidad_en_stock = $this->carritoModel->verificarProductoEnStock($row1['pro_id'], $almacen['alm_id']);
                                    $disp = convertir_a_float($cantidad_en_stock['ps_cantidad'] ?? 0);
                                    $cant = convertir_a_float($det_prod['descontado'] * $row1['pro_cccant']);
                                    Notifica::stock($row1['pro_id'], $almacen['alm_nombre'], 'ventas', $disp, $cant, 0, convertir_a_float($disp + $cant), $correlativo_fac['correlativo'], 2);
                                }
                            }
                        }
                    } else {
                        try {
                            $this->carritoModel->transactionBegin();
                            $this->carritoModel->eliminarProductoFac($id_factura, $det_prod['pro_id'], $_SESSION["$_nombre_carrito_$id_factura"][$unique]['cantidad']);
                            $this->carritoModel->transactionCommit();
                        } catch (\Throwable $th) {
                            $this->carritoModel->transactionRollBack();
                            $this->array_errors[] = 'Error al eliminar el producto';
                        }
                    }
                }
            } else if ($tabla_db == 'app_pedidos') {
                $det_prod = $this->carritoModel->obtenerProductoPe($id_factura, $_SESSION["$_nombre_carrito_$id_factura"][$unique]['id']);
                if ($det_prod) {
                    try {
                        $this->carritoModel->transactionBegin();
                        $this->carritoModel->eliminarProductoPe($id_factura, $det_prod['pro_id'], $_SESSION["$_nombre_carrito_$id_factura"][$unique]['cantidad']);
                        $this->carritoModel->transactionCommit();
                    } catch (\Throwable $th) {
                        $this->carritoModel->transactionRollBack();
                        $this->array_errors[] = 'Error al eliminar el producto';
                    }
                }
            } else if ($tabla_db == 'app_presupuesto') {
                $det_prod = $this->carritoModel->obtenerProductoPre($id_factura, $_SESSION["$_nombre_carrito_$id_factura"][$unique]['id']);
                if ($det_prod) {
                    try {
                        $this->carritoModel->transactionBegin();
                        $this->carritoModel->eliminarProductoPre($id_factura, $det_prod['pro_id'], $_SESSION["$_nombre_carrito_$id_factura"][$unique]['cantidad']);
                        $this->carritoModel->transactionCommit();
                    } catch (\Throwable $th) {
                        $this->carritoModel->transactionRollBack();
                        $this->array_errors[] = 'Error al eliminar el producto';
                    }
                }
            }

            if (empty($this->array_errors)) {
                unset($_SESSION["$_nombre_carrito_$id_factura"][$unique]);
                return $this->obtenerCarritoCliente($_nombre_carrito_, $id_factura, $id_cliente, $descuento_global);
            }
        }
        if ($data_pro['pro_tipo'] == 1) {

            if ($tabla_db == 'app_notas_de_entrega') {
                $correlativo_fac = $this->carritoModel->obtenerCorrelativoNe($id_factura);
                $det_prod = $this->carritoModel->obtenerProductoNe($id_factura, $_SESSION["$_nombre_carrito_$id_factura"][$unique]['id']);
                if ($det_prod) {
                    if ($det_prod['descontado'] > 0) {
                        try {
                            $this->carritoModel->transactionBegin();
                            $this->carritoModel->restablecerStock($det_prod['pro_id'], $almacen['alm_id'], $det_prod['descontado']);
                            $this->carritoModel->eliminarProductoNe($id_factura, $det_prod['pro_id'], $det_prod['descontado']);
                            $this->carritoModel->transactionCommit();
                        } catch (\Throwable $th) {
                            $this->carritoModel->transactionRollBack();
                            $this->array_errors[] = 'Error al eliminar el producto';
                        }
                        if (empty($this->array_errors)) {
                            Notifica::stock($det_prod['pro_id'], $almacen['alm_nombre'], 'ventas', $habia, $det_prod['descontado'], 0, $habia + $det_prod['descontado'], $correlativo_fac['correlativo'], 1);
                        }
                    } else {
                        try {
                            $this->carritoModel->transactionBegin();
                            $this->carritoModel->eliminarProductoNe($id_factura, $det_prod['pro_id'], $_SESSION["$_nombre_carrito_$id_factura"][$unique]['cantidad']);
                            $this->carritoModel->transactionCommit();
                        } catch (\Throwable $th) {
                            $this->carritoModel->transactionRollBack();
                            $this->array_errors[] = 'Error al eliminar el producto';
                        }
                    }
                }
            } else if ($tabla_db == 'app_orden_de_entrega') {
                $correlativo_fac = $this->carritoModel->obtenerCorrelativoOrden($id_factura);
                $det_prod = $this->carritoModel->obtenerProductoOr($id_factura, $_SESSION["$_nombre_carrito_$id_factura"][$unique]['id']);
                if ($det_prod) {
                    if ($det_prod['descontado'] > 0) {
                        try {
                            $this->carritoModel->transactionBegin();
                            $this->carritoModel->restablecerStock($det_prod['pro_id'], $almacen['alm_id'], $det_prod['descontado']);
                            $this->carritoModel->eliminarProductoOr($id_factura, $det_prod['pro_id'], $det_prod['descontado']);
                            $this->carritoModel->transactionCommit();
                        } catch (\Throwable $th) {
                            $this->carritoModel->transactionRollBack();
                            $this->array_errors[] = 'Error al eliminar el producto';
                        }
                        if (empty($this->array_errors)) {
                            Notifica::stock($det_prod['pro_id'], $almacen['alm_nombre'], 'ventas', $habia, $det_prod['descontado'], 0, $habia + $det_prod['descontado'], $correlativo_fac['correlativo'], 12);
                        }
                    } else {
                        try {
                            $this->carritoModel->transactionBegin();
                            $this->carritoModel->eliminarProductoOr($id_factura, $det_prod['pro_id'], $_SESSION["$_nombre_carrito_$id_factura"][$unique]['cantidad']);
                            $this->carritoModel->transactionCommit();
                        } catch (\Throwable $th) {
                            $this->carritoModel->transactionRollBack();
                            $this->array_errors[] = 'Error al eliminar el producto';
                        }
                    }
                }
            } else if ($tabla_db == 'app_factura_master') {
                $correlativo_fac = $this->carritoModel->obtenerCorrelativoFac($id_factura);
                $det_prod = $this->carritoModel->obtenerProductoFac($id_factura, $_SESSION["$_nombre_carrito_$id_factura"][$unique]['id']);
                if ($det_prod) {
                    if ($det_prod['descontado'] > 0) {
                        try {
                            $this->carritoModel->transactionBegin();
                            $this->carritoModel->restablecerStock($det_prod['pro_id'], $almacen['alm_id'], $det_prod['descontado']);
                            $this->carritoModel->eliminarProductoFac($id_factura, $det_prod['pro_id'], $det_prod['descontado']);
                            $this->carritoModel->transactionCommit();
                        } catch (\Throwable $th) {
                            $this->carritoModel->transactionRollBack();
                            $this->array_errors[] = 'Error al eliminar el producto';
                        }
                        if (empty($this->array_errors)) {
                            Notifica::stock($det_prod['pro_id'], $almacen['alm_nombre'], 'ventas', $habia, $det_prod['descontado'], 0, $habia + $det_prod['descontado'], $correlativo_fac['correlativo'], 2);
                        }
                    } else {
                        try {
                            $this->carritoModel->transactionBegin();
                            $this->carritoModel->eliminarProductoFac($id_factura, $det_prod['pro_id'], $_SESSION["$_nombre_carrito_$id_factura"][$unique]['cantidad']);
                            $this->carritoModel->transactionCommit();
                        } catch (\Throwable $th) {
                            $this->carritoModel->transactionRollBack();
                            $this->array_errors[] = 'Error al eliminar el producto';
                        }
                    }
                }
            } else if ($tabla_db == 'app_pedidos') {
                $det_prod = $this->carritoModel->obtenerProductoPe($id_factura, $_SESSION["$_nombre_carrito_$id_factura"][$unique]['id']);
                if ($det_prod) {
                    try {
                        $this->carritoModel->transactionBegin();
                        $this->carritoModel->eliminarProductoPe($id_factura, $det_prod['pro_id'], $_SESSION["$_nombre_carrito_$id_factura"][$unique]['cantidad']);
                        $this->carritoModel->transactionCommit();
                    } catch (\Throwable $th) {
                        $this->carritoModel->transactionRollBack();
                        $this->array_errors[] = 'Error al eliminar el producto';
                    }
                }
            } else if ($tabla_db == 'app_presupuesto') {
                $det_prod = $this->carritoModel->obtenerProductoPre($id_factura, $_SESSION["$_nombre_carrito_$id_factura"][$unique]['id']);
                if ($det_prod) {
                    try {
                        $this->carritoModel->transactionBegin();
                        $this->carritoModel->eliminarProductoPre($id_factura, $det_prod['pro_id'], $_SESSION["$_nombre_carrito_$id_factura"][$unique]['cantidad']);
                        $this->carritoModel->transactionCommit();
                    } catch (\Throwable $th) {
                        $this->carritoModel->transactionRollBack();
                        $this->array_errors[] = 'Error al eliminar el producto';
                    }
                }
            }

            if (empty($this->array_errors)) {
                unset($_SESSION["$_nombre_carrito_$id_factura"][$unique]);
                return $this->obtenerCarritoCliente($_nombre_carrito_, $id_factura, $id_cliente, $descuento_global);
            }
        }

        return ['errors' => $this->array_errors];
    }

    public function pagar(string $tabla_db, string $monto, int $id_divisa, int $id_factura, bool $generar_credito, int $id_cuenta_metodo, int $id_metodo_divisa, bool $compra_dolares = false, array $cuenta_pagoDol = [], string $referencia = '', bool $cambiar_estatus = true, string $fact = '')
    {
        if ($tabla_db == 'app_notas_de_entrega') {
            $tipo_doc = 1;
            $tipo_doc_a = 'NEV';
            $tipo_doc_descripcion = 'Notas de entrega';
            $status = ['ne_estatus' => 1];
            $id_tabla = 'ne_id';
            $factura = $this->carritoModel->obtenerNe($id_factura);
        } else if ($tabla_db == 'app_factura_master') {
            $tipo_doc = 2;
            $tipo_doc_a = 'FACV';
            $tipo_doc_descripcion = 'Factura';
            $status = ['fm_estatus' => 1];
            $id_tabla = 'fm_id';
            $factura = $this->carritoModel->obtenerFac($id_factura);
        } else {
            $d_ = $this->carritoModel->obtenerDocumento(12);
            $tipo_doc = 12;
            $tipo_doc_a = $d_['doc_prefijo'];
            $tipo_doc_descripcion = $d_['doc_descripcion'];
            $status = ['n_estatus' => 1];
            $id_tabla = 'n_id';
            $factura = $this->carritoModel->obtenerOrdenE($id_factura);
        }

        $modulo = new Module();

        $permiso_factor = $modulo->has_module_action_permission('facturacion', 'cambiar_factor', $_SESSION['user_data']['emp_id']);

        if ($factura) {

            $monto = convertir_a_float($monto);

            if ($monto <= 0) {
                $this->array_errors[] = 'EL campo monto no puede ser 0';
            } else {

                if ($factura['total'] == 0) {
                    Http::json_response(['errors' => ['Total de documento invalido']]);
                }

                $array_abonos = [];
                $factor_factura = 1;
                $factor_master  = 1;
                $total_credito = 0;
                $total_credito_conversion = 0;
                $total_comprar = 0;
                $total_compra_conversion = 0;
                $pagado = false;

                $divisa     = $this->carritoModel->obtenerDivisa($id_divisa);
                $cliente    = $this->carritoModel->obtenerCliente($factura['id_cliente']);

                if ($this->divisa_master['id'] != $divisa['div_id']) {
                    $data_factor = $this->carritoModel->obtenerDivisaAlCambio($this->divisa_master['id'], $id_divisa);
                    if (!$data_factor) {
                        $this->array_errors[] = 'No se encuentra el factor de conversion entre la divisa predeterminada y la divisa a pagar';
                    } else {
                        $factor_master = $data_factor['df_factor'];
                        if ($id_divisa == 1) {
                            $factor_master = ($permiso_factor) ? $fact : $data_factor['df_factor'];
                        }
                    }
                }

                if ($factura['id_divisa'] != $divisa['div_id']) {
                    $data_factor_factura = $this->carritoModel->obtenerDivisaAlCambio($factura['id_divisa'], $id_divisa);
                    if (!$data_factor_factura) {
                        $this->array_errors[] = 'No se encuentra el factor de conversion entre la divisa de la factura y la divisa a pagar';
                    } else {
                        $factor_factura = $data_factor_factura['df_factor'];
                        if ($id_divisa == 1) {
                            $factor_factura = ($permiso_factor) ? $fact : $data_factor_factura['df_factor'];
                        }
                    }
                }

                $total_pagos = $this->carritoModel->totalPagos($id_factura, $tipo_doc, 1);

                if ((round($total_pagos['total'] ?? 0, 2) >= round($factura['total'], 2))) {
                    $this->array_errors[] = 'EL documento ha sido pagado en su totalidad';
                } else {

                    $conversion = $monto / $factor_factura;
                    $restante = $factura['total'] - $total_pagos['total'];
                    $totalcp = 0;
                    $tcmcp = 0;
                    $conversioncp = 0;

                    if ($generar_credito) {

                        $total_credito = round($conversion, 2) - round($restante, 2);

                        //CREDITO SIEMPRE CONVERTIR A DIVISA MASTER
                        if ($factura['id_divisa'] != $this->divisa_master['id']) {
                            $data_factor = $this->carritoModel->obtenerDivisaAlCambio($factura['id_divisa'], $this->divisa_master['id']);
                            if (!$data_factor) {
                                $this->array_errors[] = 'No se encuentra el factor de conversion entre la divisa de la factura y la divisa predeterminada';
                            } else {
                                $factor_credito_master = $data_factor['df_factor'];
                            }
                            $total_credito *= $factor_credito_master;
                        }

                        if ($divisa['div_id'] != $this->divisa_master['id']) {
                            $data_factor = $this->carritoModel->obtenerDivisaAlCambio($divisa['div_id'], $this->divisa_master['id']);
                            if (!$data_factor) {
                                $this->array_errors[] = 'No se encuentra el factor de conversion entre la divisa de pago y la divisa master';
                            } else {
                                $factor_credito_conv = $data_factor['df_factor'];
                            }
                            $total_credito_conversion = $total_credito / $factor_credito_conv;
                        } else {
                            $total_credito_conversion = $total_credito;
                        }

                        if ($total_credito > 0) {
                            if ($factura['id_divisa'] != $divisa['div_id']) {
                                $restante *= $factor_factura;
                                $monto = $restante;
                                $conversion = $restante / $factor_factura;
                            } else {
                                $monto = $restante;
                                $conversion = $monto;
                            }
                        }
                    } else {
                        if ($compra_dolares) {
                            $total_comprar = round($conversion, 2) - round($restante, 2);

                            //CREDITO SIEMPRE CONVERTIR A DIVISA MASTER
                            if ($factura['id_divisa'] != $this->divisa_master['id']) {
                                $data_factor = $this->carritoModel->obtenerDivisaAlCambio($factura['id_divisa'], $this->divisa_master['id']);
                                if (!$data_factor) {
                                    $this->array_errors[] = 'No se encuentra el factor de conversion entre la divisa de la factura y la divisa predeterminada';
                                } else {
                                    $factor_credito_master = $data_factor['df_factor'];
                                }
                                $total_comprar *= $factor_credito_master;
                            }

                            if ($divisa['div_id'] != $this->divisa_master['id']) {
                                $data_factor = $this->carritoModel->obtenerDivisaAlCambio($divisa['div_id'], $this->divisa_master['id']);
                                if (!$data_factor) {
                                    $this->array_errors[] = 'No se encuentra el factor de conversion entre la divisa de pago y la divisa master';
                                } else {
                                    $factor_credito_conv = $data_factor['df_factor'];
                                }
                                $total_compra_conversion = $total_credito / $factor_credito_conv;
                            } else {
                                $total_compra_conversion = $total_comprar;
                            }

                            if ($total_comprar > 0) {
                                if ($factura['id_divisa'] != $divisa['div_id']) {
                                    $restante *= $factor_factura;
                                    $monto = $restante;
                                    $conversion = $restante / $factor_factura;
                                } else {
                                    $monto = $restante;
                                    $conversion = $monto;
                                }
                            }

                            $montob = 0;
                            $data_factorcp = $this->carritoModel->obtenerDivisaAlCambio(2, 1);
                            $factorcp = $data_factorcp['df_factor'];
                            $tt = round($total_comprar * $factorcp, 2);

                            $b = 0;
                            foreach ($cuenta_pagoDol as $row) {
                                $cuentab = $this->carritoModel->consultar("SELECT cmp_saldo, cmp_cueid FROM app_cuentas_metodopago WHERE cmp_id = {$row['id']}")->row();
                                $saldob = $this->carritoModel->consultar("SELECT bc_saldo,bc_alias FROM app_bancos_cuentas WHERE bc_id = {$cuentab['cmp_cueid']}")->row();

                                $montob += convertir_a_float($row['valor']);
                                $conversioncp += round($montob);
                            }

                            if ($montob > round($saldob['bc_saldo'], 2) && $tt == $montob) {
                                $this->array_errors[] = 'Saldo insuficiente para realizar una compra de divisa en la cuenta ' . $saldob['bc_alias'];
                            } else {
                                if ($montob > $tt) {
                                    $this->array_errors[] = 'El monto a pagar para realizar la compra de divisa es mayor.';
                                }
                                if ($montob < $tt) {
                                    $this->array_errors[] = 'El monto a pagar para realizar la compra de divisa es menor.';
                                }
                            }
                        } else {
                            if (round($conversion, 2)  > round($restante, 2)) {
                                $this->array_errors[] = 'El monto supera la cantidad restante por pagar';
                            }
                        }
                    }
                }
            }

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

                $cuenta     = $this->carritoModel->consultar("SELECT cmp_saldo, cmp_cueid FROM app_cuentas_metodopago WHERE cmp_id = $id_cuenta_metodo")->row();
                $saldo      = $this->carritoModel->consultar("SELECT bc_saldo FROM app_bancos_cuentas WHERE bc_id = {$cuenta['cmp_cueid']}")->row();

                try {

                    $this->carritoModel->transactionBegin();

                    $this->carritoModel->guardar([
                        'fab_idgenerico'        => $factura['id'],
                        'fab_doc'               => $tipo_doc,
                        'fab_divisa'            => $divisa['div_id'],
                        'fab_metodo'            => $id_metodo_divisa,
                        'fab_cmpid'             => $id_cuenta_metodo,
                        'fab_monto'             => $monto,
                        'fab_factor'            => $factor_factura,
                        'fab_conversion'        => $conversion,
                        'fab_divid_conversion'  => $factura['id_divisa'],
                        'fab_factor_master'     => $factor_master,
                        'fab_empid'             => $_SESSION['user_data']['emp_id'],
                        'fab_modulo'            => $tipo_doc_descripcion,
                        'fab_descripcion'       => ($referencia != '') ? 'Referencia: ' . $referencia : '',
                        'fab_observacion'       => "Pago $tipo_doc_a # {$factura['correlativo']} {$cliente['cli_razon_social']}  Monto: " . Moneda::moneda($monto, $divisa['div_locale'], $divisa['div_simbolo']),
                        'fab_saldo_anterior'    => $saldo['bc_saldo'],
                        'fab_categoria'         => 1,
                        'fab_sucursal'         => $factura['sucursal']
                    ], true, 'app_movimientos');

                    $this->carritoModel->consultar("UPDATE app_bancos_cuentas SET bc_saldo =  bc_saldo + $monto WHERE bc_id={$cuenta['cmp_cueid']}")->run();
                    $this->carritoModel->consultar("UPDATE app_cuentas_metodopago SET cmp_saldo = cmp_saldo + $monto WHERE cmp_id = $id_cuenta_metodo")->run();

                    if ($total_comprar > 0 && $compra_dolares) {

                        $saldo = $this->carritoModel->consultar("SELECT bc_saldo FROM app_bancos_cuentas WHERE bc_id = {$cuenta['cmp_cueid']}")->row();

                        foreach ($cuenta_pagoDol as $row) {
                            $cuentab = $this->carritoModel->consultar("SELECT cmp_saldo, cmp_cueid FROM app_cuentas_metodopago WHERE cmp_id = {$row['id']}")->row();
                            $saldob = $this->carritoModel->consultar("SELECT bc_saldo FROM app_bancos_cuentas WHERE bc_id = {$cuentab['cmp_cueid']}")->row();
                            $divisab = $this->carritoModel->obtenerDivisa(1);

                            $data_factorcp = $this->carritoModel->obtenerDivisaAlCambio(2, 1);
                            $factorcp = $data_factorcp['df_factor'];

                            $montob = convertir_a_float($row['valor']);
                            $conversioncp = convertir_a_float($montob / $factorcp);


                            $this->carritoModel->guardar([
                                'fab_idgenerico'        => $factura['id'],
                                'fab_doc'               => $tipo_doc,
                                'fab_divisa'            => $divisab['div_id'],
                                'fab_metodo'            => 4,
                                'fab_cmpid'             => $row['id'],
                                'fab_monto'             => $montob * -1,
                                'fab_factor'            => $factorcp,
                                'fab_conversion'        => $conversioncp * -1,
                                'fab_divid_conversion'  => $divisab['div_id'],
                                'fab_factor_master'     => $factorcp,
                                'fab_empid'                => $_SESSION['user_data']['emp_id'],
                                'fab_modulo'            => 'venta',
                                'fab_descripcion'       => "Pago movil por compra divisa",
                                'fab_observacion'       => 'Egreso por compra de divisa por el monto en $' . $total_comprar . ' =' . Moneda::moneda($montob, $divisab['div_locale'], $divisab['div_simbolo'])  . ' del documento ' . $tipo_doc_a . " # {$factura['correlativo']} {$cliente['cli_razon_social']}",
                                'fab_categoria'         => 10,
                                'fab_saldo_anterior'    => $saldob['bc_saldo']
                            ], true, 'app_movimientos');

                            $this->carritoModel->consultar("UPDATE app_bancos_cuentas SET bc_saldo =  bc_saldo - $montob WHERE bc_id={$cuentab['cmp_cueid']}")->run();
                            $this->carritoModel->consultar("UPDATE app_cuentas_metodopago SET cmp_saldo = cmp_saldo - $montob WHERE cmp_id = {$row['id']}")->run();

                            //gpg sms

                            $sms_cliente    = $this->carritoModel->obtenerCliente($factura['id']);
                            $newSMS = new SMS(constant('SMS_USER'), constant('SMS_PASSWORD'));
                            $tele = str_replace('(', '', $cliente['cli_telefono']);
                            $tele = str_replace(')', '', $tele);
                            $tele = str_replace(' ', '', $tele);
                            $tele = str_replace('-', '', $tele);
                            $newSMS->enviarMensaje($tele, 'TECHNET Pago Movil  monto: ' . $montob . 'bs   Referencia: ' . $referencia);
                        }

                        $this->carritoModel->guardar([
                            'fab_idgenerico'        => $factura['id'],
                            'fab_doc'               => $tipo_doc,
                            'fab_divisa'            => $divisa['div_id'],
                            'fab_metodo'            => $id_metodo_divisa,
                            'fab_cmpid'             => $id_cuenta_metodo,
                            'fab_monto'             => $total_compra_conversion,
                            'fab_factor'            =>  $factor_factura,
                            'fab_conversion'        => $total_comprar,
                            'fab_divid_conversion'  => $factura['id_divisa'],
                            'fab_factor_master'     => $factor_master,
                            'fab_empid'             => $_SESSION['user_data']['emp_id'],
                            'fab_modulo'            => 'venta',
                            'fab_descripcion'       => "Pago movil por compra divisa",
                            'fab_observacion'       => 'Ingreso por compra de divisa por el monto de ' . Moneda::moneda($total_comprar, $divisa['div_locale'], $divisa['div_simbolo'])  . ' del documento ' . $tipo_doc_a . " # {$factura['correlativo']} {$cliente['cli_razon_social']}",
                            'fab_categoria'         => 10,
                            'fab_saldo_anterior'    => $saldo['bc_saldo']
                        ], true, 'app_movimientos');

                        $this->carritoModel->consultar("UPDATE app_bancos_cuentas SET bc_saldo =  bc_saldo + $total_comprar WHERE bc_id={$cuenta['cmp_cueid']}")->run();
                        $this->carritoModel->consultar("UPDATE app_cuentas_metodopago SET cmp_saldo = cmp_saldo + $total_comprar WHERE cmp_id = $id_cuenta_metodo")->run();
                    }

                    if ($total_credito > 0) {

                        $correlativo = $this->carritoModel->consultar("SELECT * FROM app_correlativos WHERE cor_serid = {$factura['id_serie']} AND cor_docid = 7")->row();
                        $saldo = $this->carritoModel->consultar("SELECT bc_saldo FROM app_bancos_cuentas WHERE bc_id = {$cuenta['cmp_cueid']}")->row();

                        $id_credito = $this->carritoModel->guardar([
                            'cre_cliid'         => $cliente['cli_id'],
                            'cre_facid'         => $factura['id'],
                            'cre_docid'         => $tipo_doc,
                            'cre_empleado'      => $_SESSION['user_data']['emp_id'],
                            'cre_modulo'        => $tipo_doc_descripcion,
                            'cre_correlativo'   => $correlativo['cor_correlativo'] + 1,
                            'cre_monto'         => $total_credito,
                            'cre_surcid'        => $factura['sucursal']
                        ], false, 'app_nota_de_credito');

                        $this->carritoModel->actualizarCorrelativo($factura['id_serie'], 7);

                        $this->carritoModel->guardar([
                            'fab_idgenerico'        => $id_credito,
                            'fab_doc'               => 7,
                            'fab_divisa'            => $divisa['div_id'],
                            'fab_metodo'            => $id_metodo_divisa,
                            'fab_cmpid'             => $id_cuenta_metodo,
                            'fab_monto'             => $total_credito_conversion,
                            'fab_conversion'        => $total_credito,
                            'fab_divid_conversion'  => $factura['id_divisa'],
                            'fab_retiro'            => 0,
                            'fab_factor_master'     => $factor_master,
                            'fab_factor'            => $factor_factura,
                            'fab_empid'             => $_SESSION['user_data']['emp_id'],
                            'fab_modulo'            => $tipo_doc_descripcion,
                            'fab_descripcion'       => '',
                            'fab_observacion'       => "Credito $tipo_doc_a #$id_factura {$cliente['cli_razon_social']} Monto: " . Moneda::moneda($total_credito_conversion, $divisa['div_locale'], $divisa['div_simbolo']),
                            'fab_credito'           => 1,
                            'fab_categoria'         => 1,
                            'fab_saldo_anterior'    => $saldo['bc_saldo'],
                            'fab_sucursal'         =>  $factura['sucursal'],
                        ], true, 'app_movimientos');

                        $this->carritoModel->consultar("UPDATE app_bancos_cuentas SET bc_saldo =  bc_saldo + $total_credito_conversion WHERE bc_id={$cuenta['cmp_cueid']}")->run();
                        $this->carritoModel->consultar("UPDATE app_cuentas_metodopago SET cmp_saldo = cmp_saldo + $total_credito_conversion WHERE cmp_id = $id_cuenta_metodo")->run();
                    }

                    $total_pagos = $this->carritoModel->totalPagos($id_factura, $tipo_doc, 1);

                    if ((round($total_pagos['total'] ?? 0, 2) >= round($factura['total'], 2))) {

                        if ($tabla_db == 'app_factura_master' || $tabla_db == 'app_notas_de_entrega') {
                            $this->carritoModel->editar($id_factura, $status, $tabla_db, $id_tabla);
                            $pagado = true;
                        } else {
                            if ($cambiar_estatus) {
                                $preorden_presupuest = $this->carritoModel->consultar("SELECT * FROM app_planilla_orden_de_entrega WHERE po_nid=$id_factura")->row();
                                if ($preorden_presupuest) {
                                    $newOrden = new PlanillaPreOrden();

                                    $servicios = $this->carritoModel->consultar("SELECT count(preserv_id) as total FROM app_preorden_master_servicios WHERE preserv_preid = {$preorden_presupuest['po_preid']} AND preserv_estatus = 0")->row();
                                    $preorden = $this->carritoModel->consultar("SELECT * FROM app_preorden_master WHERE pre_id={$preorden_presupuest['po_preid']}")->row();

                                    if ($servicios['total'] == 0) {
                                        $newOrden->editar($preorden_presupuest['po_preid'], [
                                            'pre_estatus' => 2
                                        ], 'app_preorden_master');
                                    } else {
                                        $newOrden->editar($preorden_presupuest['po_preid'], [
                                            'pre_estatus' => 1
                                        ], 'app_preorden_master');
                                    }

                                    $this->carritoModel->editar($id_factura, $status, $tabla_db, $id_tabla);
                                    $pagado = true;
                                }
                            }
                        }
                    } else {
                        if ($tabla_db != 'app_factura_master' || $tabla_db != 'app_notas_de_entrega') {

                            $newOrden = new PlanillaPreOrden();
                            $preorden_presupuest = $this->carritoModel->consultar("SELECT * FROM app_planilla_orden_de_entrega WHERE po_nid=$id_factura")->row();

                            if ($preorden_presupuest) {
                                $servicios = $this->carritoModel->consultar("SELECT count(preserv_id) as total FROM app_preorden_master_servicios WHERE preserv_preid = {$preorden_presupuest['po_preid']} AND preserv_estatus = 0")->row();

                                $preorden = $this->carritoModel->consultar("SELECT * FROM app_preorden_master WHERE pre_id={$preorden_presupuest['po_preid']}")->row();

                                if ($servicios['total'] == 0) {
                                    if (!$preorden_presupuest['po_preid'] == 5) {
                                        $newOrden->editar($preorden_presupuest['po_preid'], [
                                            'pre_estatus' => 2
                                        ], 'app_preorden_master');
                                    }
                                } else {
                                    if (!$preorden_presupuest['po_preid'] == 5) {
                                        $newOrden->editar($preorden_presupuest['po_preid'], [
                                            'pre_estatus' => 1
                                        ], 'app_preorden_master');
                                    }
                                }
                            }
                        }
                    }

                    $this->carritoModel->transactionCommit();
                } catch (\Throwable $th) {
                    $this->carritoModel->transactionRollBack();
                    $this->array_errors[] = 'Error en transacción' . $th;
                }

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

                    $total_pagos = $this->carritoModel->totalPagos($factura['id'], $tipo_doc, 1);

                    if ($tabla_db == 'app_factura_master') {
                        $abonos = $this->carritoModel->abonosFac($factura['id']);
                    } else if ($tabla_db == 'app_notas_de_entrega') {
                        $abonos = $this->carritoModel->abonosNe($factura['id']);
                    } else {
                        $abonos = $this->carritoModel->abonosOrden($factura['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 = Moneda::obtenerDivisa($row['fab_divisa']);
                            }

                            if (is_null($row['fab_divid_conversion'])) {
                                $divisa_conv_mov = $this->divisa_master;
                            } else {
                                $divisa_conv_mov = Moneda::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'],
                                'referencia'        => $row['fab_descripcion'],
                                'fab_monto'         => Moneda::moneda($row['fab_monto'], $divisa_mov['locale'], $divisa_mov['symbol']),
                                'fab_factor'        => ($row['fab_factor'] < 1) ? $row['fab_factor'] : Moneda::decimal($row['fab_factor'], $this->divisa_master['locale']),
                                'fab_conversion'    => Moneda::moneda($row['fab_conversion'], $divisa_conv_mov['locale'], $divisa_conv_mov['symbol']),
                                'credito'           => $row['fab_credito']
                            ];
                        }
                    }

                    return [
                        'abonos'        => $array_abonos,
                        'total_factura' => round($factura['total'], 2),
                        'pagado'        => $pagado,
                        'restante'      => round(($factura['total'] - $total_pagos['total']), 2),
                        'total_pagado'  => round($total_pagos['total'], 2),
                        'pago_movil'    => $this->carritoModel->obtenerBalanceComprarDolares($id_factura, $tipo_doc),
                    ];
                }
            }
        } else {
            $this->array_errors[] = 'Acción prohibida';
        }

        return ['errors' => $this->array_errors];
    }

    public function enviarDocumento(string $tabla_db, int $id_factura, $file, string $descripcion)
    {
        $fileTmpPath    = $file['documento']['tmp_name'];
        $fileName       = $file['documento']['name'];
        $fileSize       = $file['documento']['size'];
        $extenciones    = ['jpg', 'jpeg', 'png', 'pdf'];

        if ($file['documento']['error'] === UPLOAD_ERR_OK) {

            $fileNameCmps   = explode(".", basename($file['documento']['name']));
            $fileExtension  = strtolower(end($fileNameCmps));
            $newFileName    = md5(time() . $fileName) . '.' . $fileExtension;

            if ($tabla_db == 'app_pedidos') {
                $dest_path = constant('UPLOADS_URI') . 'documentos_ventas/pedidos/' . $newFileName;
                $tabla = 'app_pedidos_documentos';
                $data_form = [
                    'pedoc_peid'        => $id_factura,
                    'pedoc_descripcion' => $descripcion,
                    'pedoc_documento'   => $newFileName
                ];
            } else if ($tabla_db == 'app_notas_de_entrega') {
                $dest_path = constant('UPLOADS_URI') . 'documentos_ventas/notas_de_entrega/' . $newFileName;
                $tabla = 'app_notas_de_entrega_documentos';
                $data_form = [
                    'nedoc_neid'        => $id_factura,
                    'nedoc_descripcion' => $descripcion,
                    'nedoc_documento'   => $newFileName
                ];
            } else if ($tabla_db == 'app_factura_master') {
                $dest_path = constant('UPLOADS_URI') . 'documentos_ventas/facturas/' . $newFileName;
                $tabla = 'app_factura_documentos';
                $data_form = [
                    'facdoc_facid'          => $id_factura,
                    'facdoc_descripcion'    => $descripcion,
                    'facdoc_documento'      => $newFileName
                ];
            } else if ($tabla_db == 'app_presupuesto') {
                $dest_path = constant('UPLOADS_URI') . 'documentos_ventas/presupuestos/' . $newFileName;
                $tabla = 'app_presupuesto_documentos';
                $data_form = [
                    'predoc_preid'          => $id_factura,
                    'predoc_descripcion'    => $descripcion,
                    'predoc_documento'      => $newFileName
                ];
            } else if ($tabla_db == 'app_orden_de_entrega') {
                $dest_path = constant('UPLOADS_URI') . 'documentos_ventas/ordendeentrega/' . $newFileName;
                $tabla = 'app_orden_de_entrega_documentos';
                $data_form = [
                    'ndoc_nid'          => $id_factura,
                    'ndoc_descripcion'  => $descripcion,
                    'ndoc_documento'    => $newFileName
                ];
            }

            if ($fileSize < 1000000) {
                if (in_array($fileExtension, $extenciones)) {
                    if (move_uploaded_file($fileTmpPath, $dest_path)) {
                        if ($this->carritoModel->guardar($data_form, true, $tabla)) {
                            return true;
                        } else {
                            unlink($dest_path);
                            $this->array_errors[] = 'Se produjo un error al intentar guardar el archivo';
                        }
                    } else {
                        $this->array_errors[] = 'Se produjo un error al cargar el archivo';
                    }
                } else {
                    $this->array_errors[] = 'Solo archivos con formato PDF, PNG o JPG';
                }
            } else {
                $this->array_errors[] = 'EL archivo supera el limite de 1MB';
            }
        } else {
            $this->array_errors[] = 'Se produjo un error al cargar el archivo';
        }

        return ['errors' => $this->array_errors];
    }

    private function fiscal(int $id_factura, int $limite, int $redondear)
    {
        $factura    = $this->carritoModel->obtenerFac($id_factura);
        $articulos  = $this->carritoModel->obtenerFacArticulos($factura['id']);
        $cliente    = $this->carritoModel->obtenerCliente($factura['id_cliente']);
        $cajero     = $this->carritoModel->obtenerCajero($factura['id_empleado']);
        $abonos     = $this->carritoModel->abonosPositvos($factura['id']);
        $divisa_facturar = Moneda::facturarPredeterminada();
        $items      = [];
        $pay        = [];
        $mayor = 0;
        //        if ($factura['estatus'] == 1) {

        foreach ($articulos as $articulo) {

            $data_producto = $this->carritoModel->consultar("SELECT pro_nombrecorto FROM app_productos WHERE pro_id = {$articulo['id_producto']}")->row();

            if ($articulo['id_iva'] == 2) {
                $tasa = 'Exento';
            } else {
                $tasa = 'General';
            }

            $string = float_a_string($articulo['precio']);
            $numero = number_format($string, 2);
            $numero = str_replace('.', '', $numero);
            $numero = str_replace(',', '', $numero);
            //$numero = $articulo['precio'];

            if ($redondear == 1) {
                $numero = round($numero);
            }

            $items[] = [
                'producto'  => empty($data_producto['pro_nombrecorto']) ? $articulo['nombre'] : $data_producto['pro_nombrecorto'],
                'precio'    => float_a_string($numero),
                'cantidad'  => $articulo['cantidad'],
                'tasa'      => $tasa
            ];
            if ($numero > $limite) {
                $mayor = 1;
            }
        }
        if ($mayor == 0) {
            $convertido = $this->carritoModel->rutaDocumento($id_factura, 2);

            $desc1 = '';
            $desc2 = '';
            if ($convertido) {

                if ($convertido['rd_docid_procedencia'] == 1) {

                    $total = $this->carritoModel->obtenerNe($convertido['rd_facid_procedencia']);

                    if ($divisa_facturar['id'] != $total['id_divisa']) {
                        if ($this->carritoModel->obtenerDivisaAlCambio($total['id_divisa'], $divisa_facturar['id'])) {
                            $monto = $this->obtenerPrecioSegunDivisa($total['total'], $total['id_divisa'], $divisa_facturar['id']);
                            $total['total'] = $monto['precio'];
                        } else {
                            $this->array_errors[] = 'Lo siento no se encuentra algun valor establecido para la conversión entre el documento de procedencia en el documento actual';
                        }
                    }

                    $string = float_a_string($total['total']);
                    $numero = number_format($string, 2);
                    $numero = str_replace('.', '', $numero);
                    $numero = str_replace(',', '', $numero);
                    $pay[] = [
                        'pago' => 'efectivo',
                        'monto' => float_a_string($numero)
                    ];
                } else if ($convertido['rd_docid_procedencia'] == 3) {

                    $total = $this->carritoModel->obtenerPre($convertido['rd_facid_procedencia']);

                    if ($divisa_facturar['id'] != $total['id_divisa']) {
                        if ($this->carritoModel->obtenerDivisaAlCambio($total['id_divisa'], $divisa_facturar['id'])) {
                            $monto = $this->obtenerPrecioSegunDivisa($total['total'], $total['id_divisa'], $divisa_facturar['id']);
                            $total['total'] = $monto['precio'];
                        } else {
                            $this->array_errors[] = 'Lo siento no se encuentra algun valor establecido para la conversión entre el documento de procedencia en el documento actual';
                        }
                    }

                    $string = float_a_string($total['total']);
                    $numero = number_format($string, 2);
                    $numero = str_replace('.', '', $numero);
                    $numero = str_replace(',', '', $numero);
                    $pay[] = [
                        'pago' => 'efectivo',
                        'monto' => float_a_string($numero)
                    ];
                } else if ($convertido['rd_docid_procedencia'] == 4) {

                    $total = $this->carritoModel->obtenerPe($convertido['rd_facid_procedencia']);

                    if ($divisa_facturar['id'] != $total['id_divisa']) {
                        if ($this->carritoModel->obtenerDivisaAlCambio($total['id_divisa'], $divisa_facturar['id'])) {
                            $monto = $this->obtenerPrecioSegunDivisa($total['total'], $total['id_divisa'], $divisa_facturar['id']);
                            $total['total'] = $monto['precio'];
                        } else {
                            $this->array_errors[] = 'Lo siento no se encuentra algun valor establecido para la conversión entre el documento de procedencia en el documento actual';
                        }
                    }

                    $string = float_a_string($total['total']);
                    $numero = number_format($string, 2);
                    $numero = str_replace('.', '', $numero);
                    $numero = str_replace(',', '', $numero);
                    $pay[] = [
                        'pago' => 'efectivo',
                        'monto' => float_a_string($numero)
                    ];
                } else if ($convertido['rd_docid_procedencia'] == 12) {
                    $preorde = $this->carritoModel->obtenerOrdenE($convertido['rd_facid_procedencia']);
                    $preOrden = $this->carritoModel->obtenerPrOrden($convertido['rd_facid_procedencia']);

                    $documento  = $this->carritoModel->obtenerDocumento(12);
                    $serie      = $this->carritoModel->obtenerSerie($preorde['id_serie']);

                    $desc1 = 'Plan: #' . $preOrden['pre_correlativo'] . '/ Pre: #' . mascara_correlativo($documento['doc_prefijo'], $serie['ser_impuesto'], $preorde['correlativo']);
                    $desc2 = 'Motor: ' . $preOrden['mot_motor'] . '-' . $preOrden['m_marca'];
                }
            } else {
                $tipo_metodo = [];
                $i = 0;
                foreach ($abonos as $abono) {
                    $string = float_a_string($abono['fab_conversion']);
                    $numero = number_format($string, 2);
                    $numero = str_replace('.', '', $numero);
                    $numero = str_replace(',', '', $numero);
                    $metodo = $abono['mp_nombre'] ?? 'efectivo';
                    if (!in_array($metodo, $tipo_metodo)) {
                        $pay[] = [
                            'pago' => strtolower($metodo),
                            'monto' => float_a_string($numero)
                        ];
                        $tipo_metodo[] = $metodo;
                    } else {
                        $pay[$i]['monto'] += float_a_string($numero);
                    }
                }
            }

            if ($factura['impreso'] == 0) {

                if (count($pay) == 0) {
                    $pay[] = [
                        'pago' => 'efectivo',
                        'monto' => float_a_string(0)
                    ];
                }
                $dni = str_replace('.', '', $cliente['cli_dni']);
                // $dni = str_replace('V', '', $dni);
                $dni = str_replace('-', '', $dni);
                $data = [
                    'command' => 'generate_invoice',
                    'args' => [[
                        'rif'       => $dni,
                        'clients'   => $cliente['cli_razon_social'],
                        'direccion' => $cliente['cli_direccion'],
                        'telefono'  => $cliente['cli_telefono'],
                        'cajero'    => $cajero['einfo_nombres'] . ' ' . $cajero['einfo_apellidos'],
                        'item'      => $items,
                        'pay'       => $pay,
                        'desc_rec'  => '0',
                        'desc1'     => $desc1,
                        'desc2'     => $desc2
                    ]]
                ];
            } else {
                $data = [
                    'command' => 'generate_reimpresion_rangonumero',
                    'args' => [[
                        'modo'      => 'Facturas',
                        'incio'     => $factura['correlativo'],
                        'fin'       => $factura['correlativo']
                    ]]
                ];
            }

            return $data;
        } else {
            $this->array_errors[] = 'Lo siento el precio de un producto excede el limite para facturar';
        }
        return ['errors' => $this->array_errors];
    }


    private function ticket(string $tabla_db, int $id_factura, int $usddivisa, string $descripcion)
    {
        if ($tabla_db == 'app_notas_de_entrega') {
            $factura    = $this->carritoModel->obtenerNe($id_factura);
            $articulos  = $this->carritoModel->obtenerNeArticulos($factura['id']);
        } else if ($tabla_db == 'app_factura_master') {
            $factura    = $this->carritoModel->obtenerFac($id_factura);
            $articulos  = $this->carritoModel->obtenerFacArticulos($factura['id']);
        } else if ($tabla_db == 'app_orden_de_entrega') {
            $factura    = $this->carritoModel->obtenerOrdenE($id_factura);
            $articulos  = $this->carritoModel->obtenerOrdenArticulos($factura['id']);
        }

        $factor = 1;

        if (($usddivisa == 0) && ($factura['id_divisa'] != 1)) {
            $data_factor_factura = $this->carritoModel->obtenerDivisaAlCambio($factura['id_divisa'], 1);
            $factor = $data_factor_factura['df_factor'];
            $divisa     = Moneda::obtenerDivisa(1);
        } else {
            $divisa     = Moneda::obtenerDivisa($factura['id_divisa']);
        }

        $cliente    = $this->carritoModel->obtenerCliente($factura['id_cliente']);
        $cajero     = $this->carritoModel->obtenerCajero($factura['id_empleado']);
        $items      = [];
        $modulo = new Module();

        $empresa = $this->carritoModel->consultar("SELECT * FROM app_empresas")->row();
        $factCompra = $empresa['emp_iva'];
        $precio = 0;
        $total = 0;

        foreach ($articulos as $articulo) {

            $data_producto = $this->carritoModel->consultar("SELECT pro_nombrecorto, pro_impid FROM app_productos WHERE pro_id = {$articulo['id_producto']}")->row();

            if ($data_producto['pro_impid'] == 2) {
                $tasa = 'Exento';
            } else {
                if ($factCompra) {
                    $tasa = 'Exento';
                } else {
                    $tasa = 'General';
                }
            }

            $precio = $articulo['total'] * $factor;

            $total += $precio;

            $items[] = [
                'producto'  => empty($data_producto['pro_nombrecorto']) ? $articulo['nombre'] : $data_producto['pro_nombrecorto'],
                'precio'    => Moneda::moneda($precio, $divisa['locale'], $divisa['symbol']),
                'cantidad'  => $articulo['cantidad'],
                'tasa'      => $tasa
            ];
        }

        $monto_desc = $factura['descuento'] == 0 ? 0 : convertir_a_float($total * ($factura['descuento'] / 100));

        return [
            'command' => 'generate_ticket',
            'args' => [[
                'fecha_impresion'   => date('d-m-Y H:i:s'),
                'fecha_creacion'    => $factura['fecha'],
                'observacion'       => empty($factura['observaciones']) ? '' : $factura['observaciones'],
                'num_ticket'        => $factura['correlativo'],
                'rif'               => $cliente['cli_dni'],
                'clients'           => $cliente['cli_razon_social'],
                'direccion'         => $cliente['cli_direccion'],
                'telefono'          => $cliente['cli_telefono'],
                'cajero'            => $cajero['einfo_nombres'] . ' ' . $cajero['einfo_apellidos'],
                'item'              => $items,
                'desc_rec'          => $factura['descuento'],
                'monto_desc'        => Moneda::moneda($monto_desc, $divisa['locale'], $divisa['symbol']),
                'monto_total'       => Moneda::moneda(($factCompra == 1) ? $total - $monto_desc : $factura['total'] * $factor, $divisa['locale'], $divisa['symbol']),
                'monto_subtotal'    => Moneda::moneda(($factCompra == 1) ? $total : $factura['subtotal'] * $factor, $divisa['locale'], $divisa['symbol']),
                'monto_iva'         => Moneda::moneda(($factCompra == 1) ? 0 : $factura['iva'] * $factor, $divisa['locale'], $divisa['symbol']),
                'descripcion' => $descripcion
            ]]
        ];
    }

    public function puntoTicket(int $id_factura)
    {
        $factura    = $this->carritoModel->obtenerOrdenE($id_factura);
        $cliente    = $this->carritoModel->obtenerCliente($factura['id_cliente']);
        $cajero     = $this->carritoModel->obtenerCajero($factura['id_empleado']);
        $abonos     = $this->carritoModel->abonosPositvosDocumento($factura['id'], 12);
        $documento  = $this->carritoModel->obtenerDocumento(12);
        $serie      = $this->carritoModel->obtenerSerie($factura['id_serie']);
        $pay        = [];

        $total_pagos    = $this->carritoModel->totalPagos($id_factura, 12, 1);

        $predefinir_estatus_pago = $factura['total'] - $total_pagos['total'];

        $mascara = mascara_correlativo($documento['doc_prefijo'], $serie['ser_impuesto'], $factura['correlativo']);

        //if ($predefinir_estatus_pago == 0) {

        $tipo_metodo = [];
        $i = 0;
        $pagos = 0;
        if (is_countable($abonos) && count($abonos)) {
            foreach ($abonos as $abono) {
                $metodo = $abono['mp_nombre'] ?? 'efectivo';
                // if (!in_array($metodo, $tipo_metodo)) {
                $pay[] = [
                    'divisa' => $factura['id_divisa'],
                    'pago' => strtolower($metodo),
                    'monto' => $abono['fab_conversion']
                ];
                $tipo_metodo[] = $metodo;
                $pagos += $abono['fab_conversion'];
                // } else {
                //    $pay[$i]['monto'] += $abono['fab_monto'];
                // }
            }
        }
        $div_format_pay = Moneda::obtenerDivisa($factura['id_divisa']);

        if (is_countable($pay) && count($pay)) {
            foreach ($pay as $row) {

                $pay_format[] = [
                    'pago' => $row['pago'],
                    'monto' => Moneda::moneda($row['monto'], $div_format_pay['locale'], $div_format_pay['symbol'], $div_format_pay['precision'])
                ];
            }
        }

        if (empty($pay_format)) {
            $pay_format[] = [
                'monto' => 0,
                'pago' => ''
            ];
        }

        $planilla = $this->carritoModel->consultar("SELECT * FROM app_planilla_orden_de_entrega oe LEFT JOIN app_preorden_master pre ON oe.po_preid =pre.pre_id WHERE po_nid =$id_factura")->row();

        $data = [
            'command'           => 'generate_punto_ticket',
            'args' => [[
                'nombre_ticket'     => 'ORDEN DE ENTREGA',
                'numero_pedido'     => $mascara,
                'planilla'          => ($planilla != null) ? $planilla['pre_correlativo'] : 'SIN PLANILLA',
                'rif'               => $cliente['cli_dni'],
                'clients'           => $cliente['cli_razon_social'],
                'direccion'         => $cliente['cli_direccion'],
                'telefono'          => $cliente['cli_telefono'],
                'cajero'            => $cajero['einfo_nombres'] . ' ' . $cajero['einfo_apellidos'],
                'pay'               => $pay_format,
                'desc_rec'          => '0',
                'total'             => Moneda::moneda($pagos, $div_format_pay['locale'], $div_format_pay['symbol'], $div_format_pay['precision'])
            ]]
        ];

        return $data;
        //  } else {
        //    $this->array_errors[] = 'Lo siento la factura no tiene estatus paga';
        // }

        return ['errors' => $this->array_errors];
    }

    private function punto(string $tabla_db, int $id_factura)
    {
        if ($tabla_db == 'app_notas_de_entrega') {
            $factura    = $this->carritoModel->obtenerNe($id_factura);
            $articulos  = $this->carritoModel->obtenerNeArticulos($factura['id']);
            $documento  = $this->carritoModel->obtenerDocumento(1);
        } else if ($tabla_db == 'app_factura_master') {
            $factura    = $this->carritoModel->obtenerFac($id_factura);
            $articulos  = $this->carritoModel->obtenerFacArticulos($factura['id']);
            $documento  = $this->carritoModel->obtenerDocumento(2);
        } else if ($tabla_db == 'app_orden_de_entrega') {
            $factura    = $this->carritoModel->obtenerOrdenE($id_factura);
            $articulos  = $this->carritoModel->obtenerOrdenArticulos($factura['id']);
            $documento  = $this->carritoModel->obtenerDocumento(12);
        }

        $divisa     = Moneda::obtenerDivisa($factura['id_divisa']);
        $cliente    = $this->carritoModel->obtenerCliente($factura['id_cliente']);
        $cajero     = $this->carritoModel->obtenerCajero($factura['id_empleado']);
        $items      = [];
        $subtotal_mano = 0;
        $iva_mano = 0;

        $subtotal_repuestos = 0;
        $iva_repuestos = 0;
        $serie = $this->carritoModel->obtenerSerie($factura['id_serie']);
        $mascara = mascara_correlativo($documento['doc_prefijo'], $serie['ser_impuesto'], $factura['correlativo']);

        foreach ($articulos as $articulo) {

            $data_producto = $this->carritoModel->consultar("SELECT pro_nombrecorto, pro_impid, pro_tipo FROM app_productos WHERE pro_id = {$articulo['id_producto']}")->row();

            /*if ($articulo['id_iva'] == 2) {
                $tasa = 'Exento';
            } else {
                $tasa = 'General';
            }*/

            if ($data_producto['pro_impid'] == 2) {
                $tasa = 'Exento';
            } else {
                $tasa = 'General';
            }

            $items[] = [
                'codigo'    => $articulo['codigo'],
                'producto'  => empty($data_producto['pro_nombrecorto']) ? $articulo['nombre'] : $data_producto['pro_nombrecorto'],
                'cantidad'  => $articulo['cantidad'],
                'decuento'  => $articulo['descuento'],
                'precio'    => Moneda::moneda($articulo['precio'], $divisa['locale'], $divisa['symbol']),
                'total'     => Moneda::moneda($articulo['precio'] * $articulo['cantidad'], $divisa['locale'], $divisa['symbol']),
                'tipo'      => $data_producto['pro_tipo']
            ];

            if ($data_producto['pro_tipo'] == 3) {
                $subtotal_mano += $articulo['neto'];
                $iva_mano += $articulo['iva_total'];
            }

            if ($data_producto['pro_tipo'] == 1) {
                $subtotal_repuestos += $articulo['neto'];
                $iva_repuestos += $articulo['iva_total'];
            }
        }

        $monto_desc = $factura['descuento'] == 0 ? 0 : $factura['neto'];

        $orden_trabajo = '';
        $modelo = '';
        $observacion = '';

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

        if ($planilla_orden) {

            $planilla = $GLOBALS['newDBIni']->consultar("SELECT * FROM app_preorden_master WHERE pre_id = {$planilla_orden['po_preid']}")->row();

            if ($planilla['pre_motid']) {

                $motor = $GLOBALS['newDBIni']->consultar("SELECT * FROM app_motores mot JOIN app_marcas m ON m.m_id = mot.mot_marca WHERE mot_id={$planilla['pre_motid']}")->row();

                $modelo = $motor ? $motor['mot_motor'] . ' - Marca: ' . $motor['m_marca'] . ' - Modelo: ' . $motor['mot_modelo'] : '';
            }

            $orden_trabajo = $planilla['pre_correlativo'];
        }

        return [
            'command' => 'generate_factura_punto_presupuesto',
            'args' => [[
                'numero_pedido'     => $mascara,
                'orden_trabajo'     => $orden_trabajo,
                'modelo'            => $modelo,
                'rif'               => $cliente['cli_dni'],
                'clients'           => $cliente['cli_razon_social'],
                'direccion'         => $cliente['cli_direccion'],
                'telefono'          => $cliente['cli_telefono'],
                'cajero'            => $cajero['einfo_nombres'] . ' ' . $cajero['einfo_apellidos'],
                'item'              => $items,
                'subtotal_mano'     => Moneda::moneda($subtotal_mano, $divisa['locale'], $divisa['symbol']),
                'iva_mano'          => Moneda::moneda($iva_mano, $divisa['locale'], $divisa['symbol']),
                'total_mano'        => Moneda::moneda($subtotal_mano + $iva_mano, $divisa['locale'], $divisa['symbol']),
                'subtotal_repuestos'     => Moneda::moneda($subtotal_repuestos, $divisa['locale'], $divisa['symbol']),
                'iva_repuestos'     => Moneda::moneda($iva_repuestos, $divisa['locale'], $divisa['symbol']),
                'total_repuestos'     => Moneda::moneda($subtotal_repuestos + $iva_repuestos, $divisa['locale'], $divisa['symbol']),
                'total'             => Moneda::moneda($factura['total'], $divisa['locale'], $divisa['symbol']),
                'desc_rec'          => $factura['descuento'],
                'monto_desc'        => Moneda::moneda($monto_desc, $divisa['locale'], $divisa['symbol']),
                'observacion'       => $factura['observaciones']
            ]]
        ];
    }

    public function imprimirPuntoTicket(string $tabla_db, int $id_factura, int $id_impresora)
    {
        $impresora = $this->carritoModel->impresora($id_impresora);
        if ($impresora) {
            return [
                'ip_puerto' => protocolo() . $impresora['ip_puerto'],
                'data'      => $this->puntoTicket($id_factura)
            ];
        } else {
            $this->array_errors[] = 'Acción prohibida';
        }

        return ['errors' => $this->array_errors];
    }

    private function ticketIndividual(string $tabla_db, int $id_factura, int $id_movimiento)
    {
        if ($tabla_db == 'app_notas_de_entrega') {
            $factura    = $this->carritoModel->obtenerNe($id_factura);
            $abono      = $this->carritoModel->obtenerAbonoDevol($id_factura, 1, $id_movimiento);
            $total_pagos    = $this->carritoModel->totalPagos($id_factura, 1, 1);
        } else if ($tabla_db == 'app_factura_master') {
            $factura    = $this->carritoModel->obtenerFac($id_factura);
            $abono      = $this->carritoModel->obtenerAbonoDevol($id_factura, 2, $id_movimiento);
            $total_pagos    = $this->carritoModel->totalPagos($id_factura, 2, 1);
        } else if ($tabla_db == 'app_orden_de_entrega') {
            $factura    = $this->carritoModel->obtenerOrdenE($id_factura);
            $abono      = $this->carritoModel->obtenerAbonoDevol($id_factura, 12, $id_movimiento);
            $total_pagos    = $this->carritoModel->totalPagos($id_factura, 12, 1);
        }

        $cliente    = $this->carritoModel->obtenerCliente($factura['id_cliente']);
        $cajero     = $this->carritoModel->obtenerCajero($factura['id_empleado']);
        $divisa     = Moneda::obtenerDivisa($abono['fab_divid_conversion']);

        if (is_null($abono['fab_divisa'])) {
            $divisa_mov = $this->divisa_master;
        } else {
            $divisa_mov = Moneda::obtenerDivisa($abono['fab_divisa']);
        }
        $esta = "";

        if ($abono['fab_retiro'] == 1) {
            $esta = "DEVOLUCION";
        } else {
            if ((round($factura['total'] - $total_pagos['total']))) {
                $esta = "PAGADO";
            } else {
                $esta = "ABONO";
            }
        }

        return [
            'command' => 'generate_ticket_individual',
            'args' => [[
                'fecha_impresion'   => date('d-m-Y H:i:s'),
                'fecha_creacion'    => date('d-m-Y', strtotime($abono['fab_fecha'])),
                'cli_dni'           => $cliente['cli_dni'],
                'cli_nombre'        => $cliente['cli_razon_social'],
                'cli_direccion'     => $cliente['cli_direccion'],
                'cli_telefono'      => $cliente['cli_telefono'],
                'orden'             => $factura['correlativo'],
                'estatus'           => $esta,
                'cajero'            => $cajero['einfo_nombres'] . ' ' . $cajero['einfo_apellidos'],
                'monto'             => Moneda::moneda($abono['fab_monto'], $divisa_mov['locale'], $divisa_mov['symbol'], $divisa_mov['precision']),
                'metodo_de_pago'    => ($abono['mp_nombre'] == null) ? 'Credito' : $abono['mp_nombre'],
                'total'             => Moneda::moneda($factura['total'], $divisa['locale'], $divisa['symbol'], $divisa['precision']),
                'restante'          => Moneda::moneda(($factura['total'] - $total_pagos['total']), $divisa['locale'], $divisa['symbol'], $divisa['precision'])
            ]]
        ];
    }

    public function imprimirTicketCredito(string $tabla_db, int $id_factura, int $id_impresora)
    {
        $impresora = $this->carritoModel->impresora($id_impresora);
        if ($impresora) {
            return [
                'ip_puerto' => protocolo() . $impresora['ip_puerto'],
                'data'      => $this->ticketCredito($tabla_db, $id_factura)
            ];
        } else {
            $this->array_errors[] = 'Acción prohibida';
        }

        return ['errors' => $this->array_errors];
    }

    private function ticketCredito(string $tabla_db, int $id_factura)
    {
        $factura    = $this->carritoModel->obtenerOrdenE($id_factura);
        $cliente    = $this->carritoModel->obtenerCliente($factura['id_cliente']);
        $cajero     = $this->carritoModel->obtenerCajero($factura['id_empleado']);
        $serie      = $this->carritoModel->obtenerSerie($factura['id_serie']);
        $documento  = $this->carritoModel->obtenerDocumento(12);
        $pay_format        = [];

        $div_format_pay = Moneda::obtenerDivisa($factura['id_divisa']);


        if (empty($pay_format)) {
            $pay_format[] = [
                'monto' => Moneda::moneda($factura['total'], $div_format_pay['locale'], $div_format_pay['symbol'], $div_format_pay['precision']),
                'pago' => 'A credito'
            ];
        }

        $mascara = mascara_correlativo($documento['doc_prefijo'], $serie['ser_impuesto'], $factura['correlativo']);

        $planilla = $this->carritoModel->consultar("SELECT * FROM app_planilla_orden_de_entrega oe LEFT JOIN app_preorden_master pre ON oe.po_preid =pre.pre_id WHERE po_nid =$id_factura")->row();

        $data = [
            'command'           => 'generate_punto_ticket',
            'args' => [[
                'nombre_ticket'     => 'ORDEN A CREDITO',
                'numero_pedido'     => $mascara,
                'planilla'          => ($planilla != null) ? $planilla['pre_correlativo'] : 'SIN PLANILLA',
                'rif'               => $cliente['cli_dni'],
                'clients'           => $cliente['cli_razon_social'],
                'direccion'         => $cliente['cli_direccion'],
                'telefono'          => $cliente['cli_telefono'],
                'cajero'            => $cajero['einfo_nombres'] . ' ' . $cajero['einfo_apellidos'],
                'pay'               => $pay_format,
                'desc_rec'          => '0',
                'total'             => Moneda::moneda($factura['total'], $div_format_pay['locale'], $div_format_pay['symbol'], $div_format_pay['precision'])
            ]]
        ];

        return $data;
    }
    public function imprimirTicketIndividual(string $tabla_db, int $id_factura, int $id_impresora, $id_movimiento)
    {
        $impresora = $this->carritoModel->impresora($id_impresora);
        if ($impresora) {
            return [
                'ip_puerto' => protocolo() . $impresora['ip_puerto'],
                'data'      => $this->ticketIndividual($tabla_db, $id_factura, $id_movimiento)
            ];
        } else {
            $this->array_errors[] = 'Acción prohibida';
        }

        return ['errors' => $this->array_errors];
    }

    public function imprimir(string $tabla_db, int $id_factura, int $id_impresora)
    {
        $impresora = $this->carritoModel->impresora($id_impresora);
        if ($impresora) {
            switch ($impresora['imp_tipo']) {
                case 1: //FISCAL
                    return [
                        'ip_puerto' => protocolo() . $impresora['ip_puerto'],
                        'data'      => $this->fiscal($id_factura, $impresora['imp_limite'], $impresora['imp_redondear'])
                    ];
                case 2: //TICKET
                    return [
                        'ip_puerto' => protocolo() . $impresora['ip_puerto'],
                        'data'      => $this->ticket($tabla_db, $id_factura, $impresora['imp_usd'], $impresora['imp_descripcion_final'])
                    ];
                case 3: //PUNTO
                    return [
                        'ip_puerto' => protocolo() . $impresora['ip_puerto'],
                        'data'      => $this->punto($tabla_db, $id_factura)
                    ];
            }
        } else {
            $this->array_errors[] = 'Acción prohibida';
        }

        return ['errors' => $this->array_errors];
    }

    public function imprimirAnular(string $tabla_db, int $id_factura, int $id_impresora, int $numFactura)
    {
        $impresora = $this->carritoModel->impresora($id_impresora);
        if ($impresora) {
            switch ($impresora['imp_tipo']) {
                case 1: //FISCAL
                    $factura    = $this->carritoModel->obtenerFac($id_factura);
                    $articulos  = $this->carritoModel->obtenerFacArticulos($factura['id']);
                    $cliente    = $this->carritoModel->obtenerCliente($factura['id_cliente']);
                    $cajero     = $this->carritoModel->obtenerCajero($factura['id_empleado']);
                    $abonos     = $this->carritoModel->abonosPositvos($factura['id']);
                    $divisa_facturar = Moneda::facturarPredeterminada();
                    $items      = [];
                    $pay        = [];
                    $data = [];
                    $mayor = 0;
                    //        if ($factura['estatus'] == 1) {

                    foreach ($articulos as $articulo) {

                        $data_producto = $this->carritoModel->consultar("SELECT pro_nombrecorto FROM app_productos WHERE pro_id = {$articulo['id_producto']}")->row();

                        if ($articulo['id_iva'] == 2) {
                            $tasa = 'Exento';
                        } else {
                            $tasa = 'General';
                        }


                        $string = float_a_string($articulo['precio']);
                        $numero = number_format($string, 2);
                        $numero = str_replace('.', '', $numero);
                        $numero = str_replace(',', '', $numero);

                        if ($impresora['imp_redondear'] == 1) {
                            $numero = round($numero);
                        }

                        $items[] = [
                            'producto'  => empty($data_producto['pro_nombrecorto']) ? $articulo['nombre'] : $data_producto['pro_nombrecorto'],
                            'precio'    => $numero,
                            'cantidad'  => $articulo['cantidad'],
                            'tasa'      => $tasa
                        ];
                        if ($numero > $impresora['imp_limite']) {
                            $mayor = 1;
                        }
                    }

                    if ($mayor == 0) {
                        $convertido = $this->carritoModel->rutaDocumento($id_factura, 2);

                        if ($convertido) {

                            if ($convertido['rd_docid_procedencia'] == 1) {

                                $total = $this->carritoModel->obtenerNe($convertido['rd_facid_procedencia']);

                                if ($divisa_facturar['id'] != $total['id_divisa']) {
                                    if ($this->carritoModel->obtenerDivisaAlCambio($total['id_divisa'], $divisa_facturar['id'])) {
                                        $monto = $this->obtenerPrecioSegunDivisa($total['total'], $total['id_divisa'], $divisa_facturar['id']);
                                        $total['total'] = $monto['precio'];
                                    } else {
                                        $this->array_errors[] = 'Lo siento no se encuentra algun valor establecido para la conversión entre el documento de procedencia en el documento actual';
                                    }
                                }

                                $string = float_a_string($total['total']);
                                $numero = number_format($string, 2);
                                $numero = str_replace('.', '', $numero);
                                $numero = str_replace(',', '', $numero);

                                $pay[] = [
                                    'pago' => 'efectivo',
                                    'monto' => $numero
                                ];
                            } else if ($convertido['rd_docid_procedencia'] == 3) {

                                $total = $this->carritoModel->obtenerPre($convertido['rd_facid_procedencia']);

                                if ($divisa_facturar['id'] != $total['id_divisa']) {
                                    if ($this->carritoModel->obtenerDivisaAlCambio($total['id_divisa'], $divisa_facturar['id'])) {
                                        $monto = $this->obtenerPrecioSegunDivisa($total['total'], $total['id_divisa'], $divisa_facturar['id']);
                                        $total['total'] = $monto['precio'];
                                    } else {
                                        $this->array_errors[] = 'Lo siento no se encuentra algun valor establecido para la conversión entre el documento de procedencia en el documento actual';
                                    }
                                }

                                $string = float_a_string($total['total']);
                                $numero = number_format($string, 2);
                                $numero = str_replace('.', '', $numero);
                                $numero = str_replace(',', '', $numero);
                                $pay[] = [
                                    'pago' => 'efectivo',
                                    'monto' => $numero
                                ];
                            } else if ($convertido['rd_docid_procedencia'] == 4) {

                                $total = $this->carritoModel->obtenerPe($convertido['rd_facid_procedencia']);

                                if ($divisa_facturar['id'] != $total['id_divisa']) {
                                    if ($this->carritoModel->obtenerDivisaAlCambio($total['id_divisa'], $divisa_facturar['id'])) {
                                        $monto = $this->obtenerPrecioSegunDivisa($total['total'], $total['id_divisa'], $divisa_facturar['id']);
                                        $total['total'] = $monto['precio'];
                                    } else {
                                        $this->array_errors[] = 'Lo siento no se encuentra algun valor establecido para la conversión entre el documento de procedencia en el documento actual';
                                    }
                                }

                                $string = float_a_string($total['total']);
                                $numero = number_format($string, 2);
                                $numero = str_replace('.', '', $numero);
                                $numero = str_replace(',', '', $numero);
                                $pay[] = [
                                    'pago' => 'efectivo',
                                    'monto' => $numero
                                ];
                            }
                        } else {
                            $tipo_metodo = [];
                            $i = 0;
                            foreach ($abonos as $abono) {
                                $string = float_a_string($abono['fab_conversion']);
                                $numero = number_format($string, 2);
                                $numero = str_replace('.', '', $numero);
                                $numero = str_replace(',', '', $numero);
                                $metodo = $abono['mp_nombre'] ?? 'efectivo';
                                if (!in_array($metodo, $tipo_metodo)) {
                                    $pay[] = [
                                        'pago' => strtolower($metodo),
                                        'monto' => $numero
                                    ];
                                    $tipo_metodo[] = $metodo;
                                } else {
                                    $pay[$i]['monto'] += $numero;
                                }
                            }
                        }

                        if ($factura['impreso'] == 1) {

                            if (count($pay) == 0) {
                                $pay[] = [
                                    'pago' => 'efectivo',
                                    'monto' => 0
                                ];
                            }
                            $dni = $cliente['cli_dni'];
                            // $dni = str_replace('V', '', $dni);
                            //$dni = str_replace('-', '', $dni);
                            $data = [
                                'command' => 'generate_credit_note',
                                'args' => [[
                                    'rif'       => $dni,
                                    'impresora' => $impresora['imp_codigo'],
                                    'num_fact' =>  $numFactura,
                                    'clients'   => $cliente['cli_razon_social'],
                                    'fecha'    =>  date('d-m-Y', strtotime($factura['fecha'])),
                                    'cajero'    => $cajero['einfo_nombres'] . ' ' . $cajero['einfo_apellidos'],
                                    'item'      => $items,
                                    'pay'       => $pay,
                                    'desc_rec'  => '0',
                                    'desc1'     => "",
                                    'desc2'     => "",
                                ]]
                            ];
                        } else {
                            $this->array_errors[] = 'Lo siento error';
                        }
                    } else {
                        $this->array_errors[] = 'Lo siento el precio de un producto excede el limite para facturar';
                    }

                    return [
                        'ip_puerto' => protocolo() . $impresora['ip_puerto'],
                        'data'      => $data
                    ];
            }
        } else {
            $this->array_errors[] = 'Acción prohibida';
        }

        return ['errors' => $this->array_errors];
    }

    public function reimprimirFactura(int $id_factura, int $id_impresora)
    {
        $impresora = $this->carritoModel->impresora($id_impresora);
        if ($impresora) {

            $data = [
                'command' => 'generate_reimpresion_rangonumero',
                'args' => [[
                    'modo'      => 'Facturas',
                    'incio'     => $id_factura,
                    'fin'       => $id_factura
                ]]
            ];

            return [
                'ip_puerto' => protocolo() . $impresora['ip_puerto'],
                'data'      => $data
            ];
        }
        return ['errors' => $this->array_errors];
    }


    public function imprimirIngreso(string $estatus, $data, int $id_impresora)
    {
        $impresora = $this->carritoModel->impresora($id_impresora);

        if ($impresora) {

            $datos = [
                'command' => 'generate_ingresos',
                'args' => [[
                    'estatus'     => $estatus,
                    'ingreso'     => $data
                ]]
            ];

            return [
                'ip_puerto' => protocolo() . $impresora['ip_puerto'],
                'data'      => $datos
            ];
        }
    }

    public function imprimirComisiones($fecha_desde, $fecha_hasta, $data, int $id_impresora, int $estatus)
    {

        $data_final = [
            'command'           => 'generate_pago_comisiones',
            'args' => [[
                'nombre'            => 'PAGO DE COMISIONES',
                'fecha'             => $fecha_desde . '-' . $fecha_hasta,
                'data'              => $data
            ]]
        ];

        $impresora = $this->carritoModel->impresora($id_impresora);

        if ($impresora) {

            return [
                'ip_puerto' => protocolo() . $impresora['ip_puerto'],
                'data'      => $data_final
            ];
        }
    }
    public function editarDetallesCliente(int $id_factura, array $data)
    {
        $cliente = new Cliente();

        if ($cliente->cedulaExiste($id_factura, $data['cli_dni']))
            $this->array_errors[] = 'Lo siento la cedula de identidad ya se encuentra asociada a otro cliente';

        if (empty($this->array_errors)) {
            return $cliente->editar($id_factura, [
                'cli_tipodocid'     => $data['cli_tipodocid'],
                'cli_dni'           => $data['cli_dni'],
                'cli_razon_social'  => $data['cli_razon_social'],
                'cli_direccion'     => $data['cli_direccion'],
                'cli_paisid'        => $data['cli_paisid'],
                'cli_estado'        => $data['cli_estado'],
                'cli_ciudad'        => $data['cli_ciudad'],
                'cli_codpostal'     => $data['cli_codpostal'],
                'cli_telefono'      => $data['cli_telefono'],
                'cli_fecha_nac'     => $data['cli_fecha_nac'],
                'cli_email'         => $data['cli_email'],
                'cli_lat'         => $data['cli_lat'],
                'cli_lng'         => $data['cli_lng']
            ]);
        }

        return ['errors' => $this->array_errors];
    }

    public function guardarClienteCambiar(string $tabla_db, int $id_factura, array $data, bool $caja = false)
    {
        $cliente_model = new Cliente();

        if (empty($data['cli_email'])) {
            $cli_email = NULL;
        } else {
            $cli_email = filter_var($data['cli_email'], FILTER_VALIDATE_EMAIL);
            if (!$cli_email)
                $this->array_errors[] = 'Correo invalido';
            if ($cliente_model->existe('cli_email', $data['cli_email']))
                $this->array_errors[] = 'El correo electronico ya se encuentra en uso';
        }

        if ($cliente_model->existe('cli_dni', $data['cli_dni']))
            $this->array_errors[] = 'La cedula de identidad ya se encuentra en uso';

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

            $data_id = $cliente_model->guardar([
                'cli_tipodocid'     => $data['cli_tipodocid'],
                'cli_dni'           => $data['cli_dni'],
                'cli_razon_social'  => $data['cli_razon_social'],
                'cli_direccion'     => $data['cli_direccion'],
                'cli_natural'       => $data['cli_natural'],
                'cli_email'         => $data['cli_email'],
                'cli_telefono'      => $data['cli_telefono']
            ]);

            if ($data_id) {
                $cliente_direccion_envio_model = new Clientedireccionenvios();
                $cliente_direccion_envio_model->guardar([
                    'cde_cliid'     => $data_id,
                    'cde_direccion' => $data['cli_direccion']
                ]);
            }

            return $this->cambiarCliente($tabla_db, $data_id, $id_factura, $caja);
        }

        return ['errors' => $this->array_errors];
    }

    public function cambiarCliente(string $tabla_db, int $id_cliente, int $id_factura, bool $caja = false)
    {
        $cliente = $this->carritoModel->obtenerCliente($id_cliente);

        if ($tabla_db == 'app_factura_master') {
            $v_id_tabla = 'fm_id';
            if ($caja) {
                $uri = 'facturacioncajaeditar/verFactura/';
            } else {
                $uri = 'poseditar/verFactura/';
            }
            $factura = $this->carritoModel->obtenerFac($id_factura);
        } else if ($tabla_db == 'app_notas_de_entrega') {
            $v_id_tabla = 'ne_id';
            if ($caja) {
                $uri = 'notasdeentregacajaeditar/verFactura/';
            } else {
                $uri = 'notasdeentregaeditar/verFactura/';
            }
            $factura = $this->carritoModel->obtenerNe($id_factura);
        } else if ($tabla_db == 'app_presupuesto') {
            $v_id_tabla = 'pre_id';
            $uri = 'presupuestoeditar/verFactura/';
            $factura = $this->carritoModel->obtenerNe($id_factura);
        } else if ($tabla_db == 'app_orden_de_entrega') {
            $v_id_tabla = 'n_id';
            $uri = 'ordendeentregaeditar/verFactura/';
            $factura = $this->carritoModel->obtenerOrdenE($id_factura);
        }

        if ($cliente && $factura) {
            if ($tabla_db == 'app_factura_master') {
                $data_form = [
                    'fm_cliid'              => $cliente['cli_id'],
                    'fm_env_nombres'        => $cliente['cli_razon_social'],
                    'fm_env_direccion'      => $cliente['cli_direccion'],
                    'fm_env_pais'           => $cliente['cli_paisid'],
                    'fm_env_estado'         => $cliente['cli_estado'],
                    'fm_env_ciudad'         => $cliente['cli_ciudad'],
                    'fm_env_codigo_postal'  => $cliente['cli_codpostal']
                ];
            } else if ($tabla_db == 'app_notas_de_entrega') {
                $data_form = [
                    'ne_cliid'              => $cliente['cli_id'],
                    'ne_env_nombres'        => $cliente['cli_razon_social'],
                    'ne_env_direccion'      => $cliente['cli_direccion'],
                    'ne_env_pais'           => $cliente['cli_paisid'],
                    'ne_env_estado'         => $cliente['cli_estado'],
                    'ne_env_ciudad'         => $cliente['cli_ciudad'],
                    'ne_env_codigo_postal'  => $cliente['cli_codpostal']
                ];
            } else if ($tabla_db == 'app_presupuesto') {
                $data_form = [
                    'pre_cliid'                 => $cliente['cli_id'],
                    'pre_env_nombres'           => $cliente['cli_razon_social'],
                    'pre_env_direccion'         => $cliente['cli_direccion'],
                    'pre_env_pais'              => $cliente['cli_paisid'],
                    'pre_env_estado'            => $cliente['cli_estado'],
                    'pre_env_ciudad'            => $cliente['cli_ciudad'],
                    'pre_env_codigo_postal'     => $cliente['cli_codpostal'],
                ];
            } else if ($tabla_db == 'app_orden_de_entrega') {
                $data_form = [
                    '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']
                ];
            }

            if ($this->carritoModel->editar($id_factura, $data_form, $tabla_db, $v_id_tabla)) {
                return ruta_base() . $uri . $id_factura;
            } else {
                $this->array_errors[] = 'Los siento ocurrió un error al editar el cliente del documento';
            }
        } else {
            $this->array_errors[] = 'Acción prohibida';
        }

        return ['errors' => $this->array_errors];
    }

    public function guardarCredito(string $tabla_db, int $id_factura, string $monto, $id_cuenta, $id_serie, string $observacion)
    {
        $monto = convertir_a_float($monto);

        if ($monto <= 0) {
            $this->array_errors[] = "El campo Monto debe ser mayor que 0";
        }

        if ($tabla_db == 'app_notas_de_entrega') {
            $factura = $this->carritoModel->obtenerNe($id_factura);
            $id_cliente = $factura['id_cliente'];
            $id_documento = 1;
            $modulo = 'NEV';
        } else if ($tabla_db == 'app_factura_master') {
            $factura = $this->carritoModel->obtenerFac($id_factura);
            $id_cliente = $factura['id_cliente'];
            $id_documento = 2;
            $modulo = 'FACV';
        } else if ($tabla_db == 'app_orden_de_entrega') {
            $factura = $this->carritoModel->obtenerOrdenE($id_factura);
            $id_cliente = $factura['id_cliente'];
            $id_documento = 12;
            $d_ = $this->carritoModel->obtenerDocumento(12);
            $modulo = $d_['doc_prefijo'];
        }

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

            $monto = convertir_a_float($monto);

            $cliente    = $this->carritoModel->consultar("SELECT * FROM app_clientes WHERE cli_id=$id_cliente")->row();
            $serie      = $this->carritoModel->consultar("SELECT * FROM app_series WHERE ser_id=$id_serie")->row();

            if ($cliente && $serie) {

                $correlativo =  $this->carritoModel->consultar("SELECT * FROM app_correlativos WHERE cor_serid = $id_serie AND cor_docid = 7")->row();

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

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

                    $cuenta = $this->carritoModel->consultar("SELECT cmp_cueid, cmp_mdid FROM app_cuentas_metodopago WHERE cmp_id=$id_cuenta")->row();
                    $divisa_factura = $this->carritoModel->consultar("SELECT md_divid FROM app_metodopago_divisa WHERE md_id={$cuenta['cmp_mdid']}")->row();

                    if ($divisa_factura['md_divid'] != $this->divisa_master['id']) {
                        $data_factor_factura = $this->carritoModel->obtenerDivisaAlCambio($this->divisa_master['id'], $divisa_factura['md_divid']);
                        if (!$data_factor_factura) {
                            $this->array_errors[] = 'No se ecuentra el factor de conversion entre la divisa seleccionada y la divisa master.';
                        } else {
                            $factor_factura = $data_factor_factura['df_factor'];
                        }
                    } else {
                        $factor_factura = 1;
                    }

                    $div = Moneda::obtenerDivisa($divisa_factura['md_divid']);

                    $conversion = round($monto / $factor_factura, 2);

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

                        try {
                            $this->carritoModel->transactionBegin();

                            $id_credito = $this->carritoModel->guardar([
                                'cre_cliid'         => $id_cliente,
                                'cre_facid'         => $id_factura,
                                'cre_docid'         => $id_documento,
                                'cre_empleado'      => $_SESSION['user_data']['emp_id'],
                                'cre_modulo'        => $modulo,
                                'cre_observacion'   => $observacion,
                                'cre_correlativo'   => $correlativo['cor_correlativo'] + 1,
                                'cre_monto'         => $conversion,
                                'cre_surcid'        => $factura['sucursal']
                            ], false, 'app_nota_de_credito');

                            $cuenta = $this->carritoModel->consultar("SELECT cmp_saldo, cmp_cueid, cmp_mdid FROM app_cuentas_metodopago WHERE cmp_id=$id_cuenta")->row();
                            $saldo = $this->carritoModel->consultar("SELECT bc_saldo FROM app_bancos_cuentas WHERE bc_id = {$cuenta['cmp_cueid']}")->row();
                            $total = $saldo['bc_saldo'] + $monto;
                            $total_cuenta_metodo = $cuenta['cmp_saldo'] + $monto;

                            $this->carritoModel->guardar([
                                'fab_idgenerico'        => $id_credito,
                                'fab_doc'               => 7,
                                'fab_divisa'            => $divisa_factura['md_divid'],
                                'fab_metodo'            => $cuenta['cmp_mdid'],
                                'fab_cmpid'             => $id_cuenta,
                                'fab_monto'             => $monto,
                                'fab_conversion'        => $conversion,
                                'fab_retiro'            => 0,
                                'fab_factor_master'     => $factor_factura,
                                'fab_factor'            => $factor_factura,
                                'fab_empid'             => $_SESSION['user_data']['emp_id'],
                                'fab_modulo'            => $modulo,
                                'fab_descripcion'       => '',
                                'fab_observacion'       => "Credito $modulo #$id_factura {$cliente['cli_razon_social']} Monto: " . Moneda::moneda($monto, $div['locale'], $div['symbol']),
                                'fab_credito'           => 1,
                                'fab_categoria'         => 1,
                                'fab_saldo_anterior'    => $saldo['bc_saldo'],
                                'fab_sucursal'          => $factura['sucursal']
                            ], true, 'app_movimientos');

                            $this->carritoModel->actualizarCorrelativo($serie['ser_id'], 7, ($correlativo['cor_correlativo'] + 1));
                            $this->carritoModel->consultar("UPDATE app_bancos_cuentas SET bc_saldo = $total WHERE bc_id = {$cuenta['cmp_cueid']}")->run();
                            $this->carritoModel->consultar("UPDATE app_cuentas_metodopago SET cmp_saldo = $total_cuenta_metodo WHERE cmp_id = $id_cuenta")->run();

                            $this->carritoModel->transactionCommit();
                        } catch (\Throwable $th) {
                            $this->carritoModel->transactionRollBack();
                            $this->array_errors[] = 'Error en transacción';
                        }

                        if (empty($this->array_errors)) {
                            return true;
                        }
                    }
                }
            } else {
                $this->array_errors[] = 'Acción prohibida';
            }
        }

        return ['errors' => $this->array_errors];
    }

    public function obtenerUbicacionesProducto(string $_nombre_carrito_, int $id_factura)
    {
        $newProUbi = new ProductoUbicacion();
        $newAU = new AlmacenUbicacion();
        $tipo_de_escalon = [];
        $lista = [];
        $array_tipo = [
            'Zonas' => 'Zona',
            'Pasillos' => 'Pasillo',
            'Armarios' => 'Armario',
            'Secciones' => 'Sección',
            'Cajones' => 'Cajón'
        ];

        $contenido_carrito = $this->contenidoCarrito($_nombre_carrito_, $id_factura);

        if (!empty($contenido_carrito)) {

            foreach ($contenido_carrito as $car) {

                $ubicacion = $newProUbi->obtenerubicacionProductoAlmacen($car['id'], $car['id_almacen']);

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

                    foreach ($ubicacion as $row) {

                        $tipo_de_escalon = [];
                        $padre = $row['au_padre'];

                        $tipo_de_escalon[] = [
                            'id' => $row['au_id'],
                            'tipo' => $array_tipo[$row['au_tipo']],
                            'descripcion' => $row['au_descripcion']
                        ];

                        while ($padre != 0) {
                            $escalon = $newAU->obtenerUbicacion($padre);
                            if ($escalon) {
                                $tipo_de_escalon[] = [
                                    'id' => $escalon['au_id'],
                                    'tipo' => $array_tipo[$escalon['au_tipo']],
                                    'descripcion' => $escalon['au_descripcion']
                                ];
                                $padre = $escalon['au_padre'];
                            } else {
                                $padre = 0;
                            }
                        }

                        $lista[] = [
                            'almacen' => [
                                'id' => $row['alm_id'],
                                'descripcion' => $row['alm_nombre']
                            ],
                            'producto' => [
                                'id' => $row['pro_id'],
                                'codigo' => $row['pro_codigo'],
                                'descripcion' => $row['pro_descripcion']
                            ],
                            'ubicacion' => $tipo_de_escalon
                        ];
                    }
                }
            }
        }

        return $lista;
    }

    public function recalcularComisiones(int $id_factura, int $id_tipo_doc)
    {
        $total_proservicio = $cantidad_prosimple = $cantidad_proservicio = $total_prosimple = $costo_prosimple = $costo_proservicio = $iva_totalsimple = $iva_totalservicio = 0;
        $data_comisiones_planillas = [];

        if ($id_tipo_doc == 1) {
            $factura    = $this->carritoModel->obtenerNe($id_factura);
            $articulos  = $this->carritoModel->obtenerNeArticulos($id_factura);
            $agent_fijo = $this->carritoModel->obtenerAgentesFijo(1);
        } elseif ($id_tipo_doc == 2) {
            $factura    = $this->carritoModel->obtenerFac($id_factura);
            $articulos  = $this->carritoModel->obtenerFacArticulos($id_factura);
            $agent_fijo = $this->carritoModel->obtenerAgentesFijo(2);
        } elseif ($id_tipo_doc == 12) {
            $factura    = $this->carritoModel->obtenerOrdenE($id_factura);
            $articulos  = $this->carritoModel->obtenerOrdenArticulos($id_factura);
            $agent_fijo = $this->carritoModel->obtenerAgentesFijo(12);
            $planilla   = $this->carritoModel->obtenerPlanilla($id_factura);
            if ($planilla) {
                $data_comisiones_planillas = $this->carritoModel->obtenerComisionesPendientesPlanilla($id_factura, $id_tipo_doc, $planilla['po_preid']);
            }
        }

        if ($factura['estatus'] == 1) {
            return ['errors' => ['El documento no puede ser editado']];
        }

        $data_comisiones = $this->carritoModel->obtenerComisionesPendientes($id_factura, $id_tipo_doc);


        if (is_countable($articulos) && count($articulos)) {
            foreach ($articulos as $row) {
                $producto = $this->carritoModel->obtenerProducto($row['id_producto']);
                if ($producto['pro_tipo'] == 1 || $producto['pro_tipo'] == 2) {
                    $total_prosimple += $row['neto'];
                    $cantidad_prosimple += $row['cantidad'];
                    $costo_prosimple += $row['costo'] * $row['cantidad'];
                    $iva_totalsimple += $row['iva_total'];
                } else if ($producto['pro_tipo'] == 3) {
                    $total_proservicio += $row['neto'];
                    $cantidad_proservicio += $row['cantidad'];
                    $costo_proservicio += $row['costo'] * $row['cantidad'];
                    $iva_totalservicio += $row['iva_total'];
                }
            }
        }

        try {

            $this->carritoModel->transactionBegin();

            if (is_countable($agent_fijo) && count($agent_fijo)) {
                foreach ($agent_fijo as $row) {
                    if (!$this->carritoModel->obtenerAgenteComision($id_factura, $row['ecd_docid'], $row['empagentipo_agente'], $row['empagentipo_comid'])) {
                        if (($row['com_tipo'] == 1 || $row['com_tipo'] == 2) && $cantidad_prosimple > 0) {
                            //COMISION POR PRODUCTOS SIMPLES
                            $temp_porcentaje = $row['com_estatus'] == 1 ? $row['com_porcentaje'] : $row['empagentipo_porcentaje'];
                            if ($temp_porcentaje > 0) {
                                $formula = 0;
                                if ($row['com_formula'] == 1) {
                                    $formula = ($total_prosimple - $costo_prosimple) * ($temp_porcentaje / 100);
                                }
                                if ($row['com_formula'] == 2) {
                                    $formula = (($total_prosimple - $costo_prosimple) + $iva_totalsimple) * ($temp_porcentaje / 100);
                                }
                                if ($row['com_formula'] == 3) {
                                    $formula = $total_prosimple * ($temp_porcentaje / 100);
                                }
                                $this->carritoModel->guardar([
                                    'comagentefn_fnempagente' => $row['empagentipo_agente'],
                                    'comagentefn_com'         => $row['empagentipo_comid'],
                                    'comagentefn_monto'       => $formula,
                                    'comagentefn_divid'       => $factura['id_divisa'],
                                    'comagentefn_porcentaje'  => $temp_porcentaje,
                                    'comagentefn_fnid'        => $id_factura,
                                    'comagentefn_fntipo'      => $row['ecd_docid'],
                                    'comagentefn_fntotal'     => $total_prosimple,
                                    'comagentefn_fncantidad'  => $cantidad_prosimple
                                ], true, 'app_comisiones_agente_fn');
                            }
                        } elseif ($row['com_tipo'] == 3 && $cantidad_proservicio > 0) {
                            //COMISION POR SERVICIOS
                            $temp_porcentaje = $row['com_estatus'] == 1 ? $row['com_porcentaje'] : $row['empagentipo_porcentaje'];
                            if ($temp_porcentaje > 0) {

                                $formula = 0;
                                if ($row['com_formula'] == 1) {
                                    $formula = ($total_proservicio - $costo_proservicio) * ($temp_porcentaje / 100);
                                }
                                if ($row['com_formula'] == 2) {
                                    $formula = (($total_proservicio - $costo_proservicio) + $iva_totalservicio) * ($temp_porcentaje / 100);
                                }
                                if ($row['com_formula'] == 3) {
                                    $formula = $total_proservicio * ($temp_porcentaje / 100);
                                }

                                $this->carritoModel->guardar([
                                    'comagentefn_fnempagente' => $row['empagentipo_agente'],
                                    'comagentefn_com'         => $row['empagentipo_comid'],
                                    'comagentefn_monto'       => $formula,
                                    'comagentefn_divid'       => $factura['id_divisa'],
                                    'comagentefn_porcentaje'  => $temp_porcentaje,
                                    'comagentefn_fnid'        => $id_factura,
                                    'comagentefn_fntipo'      => $row['ecd_docid'],
                                    'comagentefn_fntotal'     => $total_proservicio,
                                    'comagentefn_fncantidad'  => $cantidad_proservicio
                                ], true, 'app_comisiones_agente_fn');
                            }
                        }
                    }
                }
            }

            $newAgent = new EmpleadoAgente();

            $agent = 0;
            if ($newAgent->consultar("SELECT * FROM app_empleados_agentes WHERE empagent_docid=$id_factura AND empagent_tipo=$id_tipo_doc")->row()) {
                $agente_b = $newAgent->consultar("SELECT * FROM app_empleados_agentes WHERE empagent_docid=$id_factura AND empagent_tipo=$id_tipo_doc")->row();
                $agent = $agente_b['empagent_empid'];
            }

            $comisiones = $this->carritoModel->obtenerComisionesAgente($agent);

            if (count($data_comisiones) > 0 && $agent > 0) {
                if (is_countable($data_comisiones) && count($data_comisiones)) {
                    foreach ($data_comisiones as $row) {
                        $comisiones = $this->carritoModel->obtenerComisionesAgente($agent);
                        if (is_countable($comisiones) && count($comisiones)) {
                            foreach ($comisiones as $row_com) {
                                if ($row_com['com_tipo'] == $row['com_tipo']) {
                                    if ($factura['id_divisa'] != $row['comagentefn_divid']) {
                                        $total_proservicio  = $this->obtenerPrecioSegunDivisa($total_proservicio, $factura['id_divisa'], $row['comagentefn_divid']);
                                        $total_prosimple    = $this->obtenerPrecioSegunDivisa($total_prosimple, $factura['id_divisa'], $row['comagentefn_divid']);
                                        $total_prosimple    = $total_prosimple['precio'];
                                        $total_proservicio  = $total_proservicio['precio'];
                                    }

                                    if ($row['com_tipo'] == 1 || $row['com_tipo'] == 2) {
                                        $formula = 0;
                                        if ($row['com_formula'] == 1) {
                                            $formula = ($total_prosimple - $costo_prosimple) *  ($row['comagentefn_porcentaje'] / 100);
                                        }
                                        if ($row['com_formula'] == 2) {
                                            $formula = (($total_prosimple - $costo_prosimple) + $iva_totalsimple) *  ($row['comagentefn_porcentaje'] / 100);
                                        }
                                        if ($row['com_formula'] == 3) {
                                            $formula = $total_prosimple *  ($row['comagentefn_porcentaje'] / 100);
                                        }
                                        $this->carritoModel->editar($row['comagentefn_id'], [
                                            'comagentefn_fntotal'       => $total_prosimple,
                                            'comagentefn_fncantidad'    => $cantidad_prosimple,
                                            'comagentefn_monto'         => round($formula, 2),
                                        ], 'app_comisiones_agente_fn', 'comagentefn_id');
                                    } elseif ($row['com_tipo'] == 3) {
                                        $formula = 0;
                                        if ($row['com_formula'] == 1) {
                                            $formula = ($total_proservicio - $costo_proservicio) * ($row['comagentefn_porcentaje'] / 100);
                                        }
                                        if ($row['com_formula'] == 2) {
                                            $formula = (($total_proservicio - $costo_proservicio) + $iva_totalservicio) * ($row['comagentefn_porcentaje'] / 100);
                                        }
                                        if ($row['com_formula'] == 3) {
                                            $formula = $total_proservicio * ($row['comagentefn_porcentaje'] / 100);
                                        }
                                        $this->carritoModel->editar($row['comagentefn_id'], [
                                            'comagentefn_fntotal'       => $total_proservicio,
                                            'comagentefn_fncantidad'    => $cantidad_proservicio,
                                            'comagentefn_monto'         => round($formula, 2),
                                        ], 'app_comisiones_agente_fn', 'comagentefn_id');
                                    }
                                } else {
                                    $comprobar = $this->carritoModel->obtenerComisionesPendientesCom($row_com['com_id'], $id_factura, $id_tipo_doc);
                                    if ($row_com['empagentipo_estatus'] == 1 && count($comprobar) == 0) {
                                        if (($row_com['com_tipo'] == 1 || $row_com['com_tipo'] == 2) && $cantidad_prosimple > 0) {
                                            //COMISION POR PRODUCTOS SIMPLES
                                            $temp_porcentaje = $row_com['com_estatus'] == 1 ? $row_com['com_porcentaje'] : $row_com['empagentipo_porcentaje'];
                                            if ($temp_porcentaje > 0) {
                                                $formula = 0;
                                                if ($row_com['com_formula'] == 1) {
                                                    $formula = ($total_prosimple - $costo_prosimple) * ($temp_porcentaje / 100);
                                                }
                                                if ($row_com['com_formula'] == 2) {
                                                    $formula = (($total_prosimple - $costo_prosimple) + $iva_totalsimple) * ($temp_porcentaje / 100);
                                                }
                                                if ($row_com['com_formula'] == 3) {
                                                    $formula = $total_prosimple * ($temp_porcentaje / 100);
                                                }

                                                $this->carritoModel->guardar([
                                                    'comagentefn_fnempagente' => $agent,
                                                    'comagentefn_com'         => $row_com['empagentipo_comid'],
                                                    'comagentefn_monto'       => $formula,
                                                    'comagentefn_divid'       => $factura['id_divisa'],
                                                    'comagentefn_porcentaje'  => $temp_porcentaje,
                                                    'comagentefn_fnid'        => $id_factura,
                                                    'comagentefn_fntipo'      => $id_tipo_doc,
                                                    'comagentefn_fntotal'     => $total_prosimple,
                                                    'comagentefn_fncantidad'  => $cantidad_prosimple
                                                ], true, 'app_comisiones_agente_fn');
                                            }
                                        } elseif ($row_com['com_tipo'] == 3 && $cantidad_proservicio > 0) {
                                            //COMISION POR SERVICIOS
                                            $temp_porcentaje = $row_com['com_estatus'] == 1 ? $row_com['com_porcentaje'] : $row_com['empagentipo_porcentaje'];
                                            if ($temp_porcentaje > 0) {

                                                $formula = 0;
                                                if ($row_com['com_formula'] == 1) {
                                                    $formula = ($total_proservicio - $costo_proservicio) * ($temp_porcentaje / 100);
                                                }
                                                if ($row_com['com_formula'] == 2) {
                                                    $formula = (($total_proservicio - $costo_proservicio) + $iva_totalservicio) * ($temp_porcentaje / 100);
                                                }
                                                if ($row_com['com_formula'] == 3) {
                                                    $formula = $total_proservicio * ($temp_porcentaje / 100);
                                                }

                                                $this->carritoModel->guardar([
                                                    'comagentefn_fnempagente' => $agent,
                                                    'comagentefn_com'         => $row_com['empagentipo_comid'],
                                                    'comagentefn_monto'       => $formula,
                                                    'comagentefn_divid'       => $factura['id_divisa'],
                                                    'comagentefn_porcentaje'  => $temp_porcentaje,
                                                    'comagentefn_fnid'        => $id_factura,
                                                    'comagentefn_fntipo'      => $id_tipo_doc,
                                                    'comagentefn_fntotal'     => $total_proservicio,
                                                    'comagentefn_fncantidad'  => $cantidad_proservicio
                                                ], true, 'app_comisiones_agente_fn');
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            } else {
                if (empty($data_comisiones) && $agent > 0) {
                    $comisiones = $this->carritoModel->obtenerComisionesAgente($agent);

                    if (is_countable($comisiones) && count($comisiones)) {
                        foreach ($comisiones as $row_com) {
                            if ($row_com['empagentipo_estatus'] == 1) {
                                if (($row_com['com_tipo'] == 1 || $row_com['com_tipo'] == 2) && $cantidad_prosimple > 0) {
                                    //COMISION POR PRODUCTOS SIMPLES
                                    $temp_porcentaje = $row_com['com_estatus'] == 1 ? $row_com['com_porcentaje'] : $row_com['empagentipo_porcentaje'];
                                    if ($temp_porcentaje > 0) {
                                        $formula = 0;
                                        if ($row_com['com_formula'] == 1) {
                                            $formula = ($total_prosimple - $costo_prosimple) * ($temp_porcentaje / 100);
                                        }
                                        if ($row_com['com_formula'] == 2) {
                                            $formula = (($total_prosimple - $costo_prosimple) + $iva_totalsimple) * ($temp_porcentaje / 100);
                                        }
                                        if ($row_com['com_formula'] == 3) {
                                            $formula = $total_prosimple * ($temp_porcentaje / 100);
                                        }

                                        $this->carritoModel->guardar([
                                            'comagentefn_fnempagente' => $agent,
                                            'comagentefn_com'         => $row_com['empagentipo_comid'],
                                            'comagentefn_monto'       => $formula,
                                            'comagentefn_divid'       => $factura['id_divisa'],
                                            'comagentefn_porcentaje'  => $temp_porcentaje,
                                            'comagentefn_fnid'        => $id_factura,
                                            'comagentefn_fntipo'      => $id_tipo_doc,
                                            'comagentefn_fntotal'     => $total_prosimple,
                                            'comagentefn_fncantidad'  => $cantidad_prosimple
                                        ], true, 'app_comisiones_agente_fn');
                                    }
                                } elseif ($row_com['com_tipo'] == 3 && $cantidad_proservicio > 0) {
                                    //COMISION POR SERVICIOS
                                    $temp_porcentaje = $row_com['com_estatus'] == 1 ? $row_com['com_porcentaje'] : $row_com['empagentipo_porcentaje'];
                                    if ($temp_porcentaje > 0) {

                                        $formula = 0;
                                        if ($row_com['com_formula'] == 1) {
                                            $formula = ($total_proservicio - $costo_proservicio) * ($temp_porcentaje / 100);
                                        }
                                        if ($row_com['com_formula'] == 2) {
                                            $formula = (($total_proservicio - $costo_proservicio) + $iva_totalservicio) * ($temp_porcentaje / 100);
                                        }
                                        if ($row_com['com_formula'] == 3) {
                                            $formula = $total_proservicio * ($temp_porcentaje / 100);
                                        }

                                        $this->carritoModel->guardar([
                                            'comagentefn_fnempagente' => $agent,
                                            'comagentefn_com'         => $row_com['empagentipo_comid'],
                                            'comagentefn_monto'       => $formula,
                                            'comagentefn_divid'       => $factura['id_divisa'],
                                            'comagentefn_porcentaje'  => $temp_porcentaje,
                                            'comagentefn_fnid'        => $id_factura,
                                            'comagentefn_fntipo'      => $id_tipo_doc,
                                            'comagentefn_fntotal'     => $total_proservicio,
                                            'comagentefn_fncantidad'  => $cantidad_proservicio
                                        ], true, 'app_comisiones_agente_fn');
                                    }
                                }
                            }
                        }
                    }
                }
            }

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

                foreach ($data_comisiones_planillas as $row) {

                    $data_servicio = $this->carritoModel->consultar("SELECT nart_proneto, nart_procantidad FROM app_orden_de_entrega_articulos WHERE nart_nid = {$planilla['po_nid']} AND nart_proid = {$row['comagentefn_planilla_servid']}")->row();

                    if ($factura['id_divisa'] != $row['comagentefn_divid']) {
                        $total_proservicio_planilla  = $this->obtenerPrecioSegunDivisa($data_servicio['nart_proneto'], $factura['id_divisa'], $row['comagentefn_divid']);
                        $total_proservicio_planilla  = $total_proservicio_planilla['precio'];
                    } else {
                        $total_proservicio_planilla = $data_servicio['nart_proneto'];
                    }

                    $this->carritoModel->editar($row['comagentefn_id'], [
                        'comagentefn_fntotal'       => $total_proservicio_planilla,
                        'comagentefn_fncantidad'    => $data_servicio['nart_procantidad'],
                        'comagentefn_monto'         => round(($total_proservicio_planilla * $row['comagentefn_porcentaje']) / 100, 2)
                    ], 'app_comisiones_agente_fn', 'comagentefn_id');
                }
            }

            $this->carritoModel->transactionCommit();
        } catch (\Throwable $th) {
            $this->carritoModel->transactionRollBack();
            $this->array_errors[] = 'Error en transacción';
        }

        if (empty($this->array_errors)) {
            return true;
        }

        return ['errors' => $this->array_errors];
    }

    public function agregaragente(int $id_factura, int $id_agente, int $id_comision, string $monto, int $tipo, int $id_divisa)
    {
        $new_registro_comisiones_agente = new EmpleadosComisionesEmplAgente();
        $newComision = new Comisiones();
        //$datos_comision_editar = $new_registro_comisiones_agente->obtenerComisionAgentefnPendiente($id_factura, $tipo, $id_agente, $id_comision);
        $monto = convertir_a_float($monto);

        if ($monto <= 0) {
            return ['errors' => ['Lo siento el monto debe ser mayor que cero']];
        }

        $data_comision = $newComision->obtener($id_comision);

        $data_conf_com_emp = $newComision->consultar("SELECT * FROM app_empleados_agentes_tipo_comision WHERE empagentipo_comid = $id_comision AND empagentipo_agente = $id_agente")->row();

        if ($data_conf_com_emp['empagentipo_estatus'] == 0) {
            return ['El empleado no tiene activa esta comision'];
        }

        $total_prosimple = 0;
        $total_procompuesto = 0;
        $total_proservicio = 0;
        $cantidad_prosimple = 0;
        $cantidad_procompuesto = 0;
        $cantidad_proservicio = 0;

        if ($tipo == 1) {
            $factura = $this->carritoModel->obtenerNe($id_factura);
            $articulos = $this->carritoModel->obtenerNeArticulos($id_factura);
        } else {
            $factura = $this->carritoModel->obtenerFac($id_factura);
            $articulos = $this->carritoModel->obtenerFacArticulos($id_factura);
        }

        //$total_factura = $factura['total'];
        //$cantidad_articulos_facturado = $factura['art_total'];

        if (is_countable($articulos) && count($articulos)) {
            foreach ($articulos as $row) {
                $producto = $this->carritoModel->obtenerProducto($row['id_producto']);
                if ($producto['pro_tipo'] == 1 || $producto['pro_tipo'] == 2) {
                    $total_prosimple += $row['neto'];
                    $cantidad_prosimple += $row['cantidad'];
                } else if ($producto['pro_tipo'] == 3) {
                    $total_proservicio += $row['neto'];
                    $cantidad_proservicio += $row['cantidad'];
                }
            }
        }

        if ($factura['id_divisa'] != $id_divisa) {
            $total_proservicio = $this->obtenerPrecioSegunDivisa($total_proservicio, $factura['id_divisa'], $id_divisa);
            $total_prosimple = $this->obtenerPrecioSegunDivisa($total_prosimple, $factura['id_divisa'], $id_divisa);
            $total_prosimple = $total_prosimple['precio'];
            $total_proservicio = $total_proservicio['precio'];
        }

        //$temp_porcentaje = $data_comision['com_estatus'] == 1 ? $row['com_porcentaje'] : $row['empagentipo_porcentaje'];

        if ($data_comision['com_tipo'] == 1 || $data_comision['com_tipo'] == 2) {
            if ($cantidad_prosimple > 0) {
                return $new_registro_comisiones_agente->guardar([
                    'comagentefn_fnempagente' => $id_agente,
                    'comagentefn_com'         => $id_comision,
                    'comagentefn_monto'       => $monto,
                    'comagentefn_divid'       => $id_divisa,
                    'comagentefn_estatus'     => 0,
                    'comagentefn_porcentaje'  => round(($monto * 100) / $total_prosimple, 2),
                    'comagentefn_fnid'        => $id_factura,
                    'comagentefn_fntipo'      => $tipo,
                    'comagentefn_fntotal'     => $total_prosimple,
                    'comagentefn_fncantidad'  => $cantidad_prosimple
                ], true);
            } else {
                return ['errors' => ['No hay ningun producto registrado en la documento para aplicar esta comision.']];
            }
        } else if ($data_comision['com_tipo'] == 3) {
            if ($cantidad_proservicio > 0) {
                return $new_registro_comisiones_agente->guardar([
                    'comagentefn_fnempagente' => $id_agente,
                    'comagentefn_com'         => $id_comision,
                    'comagentefn_monto'       => $monto,
                    'comagentefn_estatus'     => 0,
                    'comagentefn_divid'       => $id_divisa,
                    'comagentefn_porcentaje'  => round(($monto * 100) / $total_proservicio, 2),
                    'comagentefn_fnid'        => $id_factura,
                    'comagentefn_fntipo'      => $tipo,
                    'comagentefn_fntotal'     => $total_proservicio,
                    'comagentefn_fncantidad'  => $cantidad_proservicio
                ], true);
            } else {
                return ['errors' => ['No hay ningun Servicio registrado en la factura para aplicar esta comision.']];
            }
        }
    }

    public function editarComisionPendiente(int $id_comision, string $porcentaje, string $monto)
    {
        $new_comempl = new EmpleadosComisionesEmplAgente();
        $porcentaje = convertir_a_float($porcentaje);
        $monto = convertir_a_float($monto);

        if ($monto <= 0) {
            $this->array_errors[] = 'El monto a pagar no puede quedar en 0';
        } else {

            $data_comision = $new_comempl->obtener($id_comision);

            if ($data_comision['comagentefn_fntipo'] == 1) {
                $factura = $this->carritoModel->obtenerNe($data_comision['comagentefn_fnid']);
            } elseif ($data_comision['comagentefn_fntipo'] == 2) {
                $factura = $this->carritoModel->obtenerFac($data_comision['comagentefn_fnid']);
            } elseif ($data_comision['comagentefn_fntipo'] == 12) {
                $factura = $this->carritoModel->obtenerOrdenE($data_comision['comagentefn_fnid']);
            }

            if ($factura['estatus'] == 1)
                return ['errors' => ['EL documento no puede ser editado']];

            if ($new_comempl->existe('comagentefn_id', $id_comision)) {
                if ($new_comempl->editar($id_comision, [
                    'comagentefn_monto' => $monto,
                    'comagentefn_porcentaje'  => $porcentaje,
                ], true)) {
                    return true;
                } else {
                    return false;
                }
            } else {
                $this->array_errors[] = 'Acción prohibida';
            }
        }

        return ['errors' => $this->array_errors];
    }

    public function obtenerComisionesPendiente(int $id_factura, int $tipo)
    {
        $new_comisiones_agentes = new EmpleadosComisionesEmplAgente();
        $comisiones = $new_comisiones_agentes->obtenerComisionFactNotaPendiente($id_factura, $tipo);
        $array_comisiones_agente = [];

        if ($tipo == 1) {
            $dac_doc = $this->carritoModel->obtenerNe($id_factura);
        } elseif ($tipo == 2) {
            $dac_doc = $this->carritoModel->obtenerFac($id_factura);
        } elseif ($tipo == 12) {
            $dac_doc = $this->carritoModel->obtenerOrdenE($id_factura);
        }

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

            foreach ($comisiones as $row) {

                if (!empty($row['comagentefn_divid'])) {
                    $div_doc = Moneda::obtenerDivisa($row['comagentefn_divid']);
                } else {
                    $div_doc = Moneda::obtenerDivisa($dac_doc['id_divisa']);
                }

                if ($row['comagentefn_estatus'] == 1)
                    $estatus = 'Pagado';
                if ($row['comagentefn_estatus'] == 0)
                    $estatus = 'Pendiente';

                $array_comisiones_agente[] = [
                    'id'            => $row['comagentefn_id'],
                    'estatus'       => $estatus,
                    'agente_nombre' => $row['einfo_nombres'] . ' ' . $row['einfo_apellidos'],
                    'id_comision'   => $row['com_id'],
                    'comision'      => $row['com_descripcion'],
                    'total'         => $row['comagentefn_fntotal'],
                    'total_moneda'  => Moneda::moneda($row['comagentefn_fntotal'], $div_doc['locale'], $div_doc['symbol']),
                    'porcentaje'    => round($row['comagentefn_porcentaje'], 2),
                    'monto'         => $row['comagentefn_monto'],
                    'monto_moneda'  => Moneda::moneda($row['comagentefn_monto'], $div_doc['locale'], $div_doc['symbol']),
                    'servicio_producto' => $row['pro_descripcion']
                ];
            }
        }

        return $array_comisiones_agente;
    }

    public function actualizarPrecios(int $id_factura, int $id_cliente, string $_nombre_carrito_, string $descuento_global)
    {
        $contenido_carrito = $this->contenidoCarrito($_nombre_carrito_, $id_factura);
        $descuento_global = convertir_a_float($descuento_global);
        $total_cos_servicios = $total_cos = 0;

        foreach ($contenido_carrito as $row) {

            $pro_data = $this->carritoModel->obtenerProducto($row['id']);

            $divisa_factor = $this->carritoModel->obtenerProductoFactor($row['id']);

            if ($divisa_factor) {
                $precio = $this->obtenerPrecioSegunDivisaFactorProducto($divisa_factor['profac_bifac_serial'], $pro_data['pro_precio'], $this->divisa_master['id'], $_SESSION["$_nombre_carrito_$id_factura"]['divisa']);
                $costo = $this->obtenerPrecioSegunDivisaFactorProducto($divisa_factor['profac_bifac_serial'], $pro_data['pro_costo'], $this->divisa_master['id'], $_SESSION["$_nombre_carrito_$id_factura"]['divisa']);
            } else {
                $precio = $this->obtenerPrecioSegunDivisa($pro_data['pro_precio'], $this->divisa_master['id'], $_SESSION["$_nombre_carrito_$id_factura"]['divisa']);
                $costo = $this->obtenerPrecioSegunDivisa($pro_data['pro_costo'], $this->divisa_master['id'], $_SESSION["$_nombre_carrito_$id_factura"]['divisa']);
            }

            $_SESSION["$_nombre_carrito_$id_factura"][$row['unique']]['precio'] = $precio['precio'];
            $pc = $_SESSION["$_nombre_carrito_$id_factura"][$row['unique']]['cantidad'] * $_SESSION["$_nombre_carrito_$id_factura"][$row['unique']]['precio'];
            $precio = $this->obtenerDescuentoMasIvaProducto($pc, $row['iva'], 'pvp', $_SESSION["$_nombre_carrito_$id_factura"][$row['unique']]['descuento']);
            $_SESSION["$_nombre_carrito_$id_factura"][$row['unique']]['iva_total']      = $precio['iva'];
            $_SESSION["$_nombre_carrito_$id_factura"][$row['unique']]['neto']           = $precio['neto'];
            $_SESSION["$_nombre_carrito_$id_factura"][$row['unique']]['total']          = $precio['total'];
            $_SESSION["$_nombre_carrito_$id_factura"][$row['unique']]['tarifa']         = '';

            if ($pro_data['pro_tipo'] == 3) {
                $total_cos_servicios += $costo['precio'];
            } else {
                $total_cos += $costo['precio'];
            }
        }

        $_SESSION["$_nombre_carrito_$id_factura"][$row['unique']]['costo']          = $total_cos;
        $_SESSION["$_nombre_carrito_$id_factura"][$row['unique']]['costo_servicio'] = $total_cos_servicios;

        return $this->obtenerCarritoCliente($_nombre_carrito_, $id_factura, $id_cliente, $descuento_global);
    }

    public function guardarVenta(int $id_factura, int $id_tipo_doc, bool $caja = false)
    {
        if ($id_tipo_doc == 1) {
            $factura    = $this->carritoModel->obtenerNe($id_factura);
            $articulos  = $this->carritoModel->obtenerNeArticulos($id_factura);
            $agent_fijo = $this->carritoModel->obtenerAgentesFijo($id_tipo_doc);
        } elseif ($id_tipo_doc == 2) {
            $factura    = $this->carritoModel->obtenerFac($id_factura);
            $articulos  = $this->carritoModel->obtenerFacArticulos($id_factura);
            $agent_fijo = $this->carritoModel->obtenerAgentesFijo($id_tipo_doc);
        } elseif ($id_tipo_doc == 12) {
            $factura    = $this->carritoModel->obtenerOrdenE($id_factura);
            $articulos  = $this->carritoModel->obtenerOrdenArticulos($id_factura);
            $agent_fijo = $this->carritoModel->obtenerAgentesFijo($id_tipo_doc);
            $planilla   = $this->carritoModel->obtenerPlanilla($id_factura);
            if ($planilla) {
                $data_comisiones_planillas = $this->carritoModel->obtenerComisionesPendientesPlanilla($id_factura, $id_tipo_doc, $planilla['po_preid']);
            }
        }
    }

    public function obtenerDocumentosPendientesPorPagarPorCliente(int $id_cliente)
    {
        $array_factura = [];
        $array_notas = [];
        $array_ordenes = [];
        $ventas_pendientes = 0;
        $totales_divisas = [];
        $facturas_divisas = [];
        $facturas_divisas_id = [];
        $notas_divisas = [];
        $notas_divisas_id = [];
        $ordenes_divisas = [];
        $ordenes_divisas_id = [];
        $totales_divisas = [];
        $total_divisa_id = [];
        $total_p = 0;

        $facturas = $this->carritoModel->obtenerFacturasPendientesClient($id_cliente);
        $notas = $this->carritoModel->obtenerNotasdeentregaPendienteClient($id_cliente);
        $ordenes = $this->carritoModel->obtenerOrdendeentregaPendienteClient($id_cliente);

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

            foreach ($facturas as $row) {

                $acumulado = $this->carritoModel->obtenerAcumuladofno($row['fm_id'], 2);
                $acumulado_total = ($acumulado['total']) ?? 0;

                $array_factura[] = [
                    'dni'           => $row['cli_dni'],
                    'nombrecompl'   => $row['cli_razon_social'],
                    'id'            => $row['fm_id'],
                    'correlativo'   => $row['fm_correlativo'],
                    'divisa'        => $row['div_nombre'],
                    'div_locale'    => $row['div_locale'],
                    'div_simbolo'   => $row['div_simbolo'],
                    'total'         => $row['fm_total'],
                    'estatus'       => $row['fm_estatus'],
                    'fecha'         => $row['fecha'],
                    'acumulado'     => $acumulado_total,
                    'pendiente'     => $row['fm_total'] - $acumulado_total
                ];

                $ventas_pendientes += 1;

                if (!in_array($row['div_id'], $facturas_divisas_id)) {
                    $facturas_divisas[$row['div_id']] = [
                        'div_id'        => $row['div_id'],
                        'div_nombre'    => $row['div_nombre'],
                        'div_locale'    => $row['div_locale'],
                        'div_simbolo'   => $row['div_simbolo'],
                        'total'         => round(($row['fm_total'] - $acumulado_total), 2),
                    ];
                    $facturas_divisas_id[] = $row['div_id'];
                } else {
                    $facturas_divisas[$row['div_id']]['total'] += $row['fm_total'] - $acumulado_total;
                }
            }
        }

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

            foreach ($notas as $row) {

                $acumulado = $this->carritoModel->obtenerAcumuladofno($row['ne_id'], 1);
                $acumulado_total = ($acumulado['total']) ?? 0;

                $array_notas[] = [
                    'dni'           => $row['cli_dni'],
                    'nombrecompl'   => $row['cli_razon_social'],
                    'id'            => $row['ne_id'],
                    'correlativo'   => $row['ne_correlativo'],
                    'divisa'        => $row['div_nombre'],
                    'div_locale'    => $row['div_locale'],
                    'div_simbolo'   => $row['div_simbolo'],
                    'total'         => $row['ne_total'],
                    'estatus'       => $row['ne_estatus'],
                    'fecha'         => $row['fecha'],
                    'acumulado'     => $acumulado_total,
                    'pendiente'     => $row['ne_total'] - $acumulado_total
                ];

                $ventas_pendientes += 1;

                if (!in_array($row['div_id'], $notas_divisas_id)) {
                    $notas_divisas[$row['div_id']] = [
                        'div_id'        => $row['div_id'],
                        'div_nombre'    => $row['div_nombre'],
                        'div_locale'    => $row['div_locale'],
                        'div_simbolo'   => $row['div_simbolo'],
                        'total'         => $row['ne_total'] - $acumulado_total
                    ];
                    $notas_divisas_id[] = $row['div_id'];
                } else {
                    $notas_divisas[$row['div_id']]['total'] += $row['ne_total'] - $acumulado_total;
                }
            }
        }

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

            foreach ($ordenes as $row) {

                $acumulado = $this->carritoModel->obtenerAcumuladofno($row['n_id'], 12);
                $acumulado_total = ($acumulado['total']) ?? 0;

                $array_ordenes[] = [
                    'dni'           => $row['cli_dni'],
                    'nombrecompl'   => $row['cli_razon_social'],
                    'id'            => $row['n_id'],
                    'correlativo'   => $row['n_correlativo'],
                    'divisa'        => $row['div_nombre'],
                    'div_locale'    => $row['div_locale'],
                    'div_simbolo'   => $row['div_simbolo'],
                    'total'         => $row['n_total'],
                    'estatus'       => $row['n_estatus'],
                    'fecha'         => $row['fecha'],
                    'acumulado'     => $acumulado_total,
                    'pendiente'     => $row['n_total'] - $acumulado_total
                ];

                $ventas_pendientes += 1;

                if (!in_array($row['div_id'], $ordenes_divisas_id)) {
                    $ordenes_divisas[$row['div_id']] = [
                        'div_id'        => $row['div_id'],
                        'div_nombre'    => $row['div_nombre'],
                        'div_locale'    => $row['div_locale'],
                        'div_simbolo'   => $row['div_simbolo'],
                        'total'         => $row['n_total'] - $acumulado_total
                    ];
                    $ordenes_divisas_id[] = $row['div_id'];
                } else {
                    $ordenes_divisas[$row['div_id']]['total'] += $row['n_total'] - $acumulado_total;
                }
            }
        }

        if (is_countable($facturas_divisas) && count($facturas_divisas)) {
            foreach ($facturas_divisas as $row) {
                if (!in_array($row['div_id'], $total_divisa_id)) {
                    $totales_divisas[$row['div_id']] = [
                        'div_id'        => $row['div_id'],
                        'div_nombre'    => $row['div_nombre'],
                        'div_locale'    => $row['div_locale'],
                        'div_simbolo'   => $row['div_simbolo'],
                        'total'         => $row['total'],
                    ];
                    $total_divisa_id[] = $row['div_id'];
                } else {
                    $totales_divisas[$row['div_id']]['total'] += $row['total'];
                }

                if ($row['div_id'] !== $this->divisa_master['id']) {
                    $divisa_factor = $this->carritoModel->obtenerDivisaAlCambio($row['div_id'], $this->divisa_master['id']);
                    $factor = $divisa_factor['df_factor'];
                } else {
                    $factor = 1;
                }
                $total_p += $row['total'] * $factor;
            }
        }

        if (is_countable($notas_divisas) && count($notas_divisas)) {
            foreach ($notas_divisas as $row) {
                if (!in_array($row['div_id'], $total_divisa_id)) {
                    $totales_divisas[$row['div_id']] = [
                        'div_id'        => $row['div_id'],
                        'div_nombre'    => $row['div_nombre'],
                        'div_locale'    => $row['div_locale'],
                        'div_simbolo'   => $row['div_simbolo'],
                        'total'         => $row['total'],
                    ];
                    $total_divisa_id[] = $row['div_id'];
                } else {
                    $totales_divisas[$row['div_id']]['total'] += $row['total'];
                }

                if ($row['div_id'] !== $this->divisa_master['id']) {
                    $divisa_factor = $this->carritoModel->obtenerDivisaAlCambio($row['div_id'], $this->divisa_master['id']);
                    $factor = $divisa_factor['df_factor'];
                } else {
                    $factor = 1;
                }
                $total_p += $row['total'] * $factor;
            }
        }

        if (is_countable($ordenes_divisas) && count($ordenes_divisas)) {
            foreach ($ordenes_divisas as $row) {
                if (!in_array($row['div_id'], $total_divisa_id)) {
                    $totales_divisas[$row['div_id']] = [
                        'div_id'        => $row['div_id'],
                        'div_nombre'    => $row['div_nombre'],
                        'div_locale'    => $row['div_locale'],
                        'div_simbolo'   => $row['div_simbolo'],
                        'total'         => $row['total'],
                    ];
                    $total_divisa_id[] = $row['div_id'];
                } else {
                    $totales_divisas[$row['div_id']]['total'] += $row['total'];
                }

                if ($row['div_id'] !== $this->divisa_master['id']) {
                    $divisa_factor = $this->carritoModel->obtenerDivisaAlCambio($row['div_id'], $this->divisa_master['id']);
                    $factor = $divisa_factor['df_factor'];
                } else {
                    $factor = 1;
                }
                $total_p += $row['total'] * $factor;
            }
        }

        return [
            'facturas_pendiente'    => $array_factura,
            'total'                 => $total_p,
            'notas_pendiente'       => $array_notas,
            'ordenes_pendientes'    => $array_ordenes,
            'totales_divisas_ord'   => $ordenes_divisas,
            'totales_divisas_fac'   => $facturas_divisas,
            'totales_divisas_not'   => $notas_divisas,
            'divisas_totales'       => $totales_divisas,
        ];
    }
}
