<?php

namespace App\Models;

use DB;
use App\Models\Bodega;
use App\Models\Cliente;
use App\Models\FormaPago;
use App\Models\AreaNegocio;
use App\Models\Ctacte;
use App\Models\Producto;
use App\Traits\Foliable;
//use App\Traits\Abstrahere;
use App\Api\AbstrahereApi;

class Boleta {
    use Foliable;
    //use Abstrahere;


    const BOLETA_AFECTA = 39;
    const BOLETA_EXENTA = 41;

    public function __construct(
            $id_empresa,
            $rut_empresa,
            $rut_usuario,
            $item,
            $receptor,
            $monto_neto,
            $monto_exento,
            $descuento,
            $montoNoFacturable,
            $tipo_documento,
            $area_negocio,
            $observacion,
            $direccion,
            array $detalles,
            array $adicionales
        )
    {
        $this->id_empresa = $id_empresa;
        $this->rut_empresa = $rut_empresa;
        $this->rut_usuario = $rut_usuario;
        $this->item = $item;
        $this->emisor = $this->obtenDatosEmisor($rut_empresa);
        $this->receptor = Cliente::obtenCliente(
            trim(strtoupper($receptor)),
            $rut_empresa,
            $direccion
        );

        $this->monto_neto = $monto_neto;
        $this->monto_exento = $monto_exento;
        $this->descuento = $descuento;
        $this->montoNoFacturable = $montoNoFacturable;
        $this->tipo_documento = $tipo_documento;
        $this->area_negocio = $area_negocio;
        $this->observacion = $observacion;
        $this->detalles = $detalles;
        $this->totalDetalle = 0;
        $this->adicionales = $adicionales;

        $this->montos_totales = $this->calculaTotalesBoleta(
            $this->tipo_documento,
            $this->monto_neto,
            $this->descuento
        );

    }

    protected function fallo($mensaje, $rollback = true, $registra_folio = true)
    {
        if($registra_folio){
            $this->registraFolioSinOcupar($this->rut_empresa, $this->tipo_documento, $this->folio);
        }
        if($rollback){
            $this->rollback();
        }
        return ['mensaje' => $mensaje];
    }

