<?php
/*
 * This file is part of facturacion_base
 * Copyright (C) 2013-2017  Carlos Garcia Gomez  neorazorx@gmail.com
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as
 * published by the Free Software Foundation, either version 3 of the
 * License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License for more details.
 * 
 * You should have received a copy of the GNU Lesser General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
ini_set('max_execution_time', 300);
require_once 'plugins/facturacion_base/extras/fbase_controller.php';
require_once 'plugins/factelect/controller/FirmaXades/FirmaElectronicaNativa.php';

class factelect_nc extends fbase_controller
{

    public $agente;
    public $almacenes;
    public $articulo;
    public $buscar_lineas;
    public $cliente;
    public $codagente;
    public $codalmacen;
    public $codgrupo;
    public $codpago;
    public $codserie;
    public $desde;
    public $estado;
    public $factura;
    public $forma_pago;
    public $grupo;
    public $hasta;
    public $huecos;
    public $lineas;
    public $mostrar;
    public $num_resultados;
    public $offset;
    public $order;
    public $resultados;
    public $serie;
    public $total_resultados;
    public $total_resultados_comision;
    public $total_resultados_txt;
    // facturacion electronica

    public $clave;
    public $nombarch;
    public $MEN1;
    public $mensajebien;
    public $mensajemal;
    public $clv;
    public $data_alm;
    public $factclave;          // ARRAY de la factura a procesar electronicamente
    public $archAutorizado;    // nombre del archivo autorizado por el SRI
    public $nombrecliente;     //  nombre del cliente a realizarse el xml
    public $errordatcli;        // errores de datos antes de generar xml
    public $idfiscal;          // tipo de identificacion fiscal 05= cedula, 04= RUC etc....
    public $mail;               // email tomado de la tabla de clientes
    public $cifnif;             // numero de identificacion del cliente tomado de tabla clientes
    public $correodestino;
    public $correodefault;
    public $dirarchFG;

    public function __construct()
    {
        parent::__construct('factelect_nc', 'FE Nota Crédito' , 'Formularios EC');
    }

    protected function private_core()
    {
     if( isset($_GET['id']) )
      {

            parent::private_core();
            // esta direccion electronica se utlizara en cso de no tener una el cliente
            $this->correodefault = FS_MAILDEFA;
            
            $factclave = new factura_cliente();
            $this->factclave = $factclave->get($_GET['id']);
            $this->nombrecliente = $this->factclave->nombrecliente;      // nombre cliente
            $codcli = $this->factclave->codcliente;                         // codigo del cliente
            
            
            $cliente1     = new cliente();
            $this->codcli = $cliente1->get($codcli);
            $this->correodestino = $this->codcli->email;                    // email del cliente
            $tipoidfiscal = $this->codcli->tipoidfiscal;                  // cedula=cedula RUC=RUC  CONSUMIDOR FINAL
            $this->cifnif = $this->codcli->cifnif;                        // numero del documento de identificacion
            $digicifnif   = strlen($this->cifnif);
            
            $this->estadosrinc = $this->factclave->estadosrinc;

            $this->errormail=0;

            if ($tipoidfiscal=='Cedula') 
            {
                $this->idfiscal = '05';
                if ($digicifnif !==10) $this->errordatcli .= "Error numero en CEDULA ".$this->cifnif. " ".$digicifnif;
            }
            if ($tipoidfiscal=='RUC')
            {    
                $this->idfiscal = '04';
                if ($digicifnif !== 13) $this->errordatcli .= "Error numero en RUC ";   
            }
            if ($tipoidfiscal=='CF')  
            {     
                $this->idfiscal = '07';
                if ($digicifnif !==13) $this->errordatcli .= "Error numero en CONSUMIDOR FINAL ";
            }
            if ($tipoidfiscal=='Pasaporte') 
            {
                $this->idfiscal = '06';
                if ($digicifnif > 13) $this->errordatcli .= "Error numero en PASAPORTE ";
            }
            if ($tipoidfiscal=='CedExtranjero') 
            {
                $this->idfiscal = '08';            
                if ($digicifnif >13) $this->errordatcli .= "Error numero en CEDULA DE EXTRANJERO ";
            }

                              // numero de documento



        if( isset($_GET['codalmacen']) )
        {
            $this->codalmacen = $_GET['codalmacen'];
        }

         //     

         // LOS MENSAJES SE MUESTRAN BIEN EJECUTANDO SOLO  $this->valida_sri(); 
            //$this->new_message("Generar  100 : ".$_GET['id']);


      if( isset($_GET['archiapr']) )  
      {
            $this->archAutorizado = $_GET['archiapr'];
            $this->ride_factura();
      }

      if( isset($_GET['codigo']) )  
      {
            if (!filter_var($this->correodestino, FILTER_VALIDATE_EMAIL)) { 
                $this->errormail=1;
             }
            //$this->new_message("Generar  100 : ".$_GET['codigo']);
           if ($this->estadosrinc <> 'ENVIADO' ) {
                if ($this->estadosrinc <> 'AUTORIZADO') {
                    //$this->new_message("Generar  100 : ".$_GET['codigo']);
                    $this->genera_xml();
                }
            }              
            
       }   
          
      }
      if( isset($_GET['clv']) )
      {
        $this->clv =  $_GET['clv'];
        $this->clave    = $this->clv;
        $this->nombarch = $this->clv."-NC.xml";
        //$this->new_message("valida sri : ".$this->clv."  nombre archivo ".$this->nombarch);
        
            if ($this->estadosrinc == 'ENVIADO' ) $this->new_message("Esta nota de crédito ya fue ENVIADA al comprador");
            if ($this->estadosrinc == 'AUTORIZADO') $this->new_message("Esta nota de crédito ya fue AUTORIZADA al comprador");
            if ($this->estadosrinc == 'NEGADO') $this->new_message("Esta nota de crédito fue NEGADA al comprador");
            if ($this->estadosrinc == 'GENERADO' ) $this->valida_sri();
        // para pruebas 
        // $this->archAutorizado = "0910201801040090462900110010010000349240003638416-A.xml";
        //$this->ride_factura();
                    
      }
      // envio de mail
      if( isset($_GET['clvaut']) )
        {

        
        if (!filter_var($this->correodestino, FILTER_VALIDATE_EMAIL)) 
        { 
            $this->errormail=2;
            $this->new_message("Error e-mail : ". $this->correodestino. "  Se enviará al :".$this->correodefault); 
            $this->correodestino = $this->correodefault;
        }

        $this->clvaut =  $_GET['clvaut'];
        $this->clave    = $this->clvaut;
        $this->archAutorizado =  $this->clvaut."-NCA.xml";
        $this->mail_factura();

        }

        ///////////// private core ////////////
        $this->agente = new agente();
        $this->almacenes = new almacen();
        $this->factura = new factura_cliente();
        $this->forma_pago = new forma_pago();
        $this->grupo = new grupo_clientes();
        $this->huecos = array();
        $this->serie = new serie();
        $this->mostrar = 'todo'; 


        if (isset($_GET['mostrar'])) {
            $this->mostrar = $_GET['mostrar'];
            setcookie('ventas_fac_mostrar', $this->mostrar, time() + FS_COOKIES_EXPIRE);
        } else if (isset($_COOKIE['ventas_fac_mostrar'])) {
            $this->mostrar = $_COOKIE['ventas_fac_mostrar'];
        }

        $this->offset = 0;
        if (isset($_REQUEST['offset'])) {
            $this->offset = intval($_REQUEST['offset']);
        }

        $this->order = 'fecha DESC';
        if (isset($_GET['order'])) {
            $orden_l = $this->orden();
            if (isset($orden_l[$_GET['order']])) {
                $this->order = $orden_l[$_GET['order']]['orden'];
            }

            setcookie('ventas_fac_order', $this->order, time() + FS_COOKIES_EXPIRE);
        } else if (isset($_COOKIE['ventas_fac_order'])) {
            $this->order = $_COOKIE['ventas_fac_order'];
        }

        if (isset($_POST['buscar_lineas'])) {
            $this->buscar_lineas();
        } else if (isset($_REQUEST['buscar_cliente'])) {
            $this->fbase_buscar_cliente($_REQUEST['buscar_cliente']);
        } else if (isset($_GET['ref'])) {
            //$this->template = 'extension/ventas_facturas_articulo';

            $articulo = new articulo();
            $this->articulo = $articulo->get($_GET['ref']);

            $linea = new linea_factura_cliente();
            $this->resultados = $linea->all_from_articulo($_GET['ref'], $this->offset);
        } else {
            $this->share_extension();
            $this->huecos = $this->factura->huecos();
            $this->cliente = FALSE;
            $this->codagente = '';
            $this->codalmacen = '';
            $this->codgrupo = '';
            $this->codpago = '';
            $this->codserie = '';
            $this->desde = '';
            $this->estado = '';
            $this->hasta = '';
            $this->num_resultados = '';
            $this->total_resultados = array();
            $this->total_resultados_comision = 0;
            $this->total_resultados_txt = '';
            $this->dirarch = '';

            if (isset($_GET['delete'])) {
                $this->delete_factura();
            } else {
                if (!isset($_GET['mostrar']) && ( $this->query != '' || isset($_REQUEST['codagente']) || isset($_REQUEST['codcliente']) || isset($_REQUEST['codserie']))) {
                    /**
                     * si obtenermos un codagente, un codcliente o un codserie pasamos direcatemente
                     * a la pestaña de búsqueda, a menos que tengamos un mostrar, que
                     * entonces nos indica donde tenemos que estar.
                     */
                    $this->mostrar = 'buscar';
                }

                if (isset($_REQUEST['codcliente']) && $_REQUEST['codcliente'] != '') {
                    $cli0 = new cliente();
                    $this->cliente = $cli0->get($_REQUEST['codcliente']);
                }

                if (isset($_REQUEST['codagente'])) {
                    $this->codagente = $_REQUEST['codagente'];
                }

                if (isset($_REQUEST['codalmacen'])) {
                    $this->codalmacen = $_REQUEST['codalmacen'];
                }

                if (isset($_REQUEST['codgrupo'])) {
                    $this->codgrupo = $_REQUEST['codgrupo'];
                }

                if (isset($_REQUEST['codpago'])) {
                    $this->codpago = $_REQUEST['codpago'];
                }

                if (isset($_REQUEST['codserie'])) {
                    $this->codserie = $_REQUEST['codserie'];
                }

                if (isset($_REQUEST['desde'])) {
                    $this->desde = $_REQUEST['desde'];
                    $this->hasta = $_REQUEST['hasta'];
                    $this->estado = $_REQUEST['estado'];
                }
            }

            /// añadimos segundo nivel de ordenación
            $order2 = '';
            if (substr($this->order, -4) == 'DESC') {
                $order2 = ', hora DESC, numero DESC';
            } else {
                $order2 = ', hora ASC, numero ASC';
            }

            if ($this->mostrar == 'sinpagar') {
                $this->resultados = $this->factura->all_sin_pagar($this->offset, FS_ITEM_LIMIT, $this->order . $order2);

                if ($this->offset == 0) {
                    /// calculamos el total, pero desglosando por divisa
                    $this->total_resultados = array();
                    $this->total_resultados_txt = 'Suma total de esta página:';
                    
                    foreach ($this->resultados as $fac) {
                        if (!isset($this->total_resultados[$fac->coddivisa])) {
                            $this->total_resultados[$fac->coddivisa] = array(
                                'coddivisa' => $fac->coddivisa,
                                'total' => 0
                            );
                        }

                        $this->total_resultados[$fac->coddivisa]['total'] += $fac->total;
                    }
                }
            } else if ($this->mostrar == 'buscar') {
                $this->buscar($order2);
            } else {
                $this->resultados = $this->factura->all($this->offset, FS_ITEM_LIMIT, $this->order . $order2);
            }
        }
    }

    public function url($busqueda = FALSE)
    {
        if ($busqueda) {
            $codcliente = '';
            if ($this->cliente) {
                $codcliente = $this->cliente->codcliente;
            }

            $url = parent::url() . "&mostrar=" . $this->mostrar
                . "&query=" . $this->query
                . "&codagente=" . $this->codagente
                . "&codalmacen=" . $this->codalmacen
                . "&codcliente=" . $codcliente
                . "&codgrupo=" . $this->codgrupo
                . "&codpago=" . $this->codpago
                . "&codserie=" . $this->codserie
                . "&desde=" . $this->desde
                . "&estado=" . $this->estado
                . "&hasta=" . $this->hasta;

            return $url;
        }

        return parent::url();
    }

    public function paginas()
    {
        if ($this->mostrar == 'sinpagar') {
            $total = $this->total_sinpagar();
        } else if ($this->mostrar == 'buscar') {
            $total = $this->num_resultados;
        } else {
            $total = $this->total_registros();
        }

        return $this->fbase_paginas($this->url(TRUE), $total, $this->offset);
    }

    public function buscar_lineas()
    {
        /// cambiamos la plantilla HTML
        $this->template = 'ajax/ventas_lineas_facturas';

        $this->buscar_lineas = $_POST['buscar_lineas'];
        $linea = new linea_factura_cliente();

        if (isset($_POST['codcliente'])) {
            $this->lineas = $linea->search_from_cliente2($_POST['codcliente'], $this->buscar_lineas, $_POST['buscar_lineas_o']);
        } else {
            $this->lineas = $linea->search($this->buscar_lineas);
        }
    }

    private function share_extension()
    {
        /// añadimos las extensiones para clientes, agentes y artículos
        $extensiones = array(
            array(
                'name' => 'facturas_cliente',
                'page_from' => __CLASS__,
                'page_to' => 'ventas_cliente',
                'type' => 'button',
                'text' => '<span class="glyphicon glyphicon-list" aria-hidden="true"></span> &nbsp; Facturas',
                'params' => ''
            ),
            array(
                'name' => 'facturas_agente',
                'page_from' => __CLASS__,
                'page_to' => 'admin_agente',
                'type' => 'button',
                'text' => '<span class="glyphicon glyphicon-list" aria-hidden="true"></span> &nbsp; Facturas de cliente',
                'params' => ''
            ),
            array(
                'name' => 'facturas_articulo',
                'page_from' => __CLASS__,
                'page_to' => 'ventas_articulo',
                'type' => 'tab_button',
                'text' => '<span class="glyphicon glyphicon-list" aria-hidden="true"></span> &nbsp; Facturas de cliente',
                'params' => ''
            ),
        );
        foreach ($extensiones as $ext) {
            $fsext0 = new fs_extension($ext);
            if (!$fsext0->save()) {
                $this->new_error_msg('Imposible guardar los datos de la extensión ' . $ext['name'] . '.');
            }
        }
    }

    public function total_sinpagar()
    {
        return $this->fbase_sql_total('facturascli', 'idfactura', 'WHERE pagada = false');
    }

    private function total_registros()
    {
        return $this->fbase_sql_total('facturascli', 'idfactura');
    }

    private function buscar($order2)   // Entra desde la primera vez que entra en la pantalla
    {

        // busca y lista los archivos en el directorio que generados clave=49 -NC Y EXT XML   
        $ruta100 = 'plugins/factelect/controller/src_sri/NCgenerados/'; 
        $directorio=opendir($ruta100);
        //recoger los  datos
        $datos=array();
        while ($archivo = readdir($directorio)) 
        { 
          if(($archivo != '.')&&($archivo != '..'))
          {
             
             //echo "archivo a guardar ".$archivo."  tamaño :".strlen($archivo);
           
             if (strlen($archivo)==56)       // CUENTA EL NUMERO DE CARACTERES
             {
                $datos[]=substr($archivo,-17,8);    // $ARCHIVO tiene el nombre completo.XML 
                //$id = substr($archivo,-18,8);     
             }
          } 
        }       

        $this->resultados = array();
        $this->num_resultados = 0;
        $sql = " FROM facturascli ";
        $where = 'WHERE ';

        if ($this->query) {
            $query = $this->agente->no_html(mb_strtolower($this->query, 'UTF8'));
            $sql .= $where;
            if (is_numeric($query)) {
                $sql .= "(codigo LIKE '%" . $query . "%' OR numero2 LIKE '%" . $query . "%' "
                    . "OR observaciones LIKE '%" . $query . "%' OR cifnif LIKE '" . $query . "%')";
            } else {
                $sql .= "(lower(codigo) LIKE '%" . $query . "%' OR lower(numero2) LIKE '%" . $query . "%' "
                    . "OR lower(cifnif) LIKE '" . $query . "%' "
                    . "OR lower(observaciones) LIKE '%" . str_replace(' ', '%', $query) . "%')";
            }
            $where = ' AND ';
        }
        $sql .= $where . "anulada = false and (idfacturarect !='' ) "; //anuladas como facturas previo al proceso de factura electronica
        $where = ' AND ';

        if ($this->cliente) {
            $sql .= $where . "codcliente = " . $this->agente->var2str($this->cliente->codcliente);
            $where = ' AND ';
        }

        if ($this->codagente != '') {
            $sql .= $where . "codagente = " . $this->agente->var2str($this->codagente);
            $where = ' AND ';
        }

        if ($this->codalmacen != '') {
            $sql .= $where . "codalmacen = " . $this->agente->var2str($this->codalmacen);
            $where = ' AND ';
        }

        if ($this->codgrupo != '') {
            $sql .= $where . "codcliente IN (SELECT codcliente FROM clientes WHERE codgrupo = " . $this->agente->var2str($this->codgrupo) . ")";
            $where = ' AND ';
        }

        if ($this->codpago != '') {
            $sql .= $where . "codpago = " . $this->agente->var2str($this->codpago);
            $where = ' AND ';
        }

        if ($this->codserie != '') {
            $sql .= $where . "codserie = " . $this->agente->var2str($this->codserie);
            $where = ' AND ';
        }

        if ($this->desde) {
            $sql .= $where . "fecha >= " . $this->agente->var2str($this->desde);
            $where = ' AND ';
        }

        if ($this->hasta) {
            $sql .= $where . "fecha <= " . $this->agente->var2str($this->hasta);
            $where = ' AND ';
        }

        if ($this->estado == 'generadas') {
            $cadena_idfac= implode(",", $datos);
            $sql .= $where . "estadosrinc = 'GENERADO' and numero in (".$cadena_idfac.")" ; 
            $where = ' AND ';
        } else if ($this->estado == 'singenerar') {
            $sql .= $where . "estadosrinc is null ";
            $where = ' AND ';    
        } else if ($this->estado == 'firmadas') {
            $sql .= $where . "estadosrinc = 'FIRMADO' ";
            $where = ' AND ';

        } else if ($this->estado == 'aprobadas') {
            $sql .= $where . "estadosrinc = 'AUTORIZADO' ";
            $where = ' AND ';
        } else if ($this->estado == 'negadas') {
            $sql .= $where . "estadosrinc = 'NEGADO' ";
            $where = ' AND ';
        } else if ($this->estado == 'enviadas') {
            $sql .= $where . "estadosrinc = 'ENVIADO' ";
            $where = ' AND ';
        }
 //$this->new_error_msg("SQL JOHN 1 ".$sql);
        $data = $this->db->select("SELECT COUNT(idfactura) as total" . $sql);
        if ($data) {
            $this->num_resultados = intval($data[0]['total']);

            $data2 = $this->db->select_limit("SELECT *" . $sql . " ORDER BY " . $this->order . $order2, FS_ITEM_LIMIT, $this->offset);
            if ($data2) {
                foreach ($data2 as $d) {
                    $this->resultados[] = new factura_cliente($d);
                    //print_r($this->resultados);
                    //echo "</br>";
                    //$this->new_error_msg("SQL JOHN ".$sql); 
                }
            }

            $data2 = $this->db->select("SELECT coddivisa,SUM(total) as total" . $sql . " GROUP BY coddivisa");
            if ($data2) {
                $this->total_resultados_txt = 'Suma total de los resultados:';
                $this->dirarch = 'plugins/factelect/controller/src_sri/NCgenerados/';
                foreach ($data2 as $d) {
                    $this->total_resultados[] = array(
                        'coddivisa' => $d['coddivisa'],
                        'total' => floatval($d['total'])
                    );
                }
            }

            if ($this->codagente !== '') {
                /// calculamos la comisión del empleado
                $data2 = $this->db->select("SELECT SUM(neto*porcomision/100) as total" . $sql);
                if ($data2) {
                    $this->total_resultados_comision = floatval($data2[0]['total']);
                }
            }
        }
    }

    private function delete_factura()
    {
        $fact = $this->factura->get($_GET['delete']);
        if ($fact) {
            /// obtenemos las líneas de la factura antes de eliminar
            $lineas = $fact->get_lineas();

            if ($fact->delete()) {
                if (!$fact->anulada) {
                    /// Restauramos el stock
                    $art0 = new articulo();
                    foreach ($lineas as $linea) {
                        /// si la línea pertenece a un albarán no descontamos stock
                        if (is_null($linea->idalbaran)) {
                            $articulo = $art0->get($linea->referencia);
                            if ($articulo) {
                                $articulo->sum_stock($fact->codalmacen, $linea->cantidad, FALSE, $linea->codcombinacion);
                            }
                        }
                    }
                }

                /// ¿Esta factura es rectificativa de otra?
                if ($fact->idfacturarect) {
                    $original = $this->factura->get($fact->idfacturarect);
                    if ($original) {
                        $original->anulada = FALSE;
                        $original->save();
                    }
                }

                $this->clean_last_changes();
            } else {
                $this->new_error_msg("¡Imposible eliminar la factura!");
            }
        } else {
            $this->new_error_msg("Factura no encontrada.");
        }
    }

    public function orden()
    {
        return array(
            'fecha_desc' => array(
                'icono' => '<span class="glyphicon glyphicon-sort-by-attributes-alt" aria-hidden="true"></span>',
                'texto' => 'Fecha',
                'orden' => 'fecha DESC'
            ),
            'fecha_asc' => array(
                'icono' => '<span class="glyphicon glyphicon-sort-by-attributes" aria-hidden="true"></span>',
                'texto' => 'Fecha',
                'orden' => 'fecha ASC'
            ),
            'vencimiento_desc' => array(
                'icono' => '<span class="glyphicon glyphicon-sort-by-attributes-alt" aria-hidden="true"></span>',
                'texto' => 'Vencimiento',
                'orden' => 'vencimiento DESC'
            ),
            'vencimiento_asc' => array(
                'icono' => '<span class="glyphicon glyphicon-sort-by-attributes" aria-hidden="true"></span>',
                'texto' => 'Vencimiento',
                'orden' => 'vencimiento ASC'
            ),
            'codigo_desc' => array(
                'icono' => '<span class="glyphicon glyphicon-sort-by-attributes-alt" aria-hidden="true"></span>',
                'texto' => 'Código',
                'orden' => 'codigo DESC'
            ),
            'codigo_asc' => array(
                'icono' => '<span class="glyphicon glyphicon-sort-by-attributes" aria-hidden="true"></span>',
                'texto' => 'Código',
                'orden' => 'codigo ASC'
            ),
            'total_desc' => array(
                'icono' => '<span class="glyphicon glyphicon-sort-by-attributes-alt" aria-hidden="true"></span>',
                'texto' => 'Total',
                'orden' => 'total DESC'
            )
        );
    }




    private function genera_xml()
     {
        $ruta100 = 'plugins/factelect/controller/src_sri/NCgenerados/';      
        $tipoEmi      = 1;      //   tabla 2 solo tiene opcion normal=1
        $tipcomp      = '04';        // codigo del documento ACTUAL NOTA DE CREDITO
        $serie        = '001099';
        $docclave     = "numnc";
        $where1='';
        $where3='';
        if(FS_AMBIENTE==FALSE) $tipambiente  = 1;            //  tipo de ambiente 1-> pruebas   2 -> produccion   
        if(FS_AMBIENTE==TRUE)   $tipambiente  = 2;           //  tipo de ambiente 1-> pruebas   2 -> produccion   

        //$this->new_message("get ALMACEN  ". $this->codalmacen);
               
//     if( $this->codalmacen == '' ) $this->errordatcli .= "No eligio un ALMACEN";

     if(   $this->errordatcli == '' )
      {
        // $this->codalmacen = $_GET['x'];
         //$this->new_message("SI HAY ALMACEN ". $this->codalmacen);
         $where1 .= "almacen = '".$this->codalmacen. "'";
         $where2 = " where idfactura = '" . $_GET['id']."'"  ;    // factura rectificativa

         // datos generales de la factura
         //$data_fac1 = "SELECT * FROM facturascli ".$where2;
         //$this->new_message("LADY sql= ".$data_fac1);
         $data_fac = $this->db->select("SELECT * FROM facturascli ".$where2.";");   // factura rectificativa
         $contacto = '';



         $nombre = '';

        // datos del almacen o empresa  
        // $data_alm = $this->db->select("SELECT codalmacen, contacto, nombre, direccion FROM almacenes WHERE codalmacen = '".$this->codalmacen."';");
         $data_alm = $this->db->select("SELECT administrador , nombre, direccion, cifnif FROM empresa WHERE id=1 ;");     
    
        if (is_array($data_alm))
        {
          foreach($data_alm as $alm)
           {
              $rucalmacen = ($alm['cifnif']);   
              $nombre = ($alm['nombre']);   
              $direccionalma = ($alm['direccion']);   
             //$this->new_message("datos almacen ". $contacto."  nombre ".$nombre); 
           }
        }else 
          {
           $this->new_message("no hay datos ALMACEN");
          }

       // datos generales de factura 
       if( isset($_GET['idfactura']) )
        {
          $codigo = $_GET['idfactura'];
        }
       if (is_array($data_fac))
       {
       foreach($data_fac as $fac)                                // factura rectificativa
         {
            $idfactura     = ($fac['idfactura']);
            $idfacturarect = ($fac['idfacturarect']);
            $codigorect    = ($fac['codigorect']);
            $codigo        = ($fac['codigo']);
            $cifnif        = $this->cifnif;                    // ($fac['cifnif']);               
            $direccioncli  = ($fac['direccion']);
            $fecha         = ($fac['fecha']);
            $nombrecliente = ($fac['nombrecliente']);
            $netofac       = ($fac['neto']);
            $totaliva      = ($fac['totaliva']);
            $total         = ($fac['total']);
            $netosindto    = ($fac['netosindto']);
            $observaciones = ($fac['observaciones']);
            $estadosrinc    = ($fac['estadosrinc']);
            $numncanterior    = ($fac['numnc']);    
            $descuento     = number_format($netosindto-$netofac,2,".","");
           //$this->new_message("datos factura ". $idfactura."  nombre ".$nombrecliente. "  cifnif ".$cifnif . "  direccion ".$direccioncli."  fecha ". $fecha); 
           //$where3 = " where idfactura = '" . $idfactura."'"  ;
         }
        }
        // factura rectificativa
        $whereFR = " where idfactura = '" . $idfacturarect."'"  ;
        $data_facRec = $this->db->select("SELECT * FROM facturascli ".$whereFR.";");   // factura original
        if (is_array($data_facRec))     // factura rectificativa
        {
            foreach($data_facRec as $facR)
             {
                $idfacturaR     = ($facR['idfactura']);
                $codigoR        = ($facR['codigo']);
                $cifnifR        = ($facR['cifnif']);
                $direccioncliR  = ($facR['direccion']);
                $fechaR         = ($facR['fecha']);
                $nombreclienteR = ($facR['nombrecliente']);
                $netofacR       = ($facR['neto']);
                $totalivaR      = ($facR['totaliva']);
                $totalR         = ($facR['total']);
                $netosindtoR    = ($facR['netosindto']);
                $observacionesR    = ($facR['observaciones']);
                $descuentoR     = number_format($netosindtoR-$netofacR,2,".","");
                $where3 = " where idfactura = '" . $idfactura."'"  ;
             }
        }

        else 
          {
           $this->new_message("no hay datos");
          }  


          $tipIdenComp=$this->idfiscal ;  // se debe buscar el tipo de identificacion del cliente 05 -> cedula

          // clave
          $dia          = substr($fechaR, 8, 2);
          $mes          = substr($fechaR, 5, 2);
          $ano          = substr($fechaR, 0, 4);
          $numruc       = $rucalmacen;    // numero RUC del ALMACEN

          //$this->new_message('ESTADO '.$estadosrinc);
          
          $secuenOrig   =  substr(str_pad($codigoR, 9, "0", STR_PAD_LEFT), -9); 
          $codigof      =  substr(str_pad($codigo, 8, "0", STR_PAD_LEFT),-8);
          $clavefac     = $dia.$mes.$ano.$tipcomp.$numruc.$tipambiente.$serie.$secuencial.$codigof.$tipoEmi;
          $fechafac     = $dia."/".$mes."/".$ano;
          //$this->new_message("clave ".$clavefac);
          
          $this->clave = clave_documentos($this->db,$idfactura, $tipambiente,$docclave,$tipcomp);
          $dv = $this->clave;
          $numfact1     =   substr($dv,30,-10);
          $secuencial   =   substr(str_pad($numfact1, 9, "0", STR_PAD_LEFT), -9);  
          $data_linfac  =   $this->db->select("SELECT * FROM lineasfacturascli ".$where3.";"); 
          $data_liniva  =   $this->db->select("SELECT * FROM lineasivafactcli ".$where3.";"); 

         /// lineas de la factura clientes   ()
          if (is_array($data_linfac))
          {
           foreach($data_linfac as $lfac)
             {
                $cantidad     = ($lfac['cantidad']);   
                $descripcion  = ($lfac['descripcion']);   
                $iva          = ($lfac['iva']);
                $pvpunitario  = ($lfac['pvpunitario']);
                $pvptotal     = ($lfac['pvptotal']);
                $pvpsindto    = ($lfac['pvpsindto']);
               //$this->new_message("linea productos dato 1 ". $cantidad." dato 2 ". $descripcion." dato 3 ". $iva." dato 4  ". $pvpunitario." dato 5 ". $pvptotal." dato 6 ". $pvpsindto); 
             }
          }
          else 
              {
             $this->new_message("No hay datos");
              }

         ////   lineas de iva
          if (is_array($data_liniva))
          {
           foreach($data_liniva as $liva)
            {
                $iva        = ($liva['iva']);   
                $neto       = ($liva['neto']);   
                $totaliva   = ($liva['totaliva']);
                $totallinea = ($liva['totallinea']);
               //$this->new_message("linea IVA dato 1->". $iva." dato 2->". $neto." dato 3->". $totaliva." dato-> 4 ". $totallinea); 
            }
          }
          else 
              {
             $this->new_message("No hay datos");
              }

//*

            //ambiente 1-> pruebas / codDoc  01-> factura
            $this->template = false;
            /// creamos el xml    codDoc 04 = notas de credito
            $cadena_xml = "<?xml version='1.0' encoding='UTF-8'?>
            <notaCredito id='comprobante' version='1.0.0'>
              <infoTributaria>
                <ambiente>".$tipambiente."</ambiente>
                <tipoEmision>".$tipoEmi."</tipoEmision>
                <razonSocial>".$nombre."</razonSocial>
                <nombreComercial>".$nombre."</nombreComercial>
                <ruc>".$rucalmacen."</ruc>
                <claveAcceso>".$dv."</claveAcceso>
                <codDoc>".$tipcomp."</codDoc>
                <estab>001</estab>
                <ptoEmi>099</ptoEmi>
                <secuencial>".$secuencial."</secuencial>
                <dirMatriz>".$direccionalma."</dirMatriz>
              </infoTributaria>
            </notaCredito>\n";
      
            $archivo_xml = simplexml_load_string($cadena_xml);
 
            // informacion de impuestos
            $data_liniva = $this->db->select("SELECT 
                                        2 as codigo,
                                        CASE WHEN iva = 12 then 2
                                             WHEN iva = 0 then 0
                                             WHEN iva = 14 then 3
                                             WHEN iva = 15 then 4
                                         ELSE 0
                                         END AS codigoPorcentaje,
                                         neto as baseImponible,  
                                         totaliva as valor    
                                         FROM lineasivafactcli ".$where3.";"); 

            $aux0 = $archivo_xml->addChild('infoNotaCredito');
            $aux00 = $aux0->addChild('fechaEmision',$fechafac);
            $aux00 = $aux0->addChild('tipoIdentificacionComprador',$tipIdenComp);
            $aux00 = $aux0->addChild('razonSocialComprador',$this->nombrecliente);
            $aux00 = $aux0->addChild('identificacionComprador',$cifnif);

            //$aux00 = $aux0->addChild('contribuyenteEspecial',);        // completar la informacion
            
            $aux00 = $aux0->addChild('obligadoContabilidad','SI');

            
            // $aux00 = $aux0->addChild('rise',);                    // ??  completar la informacion              
                        
            $aux00 = $aux0->addChild('codDocModificado','01');            //  codigo doc modificado factura modificado original
            $aux00 = $aux0->addChild('numDocModificado',"001-099-".$secuenOrig);  //  idfactura modificado original
            $aux00 = $aux0->addChild('fechaEmisionDocSustento',$fechafac);      // fecha de la factura rectificativa
            $aux00 = $aux0->addChild('totalSinImpuestos',number_format((-1*$netofac),2,".",""));
            $aux00 = $aux0->addChild('valorModificacion',-1*$total);
            $aux00 = $aux0->addChild('moneda',"DOLAR");            

            if($data_liniva)       // siempre debe entrar no puede haber una venta que no tenga impuestos iva 
            {
              $aux10 = $aux0->addChild('totalConImpuestos');
              foreach($data_liniva as $d)
              {
                $aux1 = $aux10->addChild('totalImpuesto');
                foreach($d as $i => $value)
                  {
                    if( is_null($value) )
                      $aux1->addChild($i, 'NULL');
                    else if($value == 't')
                      $aux1->addChild($i, 'TRUE');
                    else if($value == 'f')
                        $aux1->addChild($i, 'FALSE');

                    else 
                      if ($i=='codigo'){
                         $aux1->addChild($i, $value);
                       }
                      if ($i=='codigoPorcentaje'){
                         $aux1->addChild($i, $value); 
                      }   
                      if ($i !=='codigo' and  $i !=='codigoPorcentaje')
                         $aux1->addChild($i, number_format((-1*$value),2,".","")); 
                       
                  }

              }
            }else{
                    $aux0 = $archivo_xml->addChild('no_hay');
                 }  
            IF ($observaciones=='') $observaciones = 'NINGUNA';    
            $aux10 = $aux0->addChild('motivo',$observaciones); 
            //$aux20 = $archivo_xml->addChild('detalles');
            //$aux21 = $aux20->addChild('detalle',0);

            //$aux0 = $archivo_xml->addChild('detalles');
            //$aux21 = $aux0->addChild('detalle',0);

           // creacion de tabs para detalle de FACTURA
            $data_linfac = $this->db->select("SELECT referencia as codigoInterno,
                                                    descripcion as descripcion,
                                                    cantidad as cantidad,
                                                    -1*pvpunitario as precioUnitario,
                                                    pvpsindto-pvptotal as descuento,
                                                    pvptotal as precioTotalSinImpuesto,
                                                    2 as codigo,
                                                    CASE WHEN iva = 12 then 2
                                                         WHEN iva = 0 then 0
                                                         WHEN iva = 14 then 3
                                                         WHEN iva = 15 then 4
                                                     ELSE 0
                                                     END AS codigoPorcentaje,
                                                     -1*iva as tarifa,
                                                     pvptotal as baseImponible,
                                                     pvptotal * (iva/100) as valor

                                              FROM lineasfacturascli ".$where3.";");

           if($data_linfac)       // siempre debe entrar no puede haber una venta que no tenga impuestos iva 
            {
              //$aux30 = $aux0->addChild('detalles');
              $aux0 = $archivo_xml->addChild('detalles');
              foreach($data_linfac as $d)
              {
                //$aux1 = $aux30->addChild('detalle');
                $aux1 = $aux0->addChild('detalle');
                foreach($d as $i => $value)
                  {
                    if( is_null($value) )
                      $aux1->addChild($i, 'NULL');
                    else if($value == 't')
                      $aux1->addChild($i, 'TRUE');
                    else if($value == 'f')
                        $aux1->addChild($i, 'FALSE');
                    else if($i == 'codigoInterno')
                          {
                             $aux1->addChild($i, $value);
                          } 
                    else if($i == 'descripcion')
                          {
                             $aux1->addChild($i, eliminar_simbolos($value));
                          } 
                    else if($i == 'codigo')
                          {
                             $aux2 = $aux1->addChild('impuestos');
                             $aux21 = $aux2->addChild('impuesto');
                             //$aux21->addChild($i, ($value));      
                             $aux21->addChild($i,$value);                  
                          }  
                    else if($i == 'codigoPorcentaje')
                          {
                             //$aux2 = $aux1->addChild('impuestos');
                             $aux21->addChild($i, $value);
                          }  
      
                    else if($i == 'tarifa')
                          {
                             $aux21->addChild($i,number_format(-1*$value,2,".",""));                  
                          }  
                    else if($i == 'baseImponible')
                          {
                             $aux21->addChild($i, number_format(-1*$value,2,".",""));  
                          }  
                    else if($i == 'valor')
                          {
                             $aux21->addChild($i, number_format(-1*$value,2,".",""));                      
                          }               
                    else {
                      $aux1->addChild($i, number_format(-1*$value,2,".",""));
                        }
                  }
              }
            }else{
                    $aux0 = $archivo_xml->addChild('no_hay');
                 } 
            $aux0 = $archivo_xml->addChild('infoAdicional');
            $auxif = $aux0->addChild('campoAdicional', 'RESOL.NRO.NAC-DNCRASC20-00000001');
            $auxif->addAttribute('nombre', 'AGENTE DE RETENCION');
            $auxif = $aux0->addChild('campoAdicional', "Regimen General");
            $auxif->addAttribute('nombre', 'regimen');
            if ($this->correodestino){
                $auxif = $aux0->addChild('campoAdicional', $this->correodestino);
                $auxif->addAttribute('nombre', 'Mail');
            }else{
                $auxif = $aux0->addChild('campoAdicional', $this->correodefault);
                $auxif->addAttribute('nombre', 'Mail');
            } 
            
          $this->nombarch="$dv"."-NC.xml";

          //$glob_string =  realpath($ruta100).  "tab_aux_sri_ats1.xml";
          header("content-type: application/xml; charset=UTF-8");

          header("Content-Disposition: attachment; filename='".$this->nombarch."'");

          file_put_contents($ruta100.$this->nombarch,$archivo_xml->asXML());
          echo $archivo_xml->asXML();
          // actualiza la base de datos con la clave SRI
          //$this->factclave = $factclave->get($_GET['id']);
          $this->factclave->clavesrinc = $dv;
          $this->factclave->numnc = $numfact1;
          $this->factclave->estadosrinc = "GENERADO";
          $this->factclave->save();
          //$this->new_message("Archivo Creado y clave guardada : ".$_GET['id'].chr(10)." Arch:".$this->nombarch );
 // */
      } else 
          {  

          $this->new_error_msg($this->errordatcli );
          }
     }
   
function valida_dv($baseVal = "", $separator = '-')
{
    $result = "";
    $weight = [ 2, 3, 4, 5, 6, 7,
                2, 3, 4, 5, 6, 7,
                2, 3, 4, 5, 6, 7,
                2, 3, 4, 5, 6, 7,
                2, 3, 4, 5, 6, 7,
                2, 3, 4, 5, 6, 7,
                2, 3, 4, 5, 6, 7,
                2, 3, 4, 5, 6, 7,
                2, 3, 4, 5, 6, 7  
            ];
    /* For convenience, reverse the string and work left to right. */
    $reversedBseVal = strrev($baseVal);
    for ($i=0, $sum=0; $i < strlen($reversedBseVal); $i++) {
        /* Calculate product and accumulate. */
        $sum += substr($reversedBseVal, $i, 1) * $weight[$i];
    }
    /* Determine check digit, and concatenate to base value. */
    $remainder = $sum % 11;
    switch ($remainder) {
        case 0:
        case 1:
            $result = "{$baseVal}{$separator}0";
            break;
        default:
            $checkDigit = 11 - $remainder;
            $result = "{$baseVal}{$separator}{$checkDigit}";
            break;
    }
    return $result;
}


    public function valida_sri()
    {

    $echo = true; // solo para ver los procesos

    // Este config es opcional, se puede manejar los argumentos directo de cada funcion
    //$this->new_message("clave  ".$this->clave."nombre archivo ".$this->nombarch);
    // la clave de acceso es necesaria para la autorizacion
    $config=array(
        'access_key'    =>$this->clave, 
        'pass_p12'      =>FS_PASPSRI,
        'file_p12'      =>'plugins/factelect/controller/src_sri/'.FS_ELECSIGNA,    
        'file_to_sign'  =>'plugins/factelect/controller/src_sri/NCgenerados/'.$this->nombarch,
        'file_signed'   =>'plugins/factelect/controller/src_sri/NCfirmados/'.$this->clave."-NCF".".xml",        
        'file_autorized'=>'plugins/factelect/controller/src_sri/NCautorizados/'.$this->clave."-NCA".".xml"
    );
    // NOTA: las funciones estan seccionadas por procesos, osea se debe llevar control del estado del documento,
    // Ejemplo: si se envio pero quedo pendiente la autorizacion solo se tendria que volver a autorizar, etc.
    try{
        if($echo) $this->new_message("INICIANDO PROCESO DE AUTORIZACION CON EL SRI......"); 
        // echo '<h2>EJEMPLO CON PHP PURO [EN Systems]</h2><br/><b>EN Systems SRI, Iniciando...</b><br/><br/>';
        
        $signer=new FirmaElectronica($config); // Instancio la clase
        // Arg1 true=Links Online, false= Links Offline 
        // Arg2 true=Produccion, false=development
        $signer->setAmbiente(false,FS_AMBIENTE); // IMPORTANTE: setear el metodo a usar y el ambiente, por default viene ONLINE y PRODUCTION
        /* FIRMADO DEL XML */ 
        //NOTA: sendToSign(); usa el WS de firmado gratuito de EN Systems
        if(!$signer->isKeyActive())
            if(!$signer->setKey($config['file_p12'],$config['pass_p12'])) 
            //if(!$signer->setKey($config['file_p12'],$config['pass_p12'])) 
                throw new Exception("No se pudo leer la firma digital "); // error al firmar       
        $signatured = $signer->signXml(); // no lleva argumentos, xq ya los cogio del config
        if($signatured==false) {
            throw new Exception($signatured['message']); // error al firmar
        }

        if($echo) {
            $this->new_message("Firma:          EXITOSO -- Clave Generada: ".$this->clave);
        //echo 'XML Signature-> <b>Correctamente</b>!</br>';
            $this->factclave->estadosrinc = "FIRMADO";
            $this->factclave->save();
            }
        
        /* VALIDACION XML CON XSD */    
        //NOTA: Funciona con cualquier documento electronico mientras el XSD exista en la ruta, con el nombre de acuerdo al formato
        $xsd_validation = $signer->validaXml(); // no lleva argumentos, xq ya los cogio del config
        if($xsd_validation['success']==false)
            throw new Exception($xsd_validation['message']); // error validando xsd
        if($echo) {
            $this->new_message("XSD Validacion:     EXITOSA"); 
          //echo 'XSD Validation-> <b>Correctamente</b>!</br>';
            $this->factclave->estadosrinc = "VALIDADO";
            $this->factclave->save();
        }

        /* ENVIO AL SRI */
        $sri_send = $signer->sendToSri(); // no lleva argumentos, xq ya los cogio del config
        if($sri_send['success']==false)
            throw new Exception($sri_send['message'].(isset($sri_send['informacionAdicional'])?' - '.$sri_send['informacionAdicional']:'')); // error envio SRI
        if($echo) $this->new_message("ENVIO SRI:          EXITOSO"); 
          //echo 'SRI Sending ----> <b>Correctamente</b>!</br>';
        
        /* AUTORIZACION DEL SRI */
        $sri_aut = $signer->autorizarSri(); // no lleva argumentos, xq ya los cogio del config
        if($sri_aut['success']==false)
            throw new Exception($sri_aut['message'].(isset($sri_aut['informacionAdicional'])?' - '.$sri_aut['informacionAdicional']:'')); // error autorizacion SRI
        if($echo) {
            $this->new_message("Autorizacion SRI:   EXITOSO"); 
          //echo "SRI Autorizat. --> <b>Correctamente</b> [Aut.Num.:<u>{$sri_aut['numeroAutorizacion']} </u>]!</br>";
            $this->factclave->estadosrinc = "AUTORIZADO";
            $this->factclave->save();
                }
        
        if($echo) {
            $this->new_message("EL PROCESO FINALIZO SATISFACTORIAMENTE"); 
            //echo '<br/><b>EN Systems SRI, termino correctamente!.</b>';
            $this->archAutorizado = $this->clave."-NCA".".xml";
 
            //echo "arch 1 ".$this->archAutorizado;
            $this->ride_factura();

           }
        else{
            header("Content-Type: application/xml; charset=utf-8");
            echo $sri_aut['xml'];
        }
    }catch (Exception $e) { 
        $this->new_error_msg("ERROR AL EJECUTAR EL SCRIPT ->". $e->getMessage());  
        //echo '<br/><b>ERROR AL EJECUTAR EL SCRIPT</b><br/>';
        //echo '<b>Excepción Capturada[</b> ',  $e->getMessage(), "]\n";  
        $this->factclave->estadosrinc = "NEGADO";
        $this->factclave->save();
        

        }
    }
//}
public function ride_factura()
{
/** 
* Copyright (c)2018 - EN Systems Apps
* @abstract Envia un mail con un xml y pdf adjunto
* @author Erik Niebla
* @mail ep_niebla@hotmail.com, ep.niebla@gmail.com
* @version 1.0
* Fecha de creación  2018-02-27
* http://ensystems.ddns.net
*/    
require_once(dirname(__file__)."/RideSRI/RideSRI.php");
$ruta = dirname(__file__);
$echo = true; // solo para ver los procesos

// Muestro una Factura
    //$file_autorized = $ruta.'/src_ejemplos/fact_A.xml';
//echo "ruta : ".$ruta.$this->archAutorizado;
    $file_autorized = $ruta.'/src_sri/NCautorizados/'.$this->archAutorizado;
    $logo_path=$ruta.'/src_sri/logo/logo_l.gif';

try{    
    
    $ride = new RideSRI();
    // Arg1 ruta a archivo fisico xml
    // Arg2 logo ride
    // Arg3 I=Visualizar, D=Descargar
    // Arg4 true=online, false=offline 
    $result = $ride->createRide($file_autorized, $logo_path, 'D', true); // Instancio la clase, y muestro el ride
    
}catch (Exception $e) { 
    echo '<br/><b>ERROR AL EJECUTAR EL SCRIPT</b><br/>';
    echo '<b>Excepción Capturada[</b> ',  $e->getMessage(), "]\n";  
}
}




public function mail_factura()
{
require_once(dirname(__file__)."/RideSRI/MailNotification.php");
$ruta = dirname(__file__);
$echo = true; // solo para ver los procesos

echo " paso 1";
// En este ejemplo uso variables q psaso a las funciones
    $file_autorized = $ruta.'/src_sri/NCautorizados/'.$this->archAutorizado;
    echo $this->correodestino."   nombre ".$this->nombrecliente;
    $destinatari = array(
        'to'     => $this->correodestino,
        'to_name'=> $this->nombrecliente
    );
    $logo_path=$ruta.'/src_sri/logo/logo_l.gif';
try{
    //if($echo) $this->new_message("Iniciando ".  $this->correodestino."  ruta ".$ruta."  archivo ".$this->archAutorizado);   //echo 'EJEMPLO MAIL NOTIFICATION [EN Systems]EN Systems SRI, Iniciando...';
    
    $mailer = new MailNotification();
    // Arg1 ruta a archivo fisico xml
    // Arg2 destinatario
    // Arg3 destinatario copia //opcional
    // Arg4 logo ride //opcional
    // Arg5 true=online, false=offline //NOTA: se podria crear un xml autorizado simulado para offline, OJO REVISAR
    $result = $mailer->sendMailDoc($file_autorized,$destinatari,null,$logo_path,false); // Instancio la clase, y envio el mail
    
    if($echo) $this->new_message("Resultado ".$result['message']);   //echo '<br/><b>'.$result['message'].'</b>';
      $this->factclave->estadosrinc = "ENVIADO";  
      $this->factclave->save();
    
}catch (Exception $e) { 
    //echo '<br/><b>ERROR AL EJECUTAR EL SCRIPT</b><br/>';
    //echo '<b>Excepción Capturada[</b> ',  $e->getMessage(), "]\n";  
    $this->new_message("Resultado: ERROR AL EJECUTAR EL SCRIPT");
    $this->new_message($e->getMessage());
} 


}   

}