    public function ingresarBoleta()
    {
        
        if(is_null($this->receptor)) {
            return $this->fallo('Receptor invalido.', false, false);
        }


        $formaPago = FormaPago::obtenFormaPago($this->adicionales['Uno'], $this->rut_empresa);
        if(is_null($formaPago)) {
            return $this->fallo('Envio:'.$this->item.'-Forma de pago '.$this->adicionales['Uno'].' invalida.', false, false);
        }

        $areaNegocio = AreaNegocio::obtenAreaNegocio($this->area_negocio, $this->rut_empresa);
        if(is_null($areaNegocio)) {
            return $this->fallo('Envio:'.$this->item.'-Area de Negocio '.$this->area_negocio.' invalida.', false, false);
        }

        if (empty($this->folio)) {
            do {

                $this->folio = $this->obtenFolio(
                    $this->rut_empresa,
                    $this->tipo_documento
                );

                $existe_folio = $this->existeFolio($this->rut_empresa, $this->tipo_documento, $this->folio);
                //dd($existe_folio,$this->rut_empresa, $this->tipo_documento, $this->folio);
            } while ($existe_folio);

        }else{
            $existe_folio = $this->existeFolio($this->rut_empresa, $this->tipo_documento, $this->folio);
            if($existe_folio) {
                return $this->fallo('Envio:'.$this->item.'-Ya existe folio '.$this->folio.' tipo: '.$this->tipo_documento.'.', false, true);
            }

        }

        if(is_null($this->folio)) {
            return $this->fallo('Envio:'.$this->item.'-No se pudo obtener folio.', false, true);
        }


        /*$listaWopy = array('7790060-8','12605444-0','11224204-K','76130428-3','9449854-6','12044206-6','7154576-8','51010690-3','7392686-6','9238254-0','11265975-7','10388058-0','76575457-7','6961294-6','6526974-0','53301578-6','19057323-0','13303204-5','76397613-0','12229273-8','77013687-3','17523771-2','76071207-8','77118119-8','8052912-0','76862736-3','6543929-8','10809652-7','6629610-5');
        if (in_array($this->rut_empresa, $listaWopy)) {

            //validar que el folio este disponible en el listado de caf
            $estadoCaf = $this->validaCaf($this->rut_empresa, $this->tipo_documento);    
            
            if($estadoCaf){
                return $this->fallo('Envio:'.$this->item.'- Caf fuera de rango para generar dte folio '.$this->folio.' tipo '.$this->tipo_documento.'.', true, false);
            }
        }*/
        
        $listaWopy = array('22222222-2','12229273-8','76426270-0','7790060-8','12605444-0','11224204-K','76130428-3','9449854-6','12044206-6','7154576-8','51010690-3','7392686-6','9238254-0','11265975-7','10388058-0','76575457-7','6961294-6','6526974-0','53301578-6','19057323-0','13303204-5','76397613-0','12229273-8','77013687-3','17523771-2','76071207-8','77118119-8','8052912-0','76862736-3','6543929-8','10809652-7','6629610-5');
        //$listaWopy = array('22222222-2','12229273-8','76426270-0');
        if (in_array($this->rut_empresa, $listaWopy)) {

            //validar que el folio este disponible en el listado de caf
            $estadoCaf = $this->validaCaf($this->rut_empresa, $this->tipo_documento);    
            
            if($estadoCaf){
                return $this->fallo('Envio:'.$this->item.'- Caf fuera de rango para generar dte folio '.$this->folio.' tipo '.$this->tipo_documento.'.', true, true);
            }
        }

        $this->adicionales['Uno'] = $formaPago->NOMBRE_CPAGO;
        $this->adicionales['Siete'] = isset($this->observacion) ? $this->observacion : '';
        $this->adicionales['Treintayuno'] = $this->receptor->TELEFONO_CLIENTEPROVEEDOR;
        $this->adicionales['Treintaydos'] = $this->receptor->FAX_CLIENTEPROVEEDOR;

        $datos_xml = [
            'TipoDTE' => $this->tipo_documento,
            'Folio' => $this->folio,
            'RUTEmisor' => trim(strtoupper($this->rut_empresa)),
            'RznSoc' => $this->emisor->razon,
			'GiroEmis' => $this->emisor->giro1,
			'Telefono' => $this->emisor->telefono,
			'Acteco' => $this->emisor->codigo1,
			'DirOrigen' => $this->emisor->direccion,
			'CmnaOrigen' => $this->emisor->comuna,
			'CiudadOrigen' => $this->emisor->ciudad,
            'RUTRecep' => trim(strtoupper($this->receptor->RUT_CLIENTEPROVEEDOR)),
            'RznSocRecep' => $this->receptor->RZ_CLIENTEPROVEEDOR,
            'GiroRecep' => $this->receptor->GIRO_CLIENTEPROVEEDOR,
            'DirRecep' => $this->receptor->DIRECCION_DIRECCION,
            'CmnaRecep' => $this->receptor->ID_COMUNA,
            'CiudadRecep' => $this->receptor->ID_CIUDAD,
            'MntNeto' => round(($this->montos_totales['neto']), 0, PHP_ROUND_HALF_UP),
            'MntExento' => round(($this->montos_totales['exento']), 0, PHP_ROUND_HALF_UP),
            'MntIva' => round(($this->montos_totales['iva']), 0, PHP_ROUND_HALF_UP),
            'MntTotal' => round(($this->montos_totales['total']), 0, PHP_ROUND_HALF_UP),
            'MontoNF' => round((isset($this->montoNoFacturable) ? $this->montoNoFacturable :'0'), 0, PHP_ROUND_HALF_UP),

            'Detalles' => [],
        ];
        
        //validar que no repita
        $existe_folio = $this->existeFolio($this->rut_empresa, $this->tipo_documento, $this->folio);
        if($existe_folio) {
            return $this->fallo('Envio:'.$this->item.'-Ya existe folio '.$this->folio.' tipo: '.$this->tipo_documento);
        }

        $id_ingreso_lv = $this->ingresoLibroVentas($formaPago);
        if(!$id_ingreso_lv){
            return $this->fallo('Envio:'.$this->item.'-Excepción al ingresar datos libro ventas.');
        }
        if(!$this->ingresoCtaCte($id_ingreso_lv)){
            return $this->fallo('Envio:'.$this->item.'-No se pudo realizar ingreso en ctacte.');
        }

        if ($this->descuento > 0) {
            if(!$this->ingresoDescGlobal()){
                return $this->fallo('Envio:'.$this->item.'-No se pudo realizar ingreso en descuento global.');
            }
        }

        if(!$this->ingresoDirLibroVenta()){
            return $this->fallo('Envio:'.$this->item.'-No se pudo realizar ingreso en direccion libro de ventas.');
        }

        if(isset($this->adicionales['Treinta'])){
            if(!$this->ingresoAdicionalDonacion()){
                return $this->fallo('Envio:'.$this->item.'-No se pudo realizar ingreso de los campos adicionales.');
            }
        }

        $totalDetalle = 0;
        $totalExentoDetalle = 0;
        foreach($this->detalles as $detalle){

            $bodega = Bodega::obtenBodega($detalle['Bodega'], $this->rut_empresa);
            if(is_null($bodega)){
                return $this->fallo('Envio:'.$this->item.'-Bodega '.$detalle['Bodega'].' invalida.');
            }

            $producto = Producto::obtenProducto($detalle['Codigo'], $this->rut_empresa);

            if(is_null($producto)){
                return $this->fallo('Envio:'.$this->item.'-Producto '.$detalle['Codigo'].' No existe.');
            }

            if( $producto->ESTADO_PRODUCTO != 1 ){
                return $this->fallo('Envio:'.$this->item.'-Producto '.$detalle['Codigo'].' Se encuentra desactivado.');
            }

            if( $detalle['Cantidad'] <= 0 ){
                return $this->fallo('Envio:'.$this->item.'-Producto '.$detalle['Codigo'].' Cantidad debe ser mayor a 0.');
            }

            $detalle['Precio'] = !isset($detalle['Precio']) ? $producto->VALOR_PRODUCTO : $detalle['Precio'];

            if( $detalle['Precio'] <= 0 ){
                return $this->fallo('Envio:'.$this->item.'-Producto '.$detalle['Codigo'].' Precio debe ser mayor a 0.');
            }

            if($detalle['Afecto']){
                $exento = 0;
                $neto = round(($detalle['Precio'] * $detalle['Cantidad']), 0, PHP_ROUND_HALF_UP);
                $total = round(($neto - $detalle['Descuento']), 0, PHP_ROUND_HALF_UP);
                $id_usuario = '';

            }
            else {
                $exento = round(($detalle['Precio'] * $detalle['Cantidad']), 0, PHP_ROUND_HALF_UP);
                $neto = 0;
                $total = round(($exento - $detalle['Descuento']), 0, PHP_ROUND_HALF_UP);
                $id_usuario = 'x';
            }
            $totalDetalle += $total;

            $confDecimal = $this->confDecimalDetalle();
            
            $datos_xml['Detalles'][] = [
                'VlrCodigo' => $producto->CODIGO_PRODUCTO,
                'NmbItem' => $producto->DESCRIPCION_PRODUCTO,
                'QtyItem' => round($detalle['Cantidad'], $confDecimal->ADICIONAL3, PHP_ROUND_HALF_UP),
                'UnmdItem' => $producto->NOMBRE,
                'PrcItem' => round($detalle['Precio'], $confDecimal->ADICIONAL4, PHP_ROUND_HALF_UP),
                'MontoItem' => $total,
            ];
            
            if(!$this->ingresaDetalleDoc2($detalle, $producto, $exento, $neto, $total, $id_usuario)){
                return $this->fallo('Envio:'.$this->item.'-No se pudo realizar el ingreso de detalle.');
            }

            if(!$this->ingresoDetalleInvProductos($producto, $detalle, $bodega)){
                return $this->fallo('Envio:'.$this->item.'-No se pudo realizar el ingreso de detalle de inventario.');
            }


        }

        if (empty($totalDetalle)) {
            return $this->fallo('Envio:'.$this->item.'-Total del detalle no debe ser 0.');
        }

        if($totalDetalle != $this->monto_neto AND $id_usuario ==''){
            return $this->fallo('Envio:'.$this->item.'-MontoNeto no coincide con sumatoria de detalles, valor debería ser: '.$totalDetalle.'.');
        }
        
        //validar que el folio exista solo una vez


        $abstrahere = new AbstrahereApi($this->rut_empresa, $this->rut_usuario);
        
        $adicional_xml = $this->generaXmlAdicionalesApi($this->adicionales);
        $datapost = $this->generaXml($datos_xml,$adicional_xml);
        
        $xml = json_decode($abstrahere->POST("/xmls", $datapost));

        if(empty($xml->folio)){
            return $this->fallo('Envio: '.$this->item.'- Error al generar documento, tipo:'.$this->tipo_documento.' folio: '.$this->folio.' '.json_encode($xml),false, false);
        }

        $urlPDF = '';
        $url = '/pdfs/'.$this->rut_empresa.'/'.$this->tipo_documento.'/'.$this->folio;
        $header_opcional = 'idImpreso: 1';

        $xml_pdf = $abstrahere->GET($url,$header_opcional);
        $xml_pdf = $abstrahere->JSON_TO_ARRAY($xml_pdf);
        if (!empty($xml_pdf['signedURL'])) {
            $urlPDF = $xml_pdf['signedURL'];
        }
        
        
        $timbre = '';
        $url = '/timbres/'.$this->rut_empresa.'/'.$this->tipo_documento.'/'.$this->folio;
        $timbre = $abstrahere->GET($url);
        $timbre = $abstrahere->JSON_TO_ARRAY($timbre);
        if (!empty($timbre['signedURL'])) {
            $timbre = $timbre['signedURL'];
        }
        
        
        
        return [
            'Envio' => $this->item, 
            'mensaje' => 'Item guardado con exito.',
            'folio' => $this->folio,
            'pdf' => $urlPDF,
            'urlTimbre' => $timbre,
        ];


    }

    protected function ingresoLibroVentas($formaPago)
    {
        try{
        $ingreso = DB::table('libro_ventas')
            ->insertGetId([
                'rut' => $this->rut_empresa,
                'mes' => date('m', time()),
                'fecha' => date('Y-m-d', time()),
                'typo_doc' => $this->tipo_documento,
                'n_doc' => $this->folio,
                'rut_c' => strtoupper($this->receptor->RUT_CLIENTEPROVEEDOR),
                'nombre_c' => $this->receptor->RZ_CLIENTEPROVEEDOR,
                'EXENTO_LVENTA' => $this->formateaNumero($this->montos_totales['exento']),
                'DESCUENTO_LVENTA' => $this->formateaNumero($this->descuento),
                'ESPECIFICO_LVENTA' => 0,
                'valor_n' => $this->formateaNumero($this->montos_totales['neto']),
                'valor_i' => $this->formateaNumero($this->montos_totales['iva']),
                'IVARETENIDO_LVENTA' => 0,
                'valor_t' => $this->formateaNumero($this->montos_totales['total']),
                'ANO_LVENTA' => date('Y', time()),
                'CTACTE_LVENTA' => 1,
                'FPAGO_LVENTA' => $formaPago->DIAS_CPAGO,
                'ANEGOCIO_LVENTA' => $this->area_negocio,
                'SUCURSAL_LVENTA' => 'CASA MATRIZ',
                'OBS_LVENTA' => $this->observacion,
                'DISPONIBLE1_LVENTA' => $formaPago->NOMBRE_CPAGO,
                'DISPONIBLE2_LVENTA' => $this->adicionales['Dos'],
                'DISPONIBLE3_LVENTA' => '',
                'DISPONIBLE4_LVENTA' => '',
                'DISPONIBLE5_LVENTA' => '',
                'DISPONIBLE6_LVENTA' => date('Y-m-d', strtotime('+'.$formaPago->DIAS_CPAGO.' day', time())),
                'FINGRESO_LVENTAS' => date('Y-m-d'),
                'UINGRESO_LVENTAS' => $this->rut_usuario,
                'ID_ENVIO' => 1,
            ]);
        }catch (Exception $e) {
            return false;
        }

        return $ingreso;
    }

    protected function ingresoCtaCte($id_libro_venta)
    {
        try{
            $ctacte = new Ctacte(
                $this->rut_empresa,
                $this->receptor->RUT_CLIENTEPROVEEDOR,
                $this->folio,
                $this->formateaNumero($this->tipo_documento),
                $this->formateaNumero($this->montos_totales['total']),
                0,
                $this->formateaNumero($this->montos_totales['total']),
                $this->id_empresa,
                $id_libro_venta
            );

            $ingreso = $ctacte->ingresar($id_libro_venta);
            
        }catch (Exception $e){
            return false;
        }
        

        /*try{
            $ingreso = DB::table('ctacte')
                ->insert([
                    'rut_empresa' => $this->rut_empresa,
                    'rut_c' => $this->receptor->RUT_CLIENTEPROVEEDOR,
                    'n_doc_ctacte' => $this->folio,
                    'tipo_doc' => $this->formateaNumero($this->tipo_documento),
                    'total_ctacte' => $this->formateaNumero($this->montos_totales['total']),
                    'pagos_ctacte' => 0,
                    'saldo_ctacte' => $this->formateaNumero($this->montos_totales['total']),
                    'libro_ventas_id' => $id_libro_venta,
                ]);
        }catch (Exception $e){
            return false;
        }*/

        return $ingreso;
    }

    protected function ingresoDescGlobal()
    {
        try{
        $ingreso = DB::table('desc_global')
            ->insert([
                'ID_EMPRESA' => $this->rut_empresa,
                'FOLIO_DOC' => $this->folio,
                'TIPO_DOC' => $this->tipo_documento,
                'TIPO_DESC' => 2,
                'VALOR_DESC' => $this->formateaNumero($this->descuento),
                'ADICIONAL1' => '',
                'ADICIONAL2' => '',
                'ADICIONAL3' => '',
            ]);
        } catch (Exception $e){
            return false;
        }

        return $ingreso;
    }

    protected function ingresoDirLibroVenta()
    {
        try{
            $ingreso = DB::table('dir_libro_venta')
                ->insert([
                    'ID_EMPRESA' => $this->rut_empresa,
                    'FOLIO_DIR_LVENTA' => $this->folio,
                    'TIPO_DIR_LVENTA' => $this->tipo_documento,
                    'ID_DIRECCION' => $this->receptor->ID_DIRECCION,
                    'ADICIONAL_DIR_LVENTA' => '',
                ]);
        } catch (Exception $e){
            return false;
        }

        return $ingreso;
    }


    protected function ingresoAdicionalDonacion()
    {
        try{
            $ingreso = DB::table('adicional_libro_ventas')
            ->insert([
                'RUT_EMPRESA' => $this->rut_empresa,
                'RUT_CLIENTE' => $this->receptor->RUT_CLIENTEPROVEEDOR,
                'typo_doc' => $this->tipo_documento,
                'n_doc' => $this->folio,
                'donacion' => $this->adicionales['Treinta'],
                'MONTO_NO_FACTURABLE' => isset($this->montoNoFacturable) ? $this->montoNoFacturable : '0',
            ]);
        } catch (Exception $e){
            return false;
        }

        return $ingreso;
    }

    protected function ingresaDetalleDoc2($detalle, $producto, $exento, $neto, $total, $id_usuario)
    {
        try{
            $ingreso = DB::table('detalle_doc2')
                ->insert([
                    'RUT_EMPRESA' => $this->rut_empresa,
                    'RUT_CLIENTE' => $this->receptor->RUT_CLIENTEPROVEEDOR,
                    'ID_CORRE_DETALLEDOC' => $this->folio,
                    'ID_TIPODOC' => $this->tipo_documento,
                    'CPROD_DETALLEDOC' => $producto->CODIGO_PRODUCTO,
                    'DETALLE_DETALLEDOC' => $producto->DESCRIPCION_PRODUCTO,
                    'ESPECIFICO_DETALLEDOC' => '',
                    'EXENTO_DETALLEDOC' => $exento,
                    'NETO_DETALLEDOC' => $neto,
                    'CANTIDAD_DETALLEDOC' => $detalle['Cantidad'],
                    'TIPODESC__DETALLEDOC' => 1,
                    'VADESC__DETALLEDOC' => $detalle['Descuento'],
                    'DESC__DETALLEDOC' => $detalle['Descuento'],
                    'TOTAL_DETALLEDOC' => $total,
                    'ID_USUARIO' => $id_usuario,
                    'FECHA_DETALLEDOC' => date('Y-m-d', time()),
                    'ESTADO_DETALLEDOC' => 2,
                ]);
        } catch(Exception $e) {
            return false;
        }

        return $ingreso;
    }

    protected function confDecimalDetalle()
    {
        /*$query_dec="select ADICIONAL3,ADICIONAL4,ADICIONAL6 FROM corre_folios 
        where RUT_EMPRESA='$empresa' AND CODIGO='33'";
        $result_dec=mysql_db_query($database,$query_dec);
        $row_dec=mysql_fetch_object($result_dec);
        $decimales 		= $row_dec->ADICIONAL3;     //cantidad
        $deci_totalitem = $row_dec->ADICIONAL4;     //valor item
        $deci_total		= $row_dec->ADICIONAL5;     //total
        */

        $data = DB::table('corre_folios')
            ->whereRaw('RUT_EMPRESA = \'' . $this->rut_empresa . '\'')
            ->whereRaw('CODIGO = \'' . $this->tipo_documento . '\'')
            ->first();
        return $data;
    }

    protected function ingresoDetalleInvProductos($producto, $detalle, $bodega)
    {
        if ($producto->INV_PRODUCTO != 14) {

            try{
                $ingreso = DB::table('detalle_inv_productos')
                    ->insert([
                        'CODIGO_PRODUCTO' => $producto->CODIGO_PRODUCTO,
                        'FECHA_INGRESO' => date('Y-m-d', time()),
                        'FECHA_MOV' => date('Y-m-d H:i:s', time()),
                        'TIPO_MOV' => 2,
                        'FECHA_DOC' => date('Y-m-d', time()),
                        'FOLIO_DOC' => $this->tipo_documento,
                        'N_DOC' => $this->folio,
                        'RUT_EMPRESA' => $this->rut_empresa,
                        'OBS' => isset($this->observacion) ? $this->observacion : '',
                        'CANTIDAD_DOC' => $detalle['Cantidad'],
                        'VALOR_PRODUCTO' => $detalle['Precio'],
                        'ID_BODEGA' => $bodega->ID_BODEGAS,
                        'CANTIDAD_INV' => $detalle['Cantidad'],
                        'CORRE_COMPRA' => 0,
                        'ADICIONAL1_DETALLE_INV' => $this->rut_usuario,
                        'datos_empresa_id' => $this->id_empresa
                    ]);
            } catch(Exception $e){
                return false;
            }
        }else{
            //descontar pack
            $datos_pack = DB::table('pack_producto')
                ->select('PROD_ADIC', 'CANTIDAD', 'VALOR_PRODUCTO')
                ->join('productos', 'pack_producto.ID_PRODUCTO', '=', 'productos.ID_PRODUCTO')
                ->whereRaw('RUT_EMPRESA = \''.$this->rut_empresa.'\'')
                ->whereRaw('NOMBRE_PACK = \''.$producto->CODIGO_PRODUCTO.'\'')
                ->get();

            foreach ($datos_pack as $key => $pack) {
                $codigo_pack = $pack->PROD_ADIC;
                $cantidad_pack = $pack->CANTIDAD * $detalle['Cantidad'];
                $neto_pack = (int) $pack->VALOR_PRODUCTO;

                $precio_pack = $neto_pack * $cantidad_pack;

                try {
                    $ingreso = DB::table('detalle_inv_productos')
                    ->insert([
                        'CODIGO_PRODUCTO' => $codigo_pack,
                        'FECHA_INGRESO' => date('Y-m-d', time()),
                        'FECHA_MOV' => date('Y-m-d H:i:s', time()),
                        'TIPO_MOV' => 2,
                        'FECHA_DOC' => date('Y-m-d', time()),
                        'FOLIO_DOC' => $this->tipo_documento,
                        'N_DOC' => $this->folio,
                        'RUT_EMPRESA' => $this->rut_empresa,
                        'OBS' => isset($this->observacion) ? $this->observacion : '',
                        'CANTIDAD_DOC' => $cantidad_pack,
                        'VALOR_PRODUCTO' => $precio_pack,
                        'ID_BODEGA' => $bodega->ID_BODEGAS,
                        'CANTIDAD_INV' => $detalle['Cantidad'],
                        'CORRE_COMPRA' => 0,
                        'ADICIONAL1_DETALLE_INV' => $this->rut_usuario,
                        'datos_empresa_id' => $this->id_empresa
                    ]);

                } catch (\Exception $e) {
                    return false;
                    //$respuestas[$item] = ['mensaje' => 'No se pudo realizar el ingreso de detalle de inventario. Error2: '.$e];
                    //continue;

                }
            }
        }

        return $ingreso;
    }

    protected function calculaTotalesBoleta($tipoDocumento, $montoNeto, $descuento)
    {
        $montosTotales = [];

        if($tipoDocumento == self::BOLETA_EXENTA) {
            $montosTotales['neto'] = $montoNeto;
            $montosTotales['exento'] = $montoNeto - $descuento;
            $montosTotales['iva'] = 0;
            $montosTotales['total'] = $montosTotales['exento'];
        }
        else if($tipoDocumento == self::BOLETA_AFECTA) {
            $montosTotales['neto'] = $montoNeto;
            $montosTotales['iva'] = ($montoNeto - $descuento) * env('IVA');
            $montosTotales['total'] = ($montoNeto - $descuento) + $montosTotales['iva'];
            $montosTotales['exento'] = 0;
        }

        return $montosTotales;
    }

    protected function obtenDatosEmisor($rut_emisor)
   {
       return DB::table('datos_empresa')
           ->whereRaw('rut = \''.$rut_emisor.'\'')
           ->where('ESISTEMA', '=', 1)
           ->first();
   }
   
   protected function validaCaf($rut_empresa, $codigo)
   {
        $estado = false;
        //mejorar  funcionamiento
        $listadoCaf = DB::table('caf')
            ->selectRaw('MIN(DESDE) AS desde, MAX(HASTA) AS hasta')
           ->whereRaw('RUT_EMPRESA = \''.$rut_empresa.'\'')
           ->whereRaw('CODIGO_DOC = \''.$codigo.'\'')
           ->get();
        //dd($listadoCaf[0]->hasta);

        if(!empty($listadoCaf[0])){
            if($this->folio >= $listadoCaf[0]->desde AND $this->folio <= $listadoCaf[0]->hasta ){
                //dd("dentro del rango",$this->folio);
                $estado = false;
            }else{
                //dd("FUERA del rango",$this->folio);
                $estado = true;
                //return $this->fallo('Envio:'.$this->item.'- Caf no disponible para generar dte folio '.$this->folio.' tipo '.$this->tipo_documento.'.', true, false);
            }
        }

        
        /*foreach ($listadoCaf as $key => $caf) {
            $desde = $caf->DESDE;
            $hasta = $caf->HASTA;
            if($this->folio >= $desde AND $this->folio <= $hasta ){
                //dd("dentro del rango",$this->folio);
                $estado = false;
            }else{
                //dd("FUERA del rango",$this->folio);
                $estado = true;
                //return $this->fallo('Envio:'.$this->item.'- Caf no disponible para generar dte folio '.$this->folio.' tipo '.$this->tipo_documento.'.', true, false);
            }
        }*/
        return $estado;

   }

    protected function rollback(){
        $ingreso = DB::table('libro_ventas')
            ->whereRaw('rut = \''.$this->rut_empresa.'\'')
            ->where('typo_doc', '=', $this->tipo_documento)
            ->where('n_doc', '=', $this->folio)
            ->delete();

        $ingreso = DB::table('ctacte')
            ->whereRaw('rut_empresa = \''.$this->rut_empresa.'\'')
            ->where('tipo_doc', '=', $this->tipo_documento)
            ->where('n_doc_ctacte', '=', $this->folio)
            ->delete();

        $ingreso = DB::table('desc_global')
            ->whereRaw('ID_EMPRESA = \''.$this->rut_empresa.'\'')
            ->where('TIPO_DOC', '=', $this->tipo_documento)
            ->where('FOLIO_DOC', '=', $this->folio)
            ->delete();

        $ingreso = DB::table('dir_libro_venta')
            ->whereRaw('ID_EMPRESA = \''.$this->rut_empresa.'\'')
            ->where('TIPO_DIR_LVENTA', '=', $this->tipo_documento)
            ->where('FOLIO_DIR_LVENTA', '=', $this->folio)
            ->delete();

        $ingreso = DB::table('adicional_libro_ventas')
            ->whereRaw('RUT_EMPRESA = \''.$this->rut_empresa.'\'')
            ->where('typo_doc', '=', $this->tipo_documento)
            ->where('n_doc', '=', $this->folio)
            ->delete();

        $ingreso = DB::table('detalle_doc2')
            ->whereRaw('RUT_EMPRESA = \''.$this->rut_empresa.'\'')
            ->where('ID_TIPODOC', '=', $this->tipo_documento)
            ->where('ID_CORRE_DETALLEDOC', '=', $this->folio)
            ->delete();

        $ingreso = DB::table('detalle_inv_productos')
            ->whereRaw('RUT_EMPRESA = \''.$this->rut_empresa.'\'')
            ->where('FOLIO_DOC', '=', $this->tipo_documento)
            ->where('N_DOC', '=', $this->folio)
            ->delete();

        $ingreso = DB::table('ref_sistema_ge_especial')
            ->whereRaw('RUT_EMPRESA = \''.$this->rut_empresa.'\'')
            ->where('ADICIONAL2', '=', $this->tipo_documento)
            ->where('ADICIONAL1', '=', $this->folio)
            ->delete();
    }


    protected function generaXml($datos,$adicionales)
    {
        $xml_detalle = '';

        $item = 1;
        foreach($datos['Detalles'] as $detalle) {
            $xml_detalle .= '<Detalle>
               <NroLinDet>'.$item.'</NroLinDet>
               <CdgItem>
                  <TpoCodigo />
                  <VlrCodigo>'.$detalle['VlrCodigo'].'</VlrCodigo>
               </CdgItem>
               <NmbItem>'.$detalle['NmbItem'].'</NmbItem>
               <QtyItem>'.$detalle['QtyItem'].'</QtyItem>
               <UnmdItem>'.$detalle['UnmdItem'].'</UnmdItem>
               <PrcItem>'.$detalle['PrcItem'].'</PrcItem>
               <MontoItem>'.$detalle['MontoItem'].'</MontoItem>
            </Detalle>'.PHP_EOL;
            $item++;
        }

        $xml_no_facturable = '';
        if (!empty($datos['NO_facturable'])) {
            $valor_total_monto_no_facturable = number_format(($datos['MntTotal'] + $datos['NO_facturable']),0,',','');

            $xml_no_facturable = '<MontoNF>'.$datos['NO_facturable'].'</MontoNF>
                    <TotalPeriodo>'.$valor_total_monto_no_facturable.'</TotalPeriodo>';
            //$xml_no_facturable .= '<MontoPeriodo>'.$valor_total_monto_no_facturable.'</MontoPeriodo>';
        }

        $xml = '
            <Body>
                <DTE>
                    <Documento>
                    <Encabezado>
                        <IdDoc>
                            <TipoDTE>'.$datos['TipoDTE'].'</TipoDTE>
                            <Folio>'.$datos['Folio'].'</Folio>
                            <FchEmis>'.date('Y-m-d', time()).'</FchEmis>
                            <IndServicio>3</IndServicio>
                        </IdDoc>
                        <Emisor>
                            <RUTEmisor>'.$datos['RUTEmisor'].'</RUTEmisor>
                            <RznSocEmisor>'.$datos['RznSoc'].'</RznSocEmisor>
                            <GiroEmisor>'.$datos['GiroEmis'].'</GiroEmisor>
                            <CdgSIISucur>'.$datos['Acteco'].'</CdgSIISucur>
                            <DirOrigen>'.$datos['DirOrigen'].'</DirOrigen>
                            <CmnaOrigen>'.$datos['CmnaOrigen'].'</CmnaOrigen>
                            <CiudadOrigen>'.$datos['CiudadOrigen'].'</CiudadOrigen>
                        </Emisor>
                        <Receptor>
                            <RUTRecep>'.$datos['RUTRecep'].'</RUTRecep>
                            <RznSocRecep>'.$datos['RznSocRecep'].'</RznSocRecep>
                            <DirRecep>'.$datos['DirRecep'].'</DirRecep>
                            <CmnaRecep>'.$datos['CmnaRecep'].'</CmnaRecep>
                            <CiudadRecep>'.$datos['CiudadRecep'].'</CiudadRecep>
                        </Receptor>
                        <Totales>
                            <MntNeto>'.$datos['MntNeto'].'</MntNeto>
                            <MntExe>'.$datos['MntExento'].'</MntExe>
                            <IVA>'.$datos['MntIva'].'</IVA>
                            <MntTotal>'.$datos['MntTotal'].'</MntTotal>
                            '.$xml_no_facturable.'
                        </Totales>
                        
                    </Encabezado>
                    '.$xml_detalle.'

                    </Documento>

                    <Adicionales>
                        '.$adicionales.'
                    </Adicionales>
                </DTE>
                <idImpreso></idImpreso>
            </Body>
            ';

            

         return $xml;


    }

    protected function generaXmlAdicionalesApi($datos)
    {
        $xml = '<Uno>'.(isset($datos['Uno']) ? $datos['Uno'] : '').'</Uno>
    	       <Dos>'.(isset($datos['Dos']) ? $datos['Dos'] : '').'</Dos>
               <Tres>'.(isset($datos['Tres']) ? $datos['Tres'] : '').'</Tres>
               <Cuatro>'.(isset($datos['Cuatro']) ? $datos['Cuatro'] : '').'</Cuatro>
               <Cinco>'.(isset($datos['Cinco']) ? $datos['Cinco'] : '').'</Cinco>
               <Seis>'.(isset($datos['Seis']) ? $datos['Seis'] : '').'</Seis>
               <Siete>'.(isset($datos['Siete']) ? $datos['Siete'] : '').'</Siete>
               <Ocho>'.(isset($datos['Ocho']) ? $datos['Ocho'] : '').'</Ocho>
               <Nueve>'.(isset($datos['Nueve']) ? $datos['Nueve'] : '').'</Nueve>
               <Diez>'.(isset($datos['Diez']) ? $datos['Diez'] : '').'</Diez>
               <Once>'.(isset($datos['Once']) ? $datos['Once'] : '').'</Once>
               <Doce>'.(isset($datos['Doce']) ? $datos['Doce'] : '').'</Doce>
               <Trece>'.(isset($datos['Trece']) ? $datos['Trece'] : '').'</Trece>
               <Catorce>'.(isset($datos['Catorce']) ? $datos['Catorce'] : '').'</Catorce>
               <Quince>'.(isset($datos['Quince']) ? $datos['Quince'] : '').'</Quince>
               <Dieciseis>'.(isset($datos['Dieciseis']) ? $datos['Dieciseis'] : '').'</Dieciseis>
               <Diecisiete>'.(isset($datos['Diecisiete']) ? $datos['Diecisiete'] : '').'</Diecisiete>
               <Dieciocho>'.(isset($datos['Dieciocho']) ? $datos['Dieciocho'] : '').'</Dieciocho>
               <Diecinueve>'.(isset($datos['Diecinueve']) ? $datos['Diecinueve'] : '').'</Diecinueve>
               <Veinte>'.(isset($datos['Veinte']) ? $datos['Veinte'] : '').'</Veinte>
               <Veintiuno>'.(isset($datos['Veintiuno']) ? $datos['Veintiuno'] : '').'</Veintiuno>
               <Veintidos>'.(isset($datos['Veintidos']) ? $datos['Veintidos'] : '').'</Veintidos>
               <Veintitres>'.(isset($datos['Veintitres']) ? $datos['Veintitres'] : '').'</Veintitres>
               <Veinticuatro>'.(isset($datos['Veinticuatro']) ? $datos['Veinticuatro'] : '').'</Veinticuatro>
               <Veinticinco>'.(isset($datos['Veinticinco']) ? $datos['Veinticinco'] : '').'</Veinticinco>
               <Veintiseis>'.(isset($datos['Veintiseis']) ? $datos['Veintiseis'] : '').'</Veintiseis>
               <Veintisiete>'.(isset($datos['Veintisiete']) ? $datos['Veintisiete'] : '').'</Veintisiete>
               <Veintiocho>'.(isset($datos['Veintiocho']) ? $datos['Veintiocho'] : '').'</Veintiocho>
               <Veintinueve>'.(isset($datos['Veintinueve']) ? $datos['Veintinueve'] : '').'</Veintinueve>
               <Treinta>'.(isset($datos['Treinta']) ? $datos['Treinta'] : '').'</Treinta>
               <Treintayuno>'.(isset($datos['Treintayuno']) ? $datos['Treintayuno'] : '').'</Treintayuno>
               <Treintaydos>'.(isset($datos['Treintaydos']) ? $datos['Treintaydos'] : '').'</Treintaydos>
               <Treintaytres>'.(isset($datos['Treintaytres']) ? $datos['Treintaytres'] : '').'</Treintaytres>
               <Treintaycuatro>'.(isset($datos['Treintaycuatro']) ? $datos['Treintaycuatro'] : '').'</Treintaycuatro>
               <Treintaycinco>'.(isset($datos['Treintaycinco']) ? $datos['Treintaycinco'] : '').'</Treintaycinco>
               <Treintayseis>'.(isset($datos['Treintayseis']) ? $datos['Treintayseis'] : '').'</Treintayseis>
               <Treintaysiete>'.(isset($datos['Treintaysiete']) ? $datos['Treintaysiete'] : '').'</Treintaysiete>
               <Treintayocho>'.(isset($datos['Treintayocho']) ? $datos['Treintayocho'] : '').'</Treintayocho>
               <Treintaynueve>'.(isset($datos['Treintaynueve']) ? $datos['Treintaynueve'] : '').'</Treintaynueve>
               <Cuarenta>'.(isset($datos['Cuarenta']) ? $datos['Cuarenta'] : '').'</Cuarenta>
               <Cuarentayuno>'.(isset($datos['Cuarentayuno']) ? $datos['Cuarentayuno'] : '').'</Cuarentayuno>
               <Cuarentaydos>'.(isset($datos['Cuarentaydos']) ? $datos['Cuarentaydos'] : '').'</Cuarentaydos>
               <Cuarentaytres>'.(isset($datos['Cuarentaytres']) ? $datos['Cuarentaytres'] : '').'</Cuarentaytres>
               <Cuarentaycuatro>'.(isset($datos['Cuarentaycuatro']) ? $datos['Cuarentaycuatro'] : '').'</Cuarentaycuatro>
               <Cuarentaycinco>'.(isset($datos['Cuarentaycinco']) ? $datos['Cuarentaycinco'] : '').'</Cuarentaycinco>
               <Cuarentayseis>'.(isset($datos['Cuarentayseis']) ? $datos['Cuarentayseis'] : '').'</Cuarentayseis>
               <Cuarentaysiete>'.(isset($datos['Cuarentaysiete']) ? $datos['Cuarentaysiete'] : '').'</Cuarentaysiete>
               <Cuarentayocho>'.(isset($datos['Cuarentayocho']) ? $datos['Cuarentayocho'] : '').'</Cuarentayocho>
               <Cuarentaynueve>'.(isset($datos['Cuarentaynueve']) ? $datos['Cuarentaynueve'] : '').'</Cuarentaynueve>
               <Cincuenta>'.(isset($datos['Cincuenta']) ? $datos['Cincuenta'] : '').'</Cincuenta>';

       return $xml;
    }

    protected function formateaNumero($numero)
    {
        return number_format($numero, 0, ',', '');
    }
}
